ActivityManagerService.java revision 2a00329c6d55c6cd9166e01963d7410e95d80d21
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.UserHandle; 115import android.os.UserManager; 116import android.provider.Settings; 117import android.text.format.Time; 118import android.util.EventLog; 119import android.util.Log; 120import android.util.Pair; 121import android.util.PrintWriterPrinter; 122import android.util.Slog; 123import android.util.SparseArray; 124import android.util.SparseIntArray; 125import android.util.TimeUtils; 126import android.view.Gravity; 127import android.view.LayoutInflater; 128import android.view.View; 129import android.view.WindowManager; 130import android.view.WindowManagerPolicy; 131 132import java.io.BufferedInputStream; 133import java.io.BufferedOutputStream; 134import java.io.BufferedReader; 135import java.io.DataInputStream; 136import java.io.DataOutputStream; 137import java.io.File; 138import java.io.FileDescriptor; 139import java.io.FileInputStream; 140import java.io.FileNotFoundException; 141import java.io.FileOutputStream; 142import java.io.IOException; 143import java.io.InputStreamReader; 144import java.io.PrintWriter; 145import java.io.StringWriter; 146import java.lang.ref.WeakReference; 147import java.util.ArrayList; 148import java.util.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 non-hidden/empty process we last found, to help 690 * determine how to distribute hidden/empty processes next time. 691 */ 692 int mNumNonHiddenProcs = 0; 693 694 /** 695 * Keep track of the number of hidden procs, to balance oom adj 696 * distribution between those and empty procs. 697 */ 698 int mNumHiddenProcs = 0; 699 700 /** 701 * Keep track of the number of service processes we last found, to 702 * determine on the next iteration which should be B services. 703 */ 704 int mNumServiceProcs = 0; 705 int mNewNumServiceProcs = 0; 706 707 /** 708 * System monitoring: number of processes that died since the last 709 * N procs were started. 710 */ 711 int[] mProcDeaths = new int[20]; 712 713 /** 714 * This is set if we had to do a delayed dexopt of an app before launching 715 * it, to increasing the ANR timeouts in that case. 716 */ 717 boolean mDidDexOpt; 718 719 String mDebugApp = null; 720 boolean mWaitForDebugger = false; 721 boolean mDebugTransient = false; 722 String mOrigDebugApp = null; 723 boolean mOrigWaitForDebugger = false; 724 boolean mAlwaysFinishActivities = false; 725 IActivityController mController = null; 726 String mProfileApp = null; 727 ProcessRecord mProfileProc = null; 728 String mProfileFile; 729 ParcelFileDescriptor mProfileFd; 730 int mProfileType = 0; 731 boolean mAutoStopProfiler = false; 732 String mOpenGlTraceApp = null; 733 734 static class ProcessChangeItem { 735 static final int CHANGE_ACTIVITIES = 1<<0; 736 static final int CHANGE_IMPORTANCE= 1<<1; 737 int changes; 738 int uid; 739 int pid; 740 int importance; 741 boolean foregroundActivities; 742 } 743 744 final RemoteCallbackList<IProcessObserver> mProcessObservers 745 = new RemoteCallbackList<IProcessObserver>(); 746 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 747 748 final ArrayList<ProcessChangeItem> mPendingProcessChanges 749 = new ArrayList<ProcessChangeItem>(); 750 final ArrayList<ProcessChangeItem> mAvailProcessChanges 751 = new ArrayList<ProcessChangeItem>(); 752 753 /** 754 * Callback of last caller to {@link #requestPss}. 755 */ 756 Runnable mRequestPssCallback; 757 758 /** 759 * Remaining processes for which we are waiting results from the last 760 * call to {@link #requestPss}. 761 */ 762 final ArrayList<ProcessRecord> mRequestPssList 763 = new ArrayList<ProcessRecord>(); 764 765 /** 766 * Runtime statistics collection thread. This object's lock is used to 767 * protect all related state. 768 */ 769 final Thread mProcessStatsThread; 770 771 /** 772 * Used to collect process stats when showing not responding dialog. 773 * Protected by mProcessStatsThread. 774 */ 775 final ProcessStats mProcessStats = new ProcessStats( 776 MONITOR_THREAD_CPU_USAGE); 777 final AtomicLong mLastCpuTime = new AtomicLong(0); 778 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 779 780 long mLastWriteTime = 0; 781 782 /** 783 * Set to true after the system has finished booting. 784 */ 785 boolean mBooted = false; 786 787 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 788 int mProcessLimitOverride = -1; 789 790 WindowManagerService mWindowManager; 791 792 static ActivityManagerService mSelf; 793 static ActivityThread mSystemThread; 794 795 private int mCurrentUserId; 796 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 797 private UserManager mUserManager; 798 799 private final class AppDeathRecipient implements IBinder.DeathRecipient { 800 final ProcessRecord mApp; 801 final int mPid; 802 final IApplicationThread mAppThread; 803 804 AppDeathRecipient(ProcessRecord app, int pid, 805 IApplicationThread thread) { 806 if (localLOGV) Slog.v( 807 TAG, "New death recipient " + this 808 + " for thread " + thread.asBinder()); 809 mApp = app; 810 mPid = pid; 811 mAppThread = thread; 812 } 813 814 public void binderDied() { 815 if (localLOGV) Slog.v( 816 TAG, "Death received in " + this 817 + " for thread " + mAppThread.asBinder()); 818 synchronized(ActivityManagerService.this) { 819 appDiedLocked(mApp, mPid, mAppThread); 820 } 821 } 822 } 823 824 static final int SHOW_ERROR_MSG = 1; 825 static final int SHOW_NOT_RESPONDING_MSG = 2; 826 static final int SHOW_FACTORY_ERROR_MSG = 3; 827 static final int UPDATE_CONFIGURATION_MSG = 4; 828 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 829 static final int WAIT_FOR_DEBUGGER_MSG = 6; 830 static final int SERVICE_TIMEOUT_MSG = 12; 831 static final int UPDATE_TIME_ZONE = 13; 832 static final int SHOW_UID_ERROR_MSG = 14; 833 static final int IM_FEELING_LUCKY_MSG = 15; 834 static final int PROC_START_TIMEOUT_MSG = 20; 835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 836 static final int KILL_APPLICATION_MSG = 22; 837 static final int FINALIZE_PENDING_INTENT_MSG = 23; 838 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 842 static final int CLEAR_DNS_CACHE = 28; 843 static final int UPDATE_HTTP_PROXY = 29; 844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 845 static final int DISPATCH_PROCESSES_CHANGED = 31; 846 static final int DISPATCH_PROCESS_DIED = 32; 847 static final int REPORT_MEM_USAGE = 33; 848 849 static final int FIRST_ACTIVITY_STACK_MSG = 100; 850 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 851 static final int FIRST_COMPAT_MODE_MSG = 300; 852 853 AlertDialog mUidAlert; 854 CompatModeDialog mCompatModeDialog; 855 long mLastMemUsageReportTime = 0; 856 857 final Handler mHandler = new Handler() { 858 //public Handler() { 859 // if (localLOGV) Slog.v(TAG, "Handler started!"); 860 //} 861 862 public void handleMessage(Message msg) { 863 switch (msg.what) { 864 case SHOW_ERROR_MSG: { 865 HashMap data = (HashMap) msg.obj; 866 synchronized (ActivityManagerService.this) { 867 ProcessRecord proc = (ProcessRecord)data.get("app"); 868 if (proc != null && proc.crashDialog != null) { 869 Slog.e(TAG, "App already has crash dialog: " + proc); 870 return; 871 } 872 AppErrorResult res = (AppErrorResult) data.get("result"); 873 if (mShowDialogs && !mSleeping && !mShuttingDown) { 874 Dialog d = new AppErrorDialog(mContext, res, proc); 875 d.show(); 876 proc.crashDialog = d; 877 } else { 878 // The device is asleep, so just pretend that the user 879 // saw a crash dialog and hit "force quit". 880 res.set(0); 881 } 882 } 883 884 ensureBootCompleted(); 885 } break; 886 case SHOW_NOT_RESPONDING_MSG: { 887 synchronized (ActivityManagerService.this) { 888 HashMap data = (HashMap) msg.obj; 889 ProcessRecord proc = (ProcessRecord)data.get("app"); 890 if (proc != null && proc.anrDialog != null) { 891 Slog.e(TAG, "App already has anr dialog: " + proc); 892 return; 893 } 894 895 Intent intent = new Intent("android.intent.action.ANR"); 896 if (!mProcessesReady) { 897 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 898 | Intent.FLAG_RECEIVER_FOREGROUND); 899 } 900 broadcastIntentLocked(null, null, intent, 901 null, null, 0, null, null, null, 902 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 903 904 if (mShowDialogs) { 905 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 906 mContext, proc, (ActivityRecord)data.get("activity")); 907 d.show(); 908 proc.anrDialog = d; 909 } else { 910 // Just kill the app if there is no dialog to be shown. 911 killAppAtUsersRequest(proc, null); 912 } 913 } 914 915 ensureBootCompleted(); 916 } break; 917 case SHOW_STRICT_MODE_VIOLATION_MSG: { 918 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 919 synchronized (ActivityManagerService.this) { 920 ProcessRecord proc = (ProcessRecord) data.get("app"); 921 if (proc == null) { 922 Slog.e(TAG, "App not found when showing strict mode dialog."); 923 break; 924 } 925 if (proc.crashDialog != null) { 926 Slog.e(TAG, "App already has strict mode dialog: " + proc); 927 return; 928 } 929 AppErrorResult res = (AppErrorResult) data.get("result"); 930 if (mShowDialogs && !mSleeping && !mShuttingDown) { 931 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 932 d.show(); 933 proc.crashDialog = d; 934 } else { 935 // The device is asleep, so just pretend that the user 936 // saw a crash dialog and hit "force quit". 937 res.set(0); 938 } 939 } 940 ensureBootCompleted(); 941 } break; 942 case SHOW_FACTORY_ERROR_MSG: { 943 Dialog d = new FactoryErrorDialog( 944 mContext, msg.getData().getCharSequence("msg")); 945 d.show(); 946 ensureBootCompleted(); 947 } break; 948 case UPDATE_CONFIGURATION_MSG: { 949 final ContentResolver resolver = mContext.getContentResolver(); 950 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 951 } break; 952 case GC_BACKGROUND_PROCESSES_MSG: { 953 synchronized (ActivityManagerService.this) { 954 performAppGcsIfAppropriateLocked(); 955 } 956 } break; 957 case WAIT_FOR_DEBUGGER_MSG: { 958 synchronized (ActivityManagerService.this) { 959 ProcessRecord app = (ProcessRecord)msg.obj; 960 if (msg.arg1 != 0) { 961 if (!app.waitedForDebugger) { 962 Dialog d = new AppWaitingForDebuggerDialog( 963 ActivityManagerService.this, 964 mContext, app); 965 app.waitDialog = d; 966 app.waitedForDebugger = true; 967 d.show(); 968 } 969 } else { 970 if (app.waitDialog != null) { 971 app.waitDialog.dismiss(); 972 app.waitDialog = null; 973 } 974 } 975 } 976 } break; 977 case SERVICE_TIMEOUT_MSG: { 978 if (mDidDexOpt) { 979 mDidDexOpt = false; 980 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 981 nmsg.obj = msg.obj; 982 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 983 return; 984 } 985 mServices.serviceTimeout((ProcessRecord)msg.obj); 986 } break; 987 case UPDATE_TIME_ZONE: { 988 synchronized (ActivityManagerService.this) { 989 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 990 ProcessRecord r = mLruProcesses.get(i); 991 if (r.thread != null) { 992 try { 993 r.thread.updateTimeZone(); 994 } catch (RemoteException ex) { 995 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 996 } 997 } 998 } 999 } 1000 } break; 1001 case CLEAR_DNS_CACHE: { 1002 synchronized (ActivityManagerService.this) { 1003 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1004 ProcessRecord r = mLruProcesses.get(i); 1005 if (r.thread != null) { 1006 try { 1007 r.thread.clearDnsCache(); 1008 } catch (RemoteException ex) { 1009 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1010 } 1011 } 1012 } 1013 } 1014 } break; 1015 case UPDATE_HTTP_PROXY: { 1016 ProxyProperties proxy = (ProxyProperties)msg.obj; 1017 String host = ""; 1018 String port = ""; 1019 String exclList = ""; 1020 if (proxy != null) { 1021 host = proxy.getHost(); 1022 port = Integer.toString(proxy.getPort()); 1023 exclList = proxy.getExclusionList(); 1024 } 1025 synchronized (ActivityManagerService.this) { 1026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1027 ProcessRecord r = mLruProcesses.get(i); 1028 if (r.thread != null) { 1029 try { 1030 r.thread.setHttpProxy(host, port, exclList); 1031 } catch (RemoteException ex) { 1032 Slog.w(TAG, "Failed to update http proxy for: " + 1033 r.info.processName); 1034 } 1035 } 1036 } 1037 } 1038 } break; 1039 case SHOW_UID_ERROR_MSG: { 1040 String title = "System UIDs Inconsistent"; 1041 String text = "UIDs on the system are inconsistent, you need to wipe your" 1042 + " data partition or your device will be unstable."; 1043 Log.e(TAG, title + ": " + text); 1044 if (mShowDialogs) { 1045 // XXX This is a temporary dialog, no need to localize. 1046 AlertDialog d = new BaseErrorDialog(mContext); 1047 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1048 d.setCancelable(false); 1049 d.setTitle(title); 1050 d.setMessage(text); 1051 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1052 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1053 mUidAlert = d; 1054 d.show(); 1055 } 1056 } break; 1057 case IM_FEELING_LUCKY_MSG: { 1058 if (mUidAlert != null) { 1059 mUidAlert.dismiss(); 1060 mUidAlert = null; 1061 } 1062 } break; 1063 case PROC_START_TIMEOUT_MSG: { 1064 if (mDidDexOpt) { 1065 mDidDexOpt = false; 1066 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1067 nmsg.obj = msg.obj; 1068 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1069 return; 1070 } 1071 ProcessRecord app = (ProcessRecord)msg.obj; 1072 synchronized (ActivityManagerService.this) { 1073 processStartTimedOutLocked(app); 1074 } 1075 } break; 1076 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1077 synchronized (ActivityManagerService.this) { 1078 doPendingActivityLaunchesLocked(true); 1079 } 1080 } break; 1081 case KILL_APPLICATION_MSG: { 1082 synchronized (ActivityManagerService.this) { 1083 int uid = msg.arg1; 1084 boolean restart = (msg.arg2 == 1); 1085 String pkg = (String) msg.obj; 1086 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1087 UserHandle.getUserId(uid)); 1088 } 1089 } break; 1090 case FINALIZE_PENDING_INTENT_MSG: { 1091 ((PendingIntentRecord)msg.obj).completeFinalize(); 1092 } break; 1093 case POST_HEAVY_NOTIFICATION_MSG: { 1094 INotificationManager inm = NotificationManager.getService(); 1095 if (inm == null) { 1096 return; 1097 } 1098 1099 ActivityRecord root = (ActivityRecord)msg.obj; 1100 ProcessRecord process = root.app; 1101 if (process == null) { 1102 return; 1103 } 1104 1105 try { 1106 Context context = mContext.createPackageContext(process.info.packageName, 0); 1107 String text = mContext.getString(R.string.heavy_weight_notification, 1108 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1109 Notification notification = new Notification(); 1110 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1111 notification.when = 0; 1112 notification.flags = Notification.FLAG_ONGOING_EVENT; 1113 notification.tickerText = text; 1114 notification.defaults = 0; // please be quiet 1115 notification.sound = null; 1116 notification.vibrate = null; 1117 notification.setLatestEventInfo(context, text, 1118 mContext.getText(R.string.heavy_weight_notification_detail), 1119 PendingIntent.getActivity(mContext, 0, root.intent, 1120 PendingIntent.FLAG_CANCEL_CURRENT)); 1121 1122 try { 1123 int[] outId = new int[1]; 1124 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1125 notification, outId); 1126 } catch (RuntimeException e) { 1127 Slog.w(ActivityManagerService.TAG, 1128 "Error showing notification for heavy-weight app", e); 1129 } catch (RemoteException e) { 1130 } 1131 } catch (NameNotFoundException e) { 1132 Slog.w(TAG, "Unable to create context for heavy notification", e); 1133 } 1134 } break; 1135 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1136 INotificationManager inm = NotificationManager.getService(); 1137 if (inm == null) { 1138 return; 1139 } 1140 try { 1141 inm.cancelNotification("android", 1142 R.string.heavy_weight_notification); 1143 } catch (RuntimeException e) { 1144 Slog.w(ActivityManagerService.TAG, 1145 "Error canceling notification for service", e); 1146 } catch (RemoteException e) { 1147 } 1148 } break; 1149 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1150 synchronized (ActivityManagerService.this) { 1151 checkExcessivePowerUsageLocked(true); 1152 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1153 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1154 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1155 } 1156 } break; 1157 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1158 synchronized (ActivityManagerService.this) { 1159 ActivityRecord ar = (ActivityRecord)msg.obj; 1160 if (mCompatModeDialog != null) { 1161 if (mCompatModeDialog.mAppInfo.packageName.equals( 1162 ar.info.applicationInfo.packageName)) { 1163 return; 1164 } 1165 mCompatModeDialog.dismiss(); 1166 mCompatModeDialog = null; 1167 } 1168 if (ar != null && false) { 1169 if (mCompatModePackages.getPackageAskCompatModeLocked( 1170 ar.packageName)) { 1171 int mode = mCompatModePackages.computeCompatModeLocked( 1172 ar.info.applicationInfo); 1173 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1174 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1175 mCompatModeDialog = new CompatModeDialog( 1176 ActivityManagerService.this, mContext, 1177 ar.info.applicationInfo); 1178 mCompatModeDialog.show(); 1179 } 1180 } 1181 } 1182 } 1183 break; 1184 } 1185 case DISPATCH_PROCESSES_CHANGED: { 1186 dispatchProcessesChanged(); 1187 break; 1188 } 1189 case DISPATCH_PROCESS_DIED: { 1190 final int pid = msg.arg1; 1191 final int uid = msg.arg2; 1192 dispatchProcessDied(pid, uid); 1193 break; 1194 } 1195 case REPORT_MEM_USAGE: { 1196 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1197 if (!isDebuggable) { 1198 return; 1199 } 1200 synchronized (ActivityManagerService.this) { 1201 long now = SystemClock.uptimeMillis(); 1202 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1203 // Don't report more than every 5 minutes to somewhat 1204 // avoid spamming. 1205 return; 1206 } 1207 mLastMemUsageReportTime = now; 1208 } 1209 Thread thread = new Thread() { 1210 @Override public void run() { 1211 StringBuilder dropBuilder = new StringBuilder(1024); 1212 StringBuilder logBuilder = new StringBuilder(1024); 1213 StringWriter oomSw = new StringWriter(); 1214 PrintWriter oomPw = new PrintWriter(oomSw); 1215 StringWriter catSw = new StringWriter(); 1216 PrintWriter catPw = new PrintWriter(catSw); 1217 String[] emptyArgs = new String[] { }; 1218 StringBuilder tag = new StringBuilder(128); 1219 StringBuilder stack = new StringBuilder(128); 1220 tag.append("Low on memory -- "); 1221 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1222 tag, stack); 1223 dropBuilder.append(stack); 1224 dropBuilder.append('\n'); 1225 dropBuilder.append('\n'); 1226 String oomString = oomSw.toString(); 1227 dropBuilder.append(oomString); 1228 dropBuilder.append('\n'); 1229 logBuilder.append(oomString); 1230 try { 1231 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1232 "procrank", }); 1233 final InputStreamReader converter = new InputStreamReader( 1234 proc.getInputStream()); 1235 BufferedReader in = new BufferedReader(converter); 1236 String line; 1237 while (true) { 1238 line = in.readLine(); 1239 if (line == null) { 1240 break; 1241 } 1242 if (line.length() > 0) { 1243 logBuilder.append(line); 1244 logBuilder.append('\n'); 1245 } 1246 dropBuilder.append(line); 1247 dropBuilder.append('\n'); 1248 } 1249 converter.close(); 1250 } catch (IOException e) { 1251 } 1252 synchronized (ActivityManagerService.this) { 1253 catPw.println(); 1254 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1255 catPw.println(); 1256 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1257 false, false, null); 1258 catPw.println(); 1259 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1260 } 1261 dropBuilder.append(catSw.toString()); 1262 addErrorToDropBox("lowmem", null, "system_server", null, 1263 null, tag.toString(), dropBuilder.toString(), null, null); 1264 Slog.i(TAG, logBuilder.toString()); 1265 synchronized (ActivityManagerService.this) { 1266 long now = SystemClock.uptimeMillis(); 1267 if (mLastMemUsageReportTime < now) { 1268 mLastMemUsageReportTime = now; 1269 } 1270 } 1271 } 1272 }; 1273 thread.start(); 1274 break; 1275 } 1276 } 1277 } 1278 }; 1279 1280 public static void setSystemProcess() { 1281 try { 1282 ActivityManagerService m = mSelf; 1283 1284 ServiceManager.addService("activity", m, true); 1285 ServiceManager.addService("meminfo", new MemBinder(m)); 1286 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1287 ServiceManager.addService("dbinfo", new DbBinder(m)); 1288 if (MONITOR_CPU_USAGE) { 1289 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1290 } 1291 ServiceManager.addService("permission", new PermissionController(m)); 1292 1293 ApplicationInfo info = 1294 mSelf.mContext.getPackageManager().getApplicationInfo( 1295 "android", STOCK_PM_FLAGS); 1296 mSystemThread.installSystemApplicationInfo(info); 1297 1298 synchronized (mSelf) { 1299 ProcessRecord app = mSelf.newProcessRecordLocked( 1300 mSystemThread.getApplicationThread(), info, 1301 info.processName, false); 1302 app.persistent = true; 1303 app.pid = MY_PID; 1304 app.maxAdj = ProcessList.SYSTEM_ADJ; 1305 mSelf.mProcessNames.put(app.processName, app.uid, app); 1306 synchronized (mSelf.mPidsSelfLocked) { 1307 mSelf.mPidsSelfLocked.put(app.pid, app); 1308 } 1309 mSelf.updateLruProcessLocked(app, true, true); 1310 } 1311 } catch (PackageManager.NameNotFoundException e) { 1312 throw new RuntimeException( 1313 "Unable to find android system package", e); 1314 } 1315 } 1316 1317 public void setWindowManager(WindowManagerService wm) { 1318 mWindowManager = wm; 1319 } 1320 1321 public static final Context main(int factoryTest) { 1322 AThread thr = new AThread(); 1323 thr.start(); 1324 1325 synchronized (thr) { 1326 while (thr.mService == null) { 1327 try { 1328 thr.wait(); 1329 } catch (InterruptedException e) { 1330 } 1331 } 1332 } 1333 1334 ActivityManagerService m = thr.mService; 1335 mSelf = m; 1336 ActivityThread at = ActivityThread.systemMain(); 1337 mSystemThread = at; 1338 Context context = at.getSystemContext(); 1339 context.setTheme(android.R.style.Theme_Holo); 1340 m.mContext = context; 1341 m.mFactoryTest = factoryTest; 1342 m.mMainStack = new ActivityStack(m, context, true); 1343 1344 m.mBatteryStatsService.publish(context); 1345 m.mUsageStatsService.publish(context); 1346 1347 synchronized (thr) { 1348 thr.mReady = true; 1349 thr.notifyAll(); 1350 } 1351 1352 m.startRunning(null, null, null, null); 1353 1354 return context; 1355 } 1356 1357 public static ActivityManagerService self() { 1358 return mSelf; 1359 } 1360 1361 static class AThread extends Thread { 1362 ActivityManagerService mService; 1363 boolean mReady = false; 1364 1365 public AThread() { 1366 super("ActivityManager"); 1367 } 1368 1369 public void run() { 1370 Looper.prepare(); 1371 1372 android.os.Process.setThreadPriority( 1373 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1374 android.os.Process.setCanSelfBackground(false); 1375 1376 ActivityManagerService m = new ActivityManagerService(); 1377 1378 synchronized (this) { 1379 mService = m; 1380 notifyAll(); 1381 } 1382 1383 synchronized (this) { 1384 while (!mReady) { 1385 try { 1386 wait(); 1387 } catch (InterruptedException e) { 1388 } 1389 } 1390 } 1391 1392 // For debug builds, log event loop stalls to dropbox for analysis. 1393 if (StrictMode.conditionallyEnableDebugLogging()) { 1394 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1395 } 1396 1397 Looper.loop(); 1398 } 1399 } 1400 1401 static class MemBinder extends Binder { 1402 ActivityManagerService mActivityManagerService; 1403 MemBinder(ActivityManagerService activityManagerService) { 1404 mActivityManagerService = activityManagerService; 1405 } 1406 1407 @Override 1408 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1409 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1410 != PackageManager.PERMISSION_GRANTED) { 1411 pw.println("Permission Denial: can't dump meminfo from from pid=" 1412 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1413 + " without permission " + android.Manifest.permission.DUMP); 1414 return; 1415 } 1416 1417 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1418 false, null, null, null); 1419 } 1420 } 1421 1422 static class GraphicsBinder extends Binder { 1423 ActivityManagerService mActivityManagerService; 1424 GraphicsBinder(ActivityManagerService activityManagerService) { 1425 mActivityManagerService = activityManagerService; 1426 } 1427 1428 @Override 1429 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1430 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1431 != PackageManager.PERMISSION_GRANTED) { 1432 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1433 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1434 + " without permission " + android.Manifest.permission.DUMP); 1435 return; 1436 } 1437 1438 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1439 } 1440 } 1441 1442 static class DbBinder extends Binder { 1443 ActivityManagerService mActivityManagerService; 1444 DbBinder(ActivityManagerService activityManagerService) { 1445 mActivityManagerService = activityManagerService; 1446 } 1447 1448 @Override 1449 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1450 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1451 != PackageManager.PERMISSION_GRANTED) { 1452 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1453 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1454 + " without permission " + android.Manifest.permission.DUMP); 1455 return; 1456 } 1457 1458 mActivityManagerService.dumpDbInfo(fd, pw, args); 1459 } 1460 } 1461 1462 static class CpuBinder extends Binder { 1463 ActivityManagerService mActivityManagerService; 1464 CpuBinder(ActivityManagerService activityManagerService) { 1465 mActivityManagerService = activityManagerService; 1466 } 1467 1468 @Override 1469 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1470 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1471 != PackageManager.PERMISSION_GRANTED) { 1472 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1473 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1474 + " without permission " + android.Manifest.permission.DUMP); 1475 return; 1476 } 1477 1478 synchronized (mActivityManagerService.mProcessStatsThread) { 1479 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1480 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1481 SystemClock.uptimeMillis())); 1482 } 1483 } 1484 } 1485 1486 private ActivityManagerService() { 1487 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1488 1489 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1490 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1491 mBroadcastQueues[0] = mFgBroadcastQueue; 1492 mBroadcastQueues[1] = mBgBroadcastQueue; 1493 1494 mServices = new ActiveServices(this); 1495 1496 File dataDir = Environment.getDataDirectory(); 1497 File systemDir = new File(dataDir, "system"); 1498 systemDir.mkdirs(); 1499 mBatteryStatsService = new BatteryStatsService(new File( 1500 systemDir, "batterystats.bin").toString()); 1501 mBatteryStatsService.getActiveStatistics().readLocked(); 1502 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1503 mOnBattery = DEBUG_POWER ? true 1504 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1505 mBatteryStatsService.getActiveStatistics().setCallback(this); 1506 1507 mUsageStatsService = new UsageStatsService(new File( 1508 systemDir, "usagestats").toString()); 1509 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1510 1511 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1512 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1513 1514 mConfiguration.setToDefaults(); 1515 mConfiguration.locale = Locale.getDefault(); 1516 mConfigurationSeq = mConfiguration.seq = 1; 1517 mProcessStats.init(); 1518 1519 mCompatModePackages = new CompatModePackages(this, systemDir); 1520 1521 // Add ourself to the Watchdog monitors. 1522 Watchdog.getInstance().addMonitor(this); 1523 1524 mProcessStatsThread = new Thread("ProcessStats") { 1525 public void run() { 1526 while (true) { 1527 try { 1528 try { 1529 synchronized(this) { 1530 final long now = SystemClock.uptimeMillis(); 1531 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1532 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1533 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1534 // + ", write delay=" + nextWriteDelay); 1535 if (nextWriteDelay < nextCpuDelay) { 1536 nextCpuDelay = nextWriteDelay; 1537 } 1538 if (nextCpuDelay > 0) { 1539 mProcessStatsMutexFree.set(true); 1540 this.wait(nextCpuDelay); 1541 } 1542 } 1543 } catch (InterruptedException e) { 1544 } 1545 updateCpuStatsNow(); 1546 } catch (Exception e) { 1547 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1548 } 1549 } 1550 } 1551 }; 1552 mProcessStatsThread.start(); 1553 } 1554 1555 @Override 1556 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1557 throws RemoteException { 1558 if (code == SYSPROPS_TRANSACTION) { 1559 // We need to tell all apps about the system property change. 1560 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1561 synchronized(this) { 1562 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1563 final int NA = apps.size(); 1564 for (int ia=0; ia<NA; ia++) { 1565 ProcessRecord app = apps.valueAt(ia); 1566 if (app.thread != null) { 1567 procs.add(app.thread.asBinder()); 1568 } 1569 } 1570 } 1571 } 1572 1573 int N = procs.size(); 1574 for (int i=0; i<N; i++) { 1575 Parcel data2 = Parcel.obtain(); 1576 try { 1577 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1578 } catch (RemoteException e) { 1579 } 1580 data2.recycle(); 1581 } 1582 } 1583 try { 1584 return super.onTransact(code, data, reply, flags); 1585 } catch (RuntimeException e) { 1586 // The activity manager only throws security exceptions, so let's 1587 // log all others. 1588 if (!(e instanceof SecurityException)) { 1589 Slog.e(TAG, "Activity Manager Crash", e); 1590 } 1591 throw e; 1592 } 1593 } 1594 1595 void updateCpuStats() { 1596 final long now = SystemClock.uptimeMillis(); 1597 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1598 return; 1599 } 1600 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1601 synchronized (mProcessStatsThread) { 1602 mProcessStatsThread.notify(); 1603 } 1604 } 1605 } 1606 1607 void updateCpuStatsNow() { 1608 synchronized (mProcessStatsThread) { 1609 mProcessStatsMutexFree.set(false); 1610 final long now = SystemClock.uptimeMillis(); 1611 boolean haveNewCpuStats = false; 1612 1613 if (MONITOR_CPU_USAGE && 1614 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1615 mLastCpuTime.set(now); 1616 haveNewCpuStats = true; 1617 mProcessStats.update(); 1618 //Slog.i(TAG, mProcessStats.printCurrentState()); 1619 //Slog.i(TAG, "Total CPU usage: " 1620 // + mProcessStats.getTotalCpuPercent() + "%"); 1621 1622 // Slog the cpu usage if the property is set. 1623 if ("true".equals(SystemProperties.get("events.cpu"))) { 1624 int user = mProcessStats.getLastUserTime(); 1625 int system = mProcessStats.getLastSystemTime(); 1626 int iowait = mProcessStats.getLastIoWaitTime(); 1627 int irq = mProcessStats.getLastIrqTime(); 1628 int softIrq = mProcessStats.getLastSoftIrqTime(); 1629 int idle = mProcessStats.getLastIdleTime(); 1630 1631 int total = user + system + iowait + irq + softIrq + idle; 1632 if (total == 0) total = 1; 1633 1634 EventLog.writeEvent(EventLogTags.CPU, 1635 ((user+system+iowait+irq+softIrq) * 100) / total, 1636 (user * 100) / total, 1637 (system * 100) / total, 1638 (iowait * 100) / total, 1639 (irq * 100) / total, 1640 (softIrq * 100) / total); 1641 } 1642 } 1643 1644 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1645 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1646 synchronized(bstats) { 1647 synchronized(mPidsSelfLocked) { 1648 if (haveNewCpuStats) { 1649 if (mOnBattery) { 1650 int perc = bstats.startAddingCpuLocked(); 1651 int totalUTime = 0; 1652 int totalSTime = 0; 1653 final int N = mProcessStats.countStats(); 1654 for (int i=0; i<N; i++) { 1655 ProcessStats.Stats st = mProcessStats.getStats(i); 1656 if (!st.working) { 1657 continue; 1658 } 1659 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1660 int otherUTime = (st.rel_utime*perc)/100; 1661 int otherSTime = (st.rel_stime*perc)/100; 1662 totalUTime += otherUTime; 1663 totalSTime += otherSTime; 1664 if (pr != null) { 1665 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1666 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1667 st.rel_stime-otherSTime); 1668 ps.addSpeedStepTimes(cpuSpeedTimes); 1669 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1670 } else { 1671 BatteryStatsImpl.Uid.Proc ps = 1672 bstats.getProcessStatsLocked(st.name, st.pid); 1673 if (ps != null) { 1674 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1675 st.rel_stime-otherSTime); 1676 ps.addSpeedStepTimes(cpuSpeedTimes); 1677 } 1678 } 1679 } 1680 bstats.finishAddingCpuLocked(perc, totalUTime, 1681 totalSTime, cpuSpeedTimes); 1682 } 1683 } 1684 } 1685 1686 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1687 mLastWriteTime = now; 1688 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1689 } 1690 } 1691 } 1692 } 1693 1694 @Override 1695 public void batteryNeedsCpuUpdate() { 1696 updateCpuStatsNow(); 1697 } 1698 1699 @Override 1700 public void batteryPowerChanged(boolean onBattery) { 1701 // When plugging in, update the CPU stats first before changing 1702 // the plug state. 1703 updateCpuStatsNow(); 1704 synchronized (this) { 1705 synchronized(mPidsSelfLocked) { 1706 mOnBattery = DEBUG_POWER ? true : onBattery; 1707 } 1708 } 1709 } 1710 1711 /** 1712 * Initialize the application bind args. These are passed to each 1713 * process when the bindApplication() IPC is sent to the process. They're 1714 * lazily setup to make sure the services are running when they're asked for. 1715 */ 1716 private HashMap<String, IBinder> getCommonServicesLocked() { 1717 if (mAppBindArgs == null) { 1718 mAppBindArgs = new HashMap<String, IBinder>(); 1719 1720 // Setup the application init args 1721 mAppBindArgs.put("package", ServiceManager.getService("package")); 1722 mAppBindArgs.put("window", ServiceManager.getService("window")); 1723 mAppBindArgs.put(Context.ALARM_SERVICE, 1724 ServiceManager.getService(Context.ALARM_SERVICE)); 1725 } 1726 return mAppBindArgs; 1727 } 1728 1729 final void setFocusedActivityLocked(ActivityRecord r) { 1730 if (mFocusedActivity != r) { 1731 mFocusedActivity = r; 1732 if (r != null) { 1733 mWindowManager.setFocusedApp(r.appToken, true); 1734 } 1735 } 1736 } 1737 1738 private final void updateLruProcessInternalLocked(ProcessRecord app, 1739 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1740 // put it on the LRU to keep track of when it should be exited. 1741 int lrui = mLruProcesses.indexOf(app); 1742 if (lrui >= 0) mLruProcesses.remove(lrui); 1743 1744 int i = mLruProcesses.size()-1; 1745 int skipTop = 0; 1746 1747 app.lruSeq = mLruSeq; 1748 1749 // compute the new weight for this process. 1750 if (updateActivityTime) { 1751 app.lastActivityTime = SystemClock.uptimeMillis(); 1752 } 1753 if (app.activities.size() > 0) { 1754 // If this process has activities, we more strongly want to keep 1755 // it around. 1756 app.lruWeight = app.lastActivityTime; 1757 } else if (app.pubProviders.size() > 0) { 1758 // If this process contains content providers, we want to keep 1759 // it a little more strongly. 1760 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1761 // Also don't let it kick out the first few "real" hidden processes. 1762 skipTop = ProcessList.MIN_HIDDEN_APPS; 1763 } else { 1764 // If this process doesn't have activities, we less strongly 1765 // want to keep it around, and generally want to avoid getting 1766 // in front of any very recently used activities. 1767 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1768 // Also don't let it kick out the first few "real" hidden processes. 1769 skipTop = ProcessList.MIN_HIDDEN_APPS; 1770 } 1771 1772 while (i >= 0) { 1773 ProcessRecord p = mLruProcesses.get(i); 1774 // If this app shouldn't be in front of the first N background 1775 // apps, then skip over that many that are currently hidden. 1776 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1777 skipTop--; 1778 } 1779 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1780 mLruProcesses.add(i+1, app); 1781 break; 1782 } 1783 i--; 1784 } 1785 if (i < 0) { 1786 mLruProcesses.add(0, app); 1787 } 1788 1789 // If the app is currently using a content provider or service, 1790 // bump those processes as well. 1791 if (app.connections.size() > 0) { 1792 for (ConnectionRecord cr : app.connections) { 1793 if (cr.binding != null && cr.binding.service != null 1794 && cr.binding.service.app != null 1795 && cr.binding.service.app.lruSeq != mLruSeq) { 1796 updateLruProcessInternalLocked(cr.binding.service.app, false, 1797 updateActivityTime, i+1); 1798 } 1799 } 1800 } 1801 for (int j=app.conProviders.size()-1; j>=0; j--) { 1802 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1803 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1804 updateLruProcessInternalLocked(cpr.proc, false, 1805 updateActivityTime, i+1); 1806 } 1807 } 1808 1809 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1810 if (oomAdj) { 1811 updateOomAdjLocked(); 1812 } 1813 } 1814 1815 final void updateLruProcessLocked(ProcessRecord app, 1816 boolean oomAdj, boolean updateActivityTime) { 1817 mLruSeq++; 1818 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1819 } 1820 1821 final ProcessRecord getProcessRecordLocked( 1822 String processName, int uid) { 1823 if (uid == Process.SYSTEM_UID) { 1824 // The system gets to run in any process. If there are multiple 1825 // processes with the same uid, just pick the first (this 1826 // should never happen). 1827 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1828 processName); 1829 if (procs == null) return null; 1830 final int N = procs.size(); 1831 for (int i = 0; i < N; i++) { 1832 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1833 } 1834 } 1835 ProcessRecord proc = mProcessNames.get(processName, uid); 1836 return proc; 1837 } 1838 1839 void ensurePackageDexOpt(String packageName) { 1840 IPackageManager pm = AppGlobals.getPackageManager(); 1841 try { 1842 if (pm.performDexOpt(packageName)) { 1843 mDidDexOpt = true; 1844 } 1845 } catch (RemoteException e) { 1846 } 1847 } 1848 1849 boolean isNextTransitionForward() { 1850 int transit = mWindowManager.getPendingAppTransition(); 1851 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1852 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1853 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1854 } 1855 1856 final ProcessRecord startProcessLocked(String processName, 1857 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1858 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1859 boolean isolated) { 1860 ProcessRecord app; 1861 if (!isolated) { 1862 app = getProcessRecordLocked(processName, info.uid); 1863 } else { 1864 // If this is an isolated process, it can't re-use an existing process. 1865 app = null; 1866 } 1867 // We don't have to do anything more if: 1868 // (1) There is an existing application record; and 1869 // (2) The caller doesn't think it is dead, OR there is no thread 1870 // object attached to it so we know it couldn't have crashed; and 1871 // (3) There is a pid assigned to it, so it is either starting or 1872 // already running. 1873 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1874 + " app=" + app + " knownToBeDead=" + knownToBeDead 1875 + " thread=" + (app != null ? app.thread : null) 1876 + " pid=" + (app != null ? app.pid : -1)); 1877 if (app != null && app.pid > 0) { 1878 if (!knownToBeDead || app.thread == null) { 1879 // We already have the app running, or are waiting for it to 1880 // come up (we have a pid but not yet its thread), so keep it. 1881 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1882 // If this is a new package in the process, add the package to the list 1883 app.addPackage(info.packageName); 1884 return app; 1885 } else { 1886 // An application record is attached to a previous process, 1887 // clean it up now. 1888 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1889 handleAppDiedLocked(app, true, true); 1890 } 1891 } 1892 1893 String hostingNameStr = hostingName != null 1894 ? hostingName.flattenToShortString() : null; 1895 1896 if (!isolated) { 1897 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1898 // If we are in the background, then check to see if this process 1899 // is bad. If so, we will just silently fail. 1900 if (mBadProcesses.get(info.processName, info.uid) != null) { 1901 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1902 + "/" + info.processName); 1903 return null; 1904 } 1905 } else { 1906 // When the user is explicitly starting a process, then clear its 1907 // crash count so that we won't make it bad until they see at 1908 // least one crash dialog again, and make the process good again 1909 // if it had been bad. 1910 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1911 + "/" + info.processName); 1912 mProcessCrashTimes.remove(info.processName, info.uid); 1913 if (mBadProcesses.get(info.processName, info.uid) != null) { 1914 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1915 info.processName); 1916 mBadProcesses.remove(info.processName, info.uid); 1917 if (app != null) { 1918 app.bad = false; 1919 } 1920 } 1921 } 1922 } 1923 1924 if (app == null) { 1925 app = newProcessRecordLocked(null, info, processName, isolated); 1926 if (app == null) { 1927 Slog.w(TAG, "Failed making new process record for " 1928 + processName + "/" + info.uid + " isolated=" + isolated); 1929 return null; 1930 } 1931 mProcessNames.put(processName, app.uid, app); 1932 if (isolated) { 1933 mIsolatedProcesses.put(app.uid, app); 1934 } 1935 } else { 1936 // If this is a new package in the process, add the package to the list 1937 app.addPackage(info.packageName); 1938 } 1939 1940 // If the system is not ready yet, then hold off on starting this 1941 // process until it is. 1942 if (!mProcessesReady 1943 && !isAllowedWhileBooting(info) 1944 && !allowWhileBooting) { 1945 if (!mProcessesOnHold.contains(app)) { 1946 mProcessesOnHold.add(app); 1947 } 1948 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1949 return app; 1950 } 1951 1952 startProcessLocked(app, hostingType, hostingNameStr); 1953 return (app.pid != 0) ? app : null; 1954 } 1955 1956 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1957 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1958 } 1959 1960 private final void startProcessLocked(ProcessRecord app, 1961 String hostingType, String hostingNameStr) { 1962 if (app.pid > 0 && app.pid != MY_PID) { 1963 synchronized (mPidsSelfLocked) { 1964 mPidsSelfLocked.remove(app.pid); 1965 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1966 } 1967 app.setPid(0); 1968 } 1969 1970 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1971 "startProcessLocked removing on hold: " + app); 1972 mProcessesOnHold.remove(app); 1973 1974 updateCpuStats(); 1975 1976 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1977 mProcDeaths[0] = 0; 1978 1979 try { 1980 int uid = app.uid; 1981 1982 int[] gids = null; 1983 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1984 if (!app.isolated) { 1985 try { 1986 final PackageManager pm = mContext.getPackageManager(); 1987 gids = pm.getPackageGids(app.info.packageName); 1988 if (pm.checkPermission( 1989 android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName) 1990 == PERMISSION_GRANTED) { 1991 if (Environment.isExternalStorageEmulated()) { 1992 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 1993 } else { 1994 mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER; 1995 } 1996 } 1997 } catch (PackageManager.NameNotFoundException e) { 1998 Slog.w(TAG, "Unable to retrieve gids", e); 1999 } 2000 } 2001 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2002 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2003 && mTopComponent != null 2004 && app.processName.equals(mTopComponent.getPackageName())) { 2005 uid = 0; 2006 } 2007 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2008 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2009 uid = 0; 2010 } 2011 } 2012 int debugFlags = 0; 2013 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2014 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2015 // Also turn on CheckJNI for debuggable apps. It's quite 2016 // awkward to turn on otherwise. 2017 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2018 } 2019 // Run the app in safe mode if its manifest requests so or the 2020 // system is booted in safe mode. 2021 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2022 Zygote.systemInSafeMode == true) { 2023 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2024 } 2025 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2026 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2027 } 2028 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2029 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2030 } 2031 if ("1".equals(SystemProperties.get("debug.assert"))) { 2032 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2033 } 2034 2035 // Start the process. It will either succeed and return a result containing 2036 // the PID of the new process, or else throw a RuntimeException. 2037 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2038 app.processName, uid, uid, gids, debugFlags, mountExternal, 2039 app.info.targetSdkVersion, null, null); 2040 2041 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2042 synchronized (bs) { 2043 if (bs.isOnBattery()) { 2044 app.batteryStats.incStartsLocked(); 2045 } 2046 } 2047 2048 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2049 app.processName, hostingType, 2050 hostingNameStr != null ? hostingNameStr : ""); 2051 2052 if (app.persistent) { 2053 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2054 } 2055 2056 StringBuilder buf = mStringBuilder; 2057 buf.setLength(0); 2058 buf.append("Start proc "); 2059 buf.append(app.processName); 2060 buf.append(" for "); 2061 buf.append(hostingType); 2062 if (hostingNameStr != null) { 2063 buf.append(" "); 2064 buf.append(hostingNameStr); 2065 } 2066 buf.append(": pid="); 2067 buf.append(startResult.pid); 2068 buf.append(" uid="); 2069 buf.append(uid); 2070 buf.append(" gids={"); 2071 if (gids != null) { 2072 for (int gi=0; gi<gids.length; gi++) { 2073 if (gi != 0) buf.append(", "); 2074 buf.append(gids[gi]); 2075 2076 } 2077 } 2078 buf.append("}"); 2079 Slog.i(TAG, buf.toString()); 2080 app.setPid(startResult.pid); 2081 app.usingWrapper = startResult.usingWrapper; 2082 app.removed = false; 2083 synchronized (mPidsSelfLocked) { 2084 this.mPidsSelfLocked.put(startResult.pid, app); 2085 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2086 msg.obj = app; 2087 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2088 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2089 } 2090 } catch (RuntimeException e) { 2091 // XXX do better error recovery. 2092 app.setPid(0); 2093 Slog.e(TAG, "Failure starting process " + app.processName, e); 2094 } 2095 } 2096 2097 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2098 if (resumed) { 2099 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2100 } else { 2101 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2102 } 2103 } 2104 2105 boolean startHomeActivityLocked(int userId) { 2106 if (mHeadless) { 2107 // Added because none of the other calls to ensureBootCompleted seem to fire 2108 // when running headless. 2109 ensureBootCompleted(); 2110 return false; 2111 } 2112 2113 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2114 && mTopAction == null) { 2115 // We are running in factory test mode, but unable to find 2116 // the factory test app, so just sit around displaying the 2117 // error message and don't try to start anything. 2118 return false; 2119 } 2120 Intent intent = new Intent( 2121 mTopAction, 2122 mTopData != null ? Uri.parse(mTopData) : null); 2123 intent.setComponent(mTopComponent); 2124 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2125 intent.addCategory(Intent.CATEGORY_HOME); 2126 } 2127 ActivityInfo aInfo = 2128 intent.resolveActivityInfo(mContext.getPackageManager(), 2129 STOCK_PM_FLAGS); 2130 if (aInfo != null) { 2131 intent.setComponent(new ComponentName( 2132 aInfo.applicationInfo.packageName, aInfo.name)); 2133 // Don't do this if the home app is currently being 2134 // instrumented. 2135 aInfo = new ActivityInfo(aInfo); 2136 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2137 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2138 aInfo.applicationInfo.uid); 2139 if (app == null || app.instrumentationClass == null) { 2140 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2141 mMainStack.startActivityLocked(null, intent, null, aInfo, 2142 null, null, 0, 0, 0, 0, null, false, null); 2143 } 2144 } 2145 2146 return true; 2147 } 2148 2149 /** 2150 * Starts the "new version setup screen" if appropriate. 2151 */ 2152 void startSetupActivityLocked() { 2153 // Only do this once per boot. 2154 if (mCheckedForSetup) { 2155 return; 2156 } 2157 2158 // We will show this screen if the current one is a different 2159 // version than the last one shown, and we are not running in 2160 // low-level factory test mode. 2161 final ContentResolver resolver = mContext.getContentResolver(); 2162 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2163 Settings.Secure.getInt(resolver, 2164 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2165 mCheckedForSetup = true; 2166 2167 // See if we should be showing the platform update setup UI. 2168 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2169 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2170 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2171 2172 // We don't allow third party apps to replace this. 2173 ResolveInfo ri = null; 2174 for (int i=0; ris != null && i<ris.size(); i++) { 2175 if ((ris.get(i).activityInfo.applicationInfo.flags 2176 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2177 ri = ris.get(i); 2178 break; 2179 } 2180 } 2181 2182 if (ri != null) { 2183 String vers = ri.activityInfo.metaData != null 2184 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2185 : null; 2186 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2187 vers = ri.activityInfo.applicationInfo.metaData.getString( 2188 Intent.METADATA_SETUP_VERSION); 2189 } 2190 String lastVers = Settings.Secure.getString( 2191 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2192 if (vers != null && !vers.equals(lastVers)) { 2193 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2194 intent.setComponent(new ComponentName( 2195 ri.activityInfo.packageName, ri.activityInfo.name)); 2196 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2197 null, null, 0, 0, 0, 0, null, false, null); 2198 } 2199 } 2200 } 2201 } 2202 2203 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2204 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2205 } 2206 2207 void enforceNotIsolatedCaller(String caller) { 2208 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2209 throw new SecurityException("Isolated process not allowed to call " + caller); 2210 } 2211 } 2212 2213 public int getFrontActivityScreenCompatMode() { 2214 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2215 synchronized (this) { 2216 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2217 } 2218 } 2219 2220 public void setFrontActivityScreenCompatMode(int mode) { 2221 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2222 "setFrontActivityScreenCompatMode"); 2223 synchronized (this) { 2224 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2225 } 2226 } 2227 2228 public int getPackageScreenCompatMode(String packageName) { 2229 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2230 synchronized (this) { 2231 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2232 } 2233 } 2234 2235 public void setPackageScreenCompatMode(String packageName, int mode) { 2236 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2237 "setPackageScreenCompatMode"); 2238 synchronized (this) { 2239 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2240 } 2241 } 2242 2243 public boolean getPackageAskScreenCompat(String packageName) { 2244 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2245 synchronized (this) { 2246 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2247 } 2248 } 2249 2250 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2251 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2252 "setPackageAskScreenCompat"); 2253 synchronized (this) { 2254 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2255 } 2256 } 2257 2258 void reportResumedActivityLocked(ActivityRecord r) { 2259 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2260 updateUsageStats(r, true); 2261 } 2262 2263 private void dispatchProcessesChanged() { 2264 int N; 2265 synchronized (this) { 2266 N = mPendingProcessChanges.size(); 2267 if (mActiveProcessChanges.length < N) { 2268 mActiveProcessChanges = new ProcessChangeItem[N]; 2269 } 2270 mPendingProcessChanges.toArray(mActiveProcessChanges); 2271 mAvailProcessChanges.addAll(mPendingProcessChanges); 2272 mPendingProcessChanges.clear(); 2273 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2274 } 2275 int i = mProcessObservers.beginBroadcast(); 2276 while (i > 0) { 2277 i--; 2278 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2279 if (observer != null) { 2280 try { 2281 for (int j=0; j<N; j++) { 2282 ProcessChangeItem item = mActiveProcessChanges[j]; 2283 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2284 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2285 + item.pid + " uid=" + item.uid + ": " 2286 + item.foregroundActivities); 2287 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2288 item.foregroundActivities); 2289 } 2290 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2291 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2292 + item.pid + " uid=" + item.uid + ": " + item.importance); 2293 observer.onImportanceChanged(item.pid, item.uid, 2294 item.importance); 2295 } 2296 } 2297 } catch (RemoteException e) { 2298 } 2299 } 2300 } 2301 mProcessObservers.finishBroadcast(); 2302 } 2303 2304 private void dispatchProcessDied(int pid, int uid) { 2305 int i = mProcessObservers.beginBroadcast(); 2306 while (i > 0) { 2307 i--; 2308 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2309 if (observer != null) { 2310 try { 2311 observer.onProcessDied(pid, uid); 2312 } catch (RemoteException e) { 2313 } 2314 } 2315 } 2316 mProcessObservers.finishBroadcast(); 2317 } 2318 2319 final void doPendingActivityLaunchesLocked(boolean doResume) { 2320 final int N = mPendingActivityLaunches.size(); 2321 if (N <= 0) { 2322 return; 2323 } 2324 for (int i=0; i<N; i++) { 2325 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2326 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2327 pal.startFlags, doResume && i == (N-1), null); 2328 } 2329 mPendingActivityLaunches.clear(); 2330 } 2331 2332 public final int startActivity(IApplicationThread caller, 2333 Intent intent, String resolvedType, IBinder resultTo, 2334 String resultWho, int requestCode, int startFlags, 2335 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2336 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2337 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2338 } 2339 2340 public final int startActivityAsUser(IApplicationThread caller, 2341 Intent intent, String resolvedType, IBinder resultTo, 2342 String resultWho, int requestCode, int startFlags, 2343 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2344 enforceNotIsolatedCaller("startActivity"); 2345 if (userId != UserHandle.getCallingUserId()) { 2346 // Requesting a different user, make sure that they have the permission 2347 if (checkComponentPermission( 2348 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2349 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2350 == PackageManager.PERMISSION_GRANTED) { 2351 // Translate to the current user id, if caller wasn't aware 2352 if (userId == UserHandle.USER_CURRENT) { 2353 userId = mCurrentUserId; 2354 } 2355 } else { 2356 String msg = "Permission Denial: " 2357 + "Request to startActivity as user " + userId 2358 + " but is calling from user " + UserHandle.getCallingUserId() 2359 + "; this requires " 2360 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2361 Slog.w(TAG, msg); 2362 throw new SecurityException(msg); 2363 } 2364 } else { 2365 if (intent.getCategories() != null 2366 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2367 // Requesting home, set the identity to the current user 2368 // HACK! 2369 userId = mCurrentUserId; 2370 } else { 2371 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2372 // the current user's userId 2373 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2374 userId = 0; 2375 } else { 2376 userId = Binder.getOrigCallingUser(); 2377 } 2378 } 2379 } 2380 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2381 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2382 null, null, options, userId); 2383 } 2384 2385 public final WaitResult startActivityAndWait(IApplicationThread caller, 2386 Intent intent, String resolvedType, IBinder resultTo, 2387 String resultWho, int requestCode, int startFlags, String profileFile, 2388 ParcelFileDescriptor profileFd, Bundle options) { 2389 enforceNotIsolatedCaller("startActivityAndWait"); 2390 WaitResult res = new WaitResult(); 2391 int userId = Binder.getOrigCallingUser(); 2392 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2393 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2394 res, null, options, userId); 2395 return res; 2396 } 2397 2398 public final int startActivityWithConfig(IApplicationThread caller, 2399 Intent intent, String resolvedType, IBinder resultTo, 2400 String resultWho, int requestCode, int startFlags, Configuration config, 2401 Bundle options) { 2402 enforceNotIsolatedCaller("startActivityWithConfig"); 2403 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2404 resultTo, resultWho, requestCode, startFlags, 2405 null, null, null, config, options, Binder.getOrigCallingUser()); 2406 return ret; 2407 } 2408 2409 public int startActivityIntentSender(IApplicationThread caller, 2410 IntentSender intent, Intent fillInIntent, String resolvedType, 2411 IBinder resultTo, String resultWho, int requestCode, 2412 int flagsMask, int flagsValues, Bundle options) { 2413 enforceNotIsolatedCaller("startActivityIntentSender"); 2414 // Refuse possible leaked file descriptors 2415 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2416 throw new IllegalArgumentException("File descriptors passed in Intent"); 2417 } 2418 2419 IIntentSender sender = intent.getTarget(); 2420 if (!(sender instanceof PendingIntentRecord)) { 2421 throw new IllegalArgumentException("Bad PendingIntent object"); 2422 } 2423 2424 PendingIntentRecord pir = (PendingIntentRecord)sender; 2425 2426 synchronized (this) { 2427 // If this is coming from the currently resumed activity, it is 2428 // effectively saying that app switches are allowed at this point. 2429 if (mMainStack.mResumedActivity != null 2430 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2431 Binder.getCallingUid()) { 2432 mAppSwitchesAllowedTime = 0; 2433 } 2434 } 2435 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2436 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2437 return ret; 2438 } 2439 2440 public boolean startNextMatchingActivity(IBinder callingActivity, 2441 Intent intent, Bundle options) { 2442 // Refuse possible leaked file descriptors 2443 if (intent != null && intent.hasFileDescriptors() == true) { 2444 throw new IllegalArgumentException("File descriptors passed in Intent"); 2445 } 2446 2447 synchronized (this) { 2448 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2449 if (r == null) { 2450 ActivityOptions.abort(options); 2451 return false; 2452 } 2453 if (r.app == null || r.app.thread == null) { 2454 // The caller is not running... d'oh! 2455 ActivityOptions.abort(options); 2456 return false; 2457 } 2458 intent = new Intent(intent); 2459 // The caller is not allowed to change the data. 2460 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2461 // And we are resetting to find the next component... 2462 intent.setComponent(null); 2463 2464 ActivityInfo aInfo = null; 2465 try { 2466 List<ResolveInfo> resolves = 2467 AppGlobals.getPackageManager().queryIntentActivities( 2468 intent, r.resolvedType, 2469 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2470 UserHandle.getCallingUserId()); 2471 2472 // Look for the original activity in the list... 2473 final int N = resolves != null ? resolves.size() : 0; 2474 for (int i=0; i<N; i++) { 2475 ResolveInfo rInfo = resolves.get(i); 2476 if (rInfo.activityInfo.packageName.equals(r.packageName) 2477 && rInfo.activityInfo.name.equals(r.info.name)) { 2478 // We found the current one... the next matching is 2479 // after it. 2480 i++; 2481 if (i<N) { 2482 aInfo = resolves.get(i).activityInfo; 2483 } 2484 break; 2485 } 2486 } 2487 } catch (RemoteException e) { 2488 } 2489 2490 if (aInfo == null) { 2491 // Nobody who is next! 2492 ActivityOptions.abort(options); 2493 return false; 2494 } 2495 2496 intent.setComponent(new ComponentName( 2497 aInfo.applicationInfo.packageName, aInfo.name)); 2498 intent.setFlags(intent.getFlags()&~( 2499 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2500 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2501 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2502 Intent.FLAG_ACTIVITY_NEW_TASK)); 2503 2504 // Okay now we need to start the new activity, replacing the 2505 // currently running activity. This is a little tricky because 2506 // we want to start the new one as if the current one is finished, 2507 // but not finish the current one first so that there is no flicker. 2508 // And thus... 2509 final boolean wasFinishing = r.finishing; 2510 r.finishing = true; 2511 2512 // Propagate reply information over to the new activity. 2513 final ActivityRecord resultTo = r.resultTo; 2514 final String resultWho = r.resultWho; 2515 final int requestCode = r.requestCode; 2516 r.resultTo = null; 2517 if (resultTo != null) { 2518 resultTo.removeResultsLocked(r, resultWho, requestCode); 2519 } 2520 2521 final long origId = Binder.clearCallingIdentity(); 2522 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2523 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2524 resultWho, requestCode, -1, r.launchedFromUid, 0, 2525 options, false, null); 2526 Binder.restoreCallingIdentity(origId); 2527 2528 r.finishing = wasFinishing; 2529 if (res != ActivityManager.START_SUCCESS) { 2530 return false; 2531 } 2532 return true; 2533 } 2534 } 2535 2536 public final int startActivityInPackage(int uid, 2537 Intent intent, String resolvedType, IBinder resultTo, 2538 String resultWho, int requestCode, int startFlags, Bundle options) { 2539 2540 // This is so super not safe, that only the system (or okay root) 2541 // can do it. 2542 int userId = Binder.getOrigCallingUser(); 2543 final int callingUid = Binder.getCallingUid(); 2544 if (callingUid != 0 && callingUid != Process.myUid()) { 2545 throw new SecurityException( 2546 "startActivityInPackage only available to the system"); 2547 } 2548 2549 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2550 resultTo, resultWho, requestCode, startFlags, 2551 null, null, null, null, options, userId); 2552 return ret; 2553 } 2554 2555 public final int startActivities(IApplicationThread caller, 2556 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2557 enforceNotIsolatedCaller("startActivities"); 2558 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2559 options, Binder.getOrigCallingUser()); 2560 return ret; 2561 } 2562 2563 public final int startActivitiesInPackage(int uid, 2564 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2565 Bundle options) { 2566 2567 // This is so super not safe, that only the system (or okay root) 2568 // can do it. 2569 final int callingUid = Binder.getCallingUid(); 2570 if (callingUid != 0 && callingUid != Process.myUid()) { 2571 throw new SecurityException( 2572 "startActivityInPackage only available to the system"); 2573 } 2574 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2575 options, UserHandle.getUserId(uid)); 2576 return ret; 2577 } 2578 2579 final void addRecentTaskLocked(TaskRecord task) { 2580 int N = mRecentTasks.size(); 2581 // Quick case: check if the top-most recent task is the same. 2582 if (N > 0 && mRecentTasks.get(0) == task) { 2583 return; 2584 } 2585 // Remove any existing entries that are the same kind of task. 2586 for (int i=0; i<N; i++) { 2587 TaskRecord tr = mRecentTasks.get(i); 2588 if (task.userId == tr.userId 2589 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2590 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2591 mRecentTasks.remove(i); 2592 i--; 2593 N--; 2594 if (task.intent == null) { 2595 // If the new recent task we are adding is not fully 2596 // specified, then replace it with the existing recent task. 2597 task = tr; 2598 } 2599 } 2600 } 2601 if (N >= MAX_RECENT_TASKS) { 2602 mRecentTasks.remove(N-1); 2603 } 2604 mRecentTasks.add(0, task); 2605 } 2606 2607 public void setRequestedOrientation(IBinder token, 2608 int requestedOrientation) { 2609 synchronized (this) { 2610 ActivityRecord r = mMainStack.isInStackLocked(token); 2611 if (r == null) { 2612 return; 2613 } 2614 final long origId = Binder.clearCallingIdentity(); 2615 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2616 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2617 mConfiguration, 2618 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2619 if (config != null) { 2620 r.frozenBeforeDestroy = true; 2621 if (!updateConfigurationLocked(config, r, false, false)) { 2622 mMainStack.resumeTopActivityLocked(null); 2623 } 2624 } 2625 Binder.restoreCallingIdentity(origId); 2626 } 2627 } 2628 2629 public int getRequestedOrientation(IBinder token) { 2630 synchronized (this) { 2631 ActivityRecord r = mMainStack.isInStackLocked(token); 2632 if (r == null) { 2633 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2634 } 2635 return mWindowManager.getAppOrientation(r.appToken); 2636 } 2637 } 2638 2639 /** 2640 * This is the internal entry point for handling Activity.finish(). 2641 * 2642 * @param token The Binder token referencing the Activity we want to finish. 2643 * @param resultCode Result code, if any, from this Activity. 2644 * @param resultData Result data (Intent), if any, from this Activity. 2645 * 2646 * @return Returns true if the activity successfully finished, or false if it is still running. 2647 */ 2648 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2649 // Refuse possible leaked file descriptors 2650 if (resultData != null && resultData.hasFileDescriptors() == true) { 2651 throw new IllegalArgumentException("File descriptors passed in Intent"); 2652 } 2653 2654 synchronized(this) { 2655 if (mController != null) { 2656 // Find the first activity that is not finishing. 2657 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2658 if (next != null) { 2659 // ask watcher if this is allowed 2660 boolean resumeOK = true; 2661 try { 2662 resumeOK = mController.activityResuming(next.packageName); 2663 } catch (RemoteException e) { 2664 mController = null; 2665 } 2666 2667 if (!resumeOK) { 2668 return false; 2669 } 2670 } 2671 } 2672 final long origId = Binder.clearCallingIdentity(); 2673 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2674 resultData, "app-request"); 2675 Binder.restoreCallingIdentity(origId); 2676 return res; 2677 } 2678 } 2679 2680 public final void finishHeavyWeightApp() { 2681 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2682 != PackageManager.PERMISSION_GRANTED) { 2683 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2684 + Binder.getCallingPid() 2685 + ", uid=" + Binder.getCallingUid() 2686 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2687 Slog.w(TAG, msg); 2688 throw new SecurityException(msg); 2689 } 2690 2691 synchronized(this) { 2692 if (mHeavyWeightProcess == null) { 2693 return; 2694 } 2695 2696 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2697 mHeavyWeightProcess.activities); 2698 for (int i=0; i<activities.size(); i++) { 2699 ActivityRecord r = activities.get(i); 2700 if (!r.finishing) { 2701 int index = mMainStack.indexOfTokenLocked(r.appToken); 2702 if (index >= 0) { 2703 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2704 null, "finish-heavy"); 2705 } 2706 } 2707 } 2708 2709 mHeavyWeightProcess = null; 2710 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2711 } 2712 } 2713 2714 public void crashApplication(int uid, int initialPid, String packageName, 2715 String message) { 2716 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2717 != PackageManager.PERMISSION_GRANTED) { 2718 String msg = "Permission Denial: crashApplication() from pid=" 2719 + Binder.getCallingPid() 2720 + ", uid=" + Binder.getCallingUid() 2721 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2722 Slog.w(TAG, msg); 2723 throw new SecurityException(msg); 2724 } 2725 2726 synchronized(this) { 2727 ProcessRecord proc = null; 2728 2729 // Figure out which process to kill. We don't trust that initialPid 2730 // still has any relation to current pids, so must scan through the 2731 // list. 2732 synchronized (mPidsSelfLocked) { 2733 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2734 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2735 if (p.uid != uid) { 2736 continue; 2737 } 2738 if (p.pid == initialPid) { 2739 proc = p; 2740 break; 2741 } 2742 for (String str : p.pkgList) { 2743 if (str.equals(packageName)) { 2744 proc = p; 2745 } 2746 } 2747 } 2748 } 2749 2750 if (proc == null) { 2751 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2752 + " initialPid=" + initialPid 2753 + " packageName=" + packageName); 2754 return; 2755 } 2756 2757 if (proc.thread != null) { 2758 if (proc.pid == Process.myPid()) { 2759 Log.w(TAG, "crashApplication: trying to crash self!"); 2760 return; 2761 } 2762 long ident = Binder.clearCallingIdentity(); 2763 try { 2764 proc.thread.scheduleCrash(message); 2765 } catch (RemoteException e) { 2766 } 2767 Binder.restoreCallingIdentity(ident); 2768 } 2769 } 2770 } 2771 2772 public final void finishSubActivity(IBinder token, String resultWho, 2773 int requestCode) { 2774 synchronized(this) { 2775 final long origId = Binder.clearCallingIdentity(); 2776 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2777 Binder.restoreCallingIdentity(origId); 2778 } 2779 } 2780 2781 public boolean finishActivityAffinity(IBinder token) { 2782 synchronized(this) { 2783 final long origId = Binder.clearCallingIdentity(); 2784 boolean res = mMainStack.finishActivityAffinityLocked(token); 2785 Binder.restoreCallingIdentity(origId); 2786 return res; 2787 } 2788 } 2789 2790 public boolean willActivityBeVisible(IBinder token) { 2791 synchronized(this) { 2792 int i; 2793 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2794 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2795 if (r.appToken == token) { 2796 return true; 2797 } 2798 if (r.fullscreen && !r.finishing) { 2799 return false; 2800 } 2801 } 2802 return true; 2803 } 2804 } 2805 2806 public void overridePendingTransition(IBinder token, String packageName, 2807 int enterAnim, int exitAnim) { 2808 synchronized(this) { 2809 ActivityRecord self = mMainStack.isInStackLocked(token); 2810 if (self == null) { 2811 return; 2812 } 2813 2814 final long origId = Binder.clearCallingIdentity(); 2815 2816 if (self.state == ActivityState.RESUMED 2817 || self.state == ActivityState.PAUSING) { 2818 mWindowManager.overridePendingAppTransition(packageName, 2819 enterAnim, exitAnim, null); 2820 } 2821 2822 Binder.restoreCallingIdentity(origId); 2823 } 2824 } 2825 2826 /** 2827 * Main function for removing an existing process from the activity manager 2828 * as a result of that process going away. Clears out all connections 2829 * to the process. 2830 */ 2831 private final void handleAppDiedLocked(ProcessRecord app, 2832 boolean restarting, boolean allowRestart) { 2833 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2834 if (!restarting) { 2835 mLruProcesses.remove(app); 2836 } 2837 2838 if (mProfileProc == app) { 2839 clearProfilerLocked(); 2840 } 2841 2842 // Just in case... 2843 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2844 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2845 mMainStack.mPausingActivity = null; 2846 } 2847 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2848 mMainStack.mLastPausedActivity = null; 2849 } 2850 2851 // Remove this application's activities from active lists. 2852 mMainStack.removeHistoryRecordsForAppLocked(app); 2853 2854 boolean atTop = true; 2855 boolean hasVisibleActivities = false; 2856 2857 // Clean out the history list. 2858 int i = mMainStack.mHistory.size(); 2859 if (localLOGV) Slog.v( 2860 TAG, "Removing app " + app + " from history with " + i + " entries"); 2861 while (i > 0) { 2862 i--; 2863 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2864 if (localLOGV) Slog.v( 2865 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2866 if (r.app == app) { 2867 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2868 if (ActivityStack.DEBUG_ADD_REMOVE) { 2869 RuntimeException here = new RuntimeException("here"); 2870 here.fillInStackTrace(); 2871 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2872 + ": haveState=" + r.haveState 2873 + " stateNotNeeded=" + r.stateNotNeeded 2874 + " finishing=" + r.finishing 2875 + " state=" + r.state, here); 2876 } 2877 if (!r.finishing) { 2878 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2879 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2880 System.identityHashCode(r), 2881 r.task.taskId, r.shortComponentName, 2882 "proc died without state saved"); 2883 } 2884 mMainStack.removeActivityFromHistoryLocked(r); 2885 2886 } else { 2887 // We have the current state for this activity, so 2888 // it can be restarted later when needed. 2889 if (localLOGV) Slog.v( 2890 TAG, "Keeping entry, setting app to null"); 2891 if (r.visible) { 2892 hasVisibleActivities = true; 2893 } 2894 r.app = null; 2895 r.nowVisible = false; 2896 if (!r.haveState) { 2897 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2898 "App died, clearing saved state of " + r); 2899 r.icicle = null; 2900 } 2901 } 2902 2903 r.stack.cleanUpActivityLocked(r, true, true); 2904 } 2905 atTop = false; 2906 } 2907 2908 app.activities.clear(); 2909 2910 if (app.instrumentationClass != null) { 2911 Slog.w(TAG, "Crash of app " + app.processName 2912 + " running instrumentation " + app.instrumentationClass); 2913 Bundle info = new Bundle(); 2914 info.putString("shortMsg", "Process crashed."); 2915 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2916 } 2917 2918 if (!restarting) { 2919 if (!mMainStack.resumeTopActivityLocked(null)) { 2920 // If there was nothing to resume, and we are not already 2921 // restarting this process, but there is a visible activity that 2922 // is hosted by the process... then make sure all visible 2923 // activities are running, taking care of restarting this 2924 // process. 2925 if (hasVisibleActivities) { 2926 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2927 } 2928 } 2929 } 2930 } 2931 2932 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2933 IBinder threadBinder = thread.asBinder(); 2934 // Find the application record. 2935 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2936 ProcessRecord rec = mLruProcesses.get(i); 2937 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2938 return i; 2939 } 2940 } 2941 return -1; 2942 } 2943 2944 final ProcessRecord getRecordForAppLocked( 2945 IApplicationThread thread) { 2946 if (thread == null) { 2947 return null; 2948 } 2949 2950 int appIndex = getLRURecordIndexForAppLocked(thread); 2951 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2952 } 2953 2954 final void appDiedLocked(ProcessRecord app, int pid, 2955 IApplicationThread thread) { 2956 2957 mProcDeaths[0]++; 2958 2959 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2960 synchronized (stats) { 2961 stats.noteProcessDiedLocked(app.info.uid, pid); 2962 } 2963 2964 // Clean up already done if the process has been re-started. 2965 if (app.pid == pid && app.thread != null && 2966 app.thread.asBinder() == thread.asBinder()) { 2967 if (!app.killedBackground) { 2968 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2969 + ") has died."); 2970 } 2971 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2972 if (localLOGV) Slog.v( 2973 TAG, "Dying app: " + app + ", pid: " + pid 2974 + ", thread: " + thread.asBinder()); 2975 boolean doLowMem = app.instrumentationClass == null; 2976 handleAppDiedLocked(app, false, true); 2977 2978 if (doLowMem) { 2979 // If there are no longer any background processes running, 2980 // and the app that died was not running instrumentation, 2981 // then tell everyone we are now low on memory. 2982 boolean haveBg = false; 2983 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2984 ProcessRecord rec = mLruProcesses.get(i); 2985 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2986 haveBg = true; 2987 break; 2988 } 2989 } 2990 2991 if (!haveBg) { 2992 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2993 long now = SystemClock.uptimeMillis(); 2994 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2995 ProcessRecord rec = mLruProcesses.get(i); 2996 if (rec != app && rec.thread != null && 2997 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2998 // The low memory report is overriding any current 2999 // state for a GC request. Make sure to do 3000 // heavy/important/visible/foreground processes first. 3001 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3002 rec.lastRequestedGc = 0; 3003 } else { 3004 rec.lastRequestedGc = rec.lastLowMemory; 3005 } 3006 rec.reportLowMemory = true; 3007 rec.lastLowMemory = now; 3008 mProcessesToGc.remove(rec); 3009 addProcessToGcListLocked(rec); 3010 } 3011 } 3012 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3013 scheduleAppGcsLocked(); 3014 } 3015 } 3016 } else if (app.pid != pid) { 3017 // A new process has already been started. 3018 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3019 + ") has died and restarted (pid " + app.pid + ")."); 3020 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3021 } else if (DEBUG_PROCESSES) { 3022 Slog.d(TAG, "Received spurious death notification for thread " 3023 + thread.asBinder()); 3024 } 3025 } 3026 3027 /** 3028 * If a stack trace dump file is configured, dump process stack traces. 3029 * @param clearTraces causes the dump file to be erased prior to the new 3030 * traces being written, if true; when false, the new traces will be 3031 * appended to any existing file content. 3032 * @param firstPids of dalvik VM processes to dump stack traces for first 3033 * @param lastPids of dalvik VM processes to dump stack traces for last 3034 * @param nativeProcs optional list of native process names to dump stack crawls 3035 * @return file containing stack traces, or null if no dump file is configured 3036 */ 3037 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3038 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3039 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3040 if (tracesPath == null || tracesPath.length() == 0) { 3041 return null; 3042 } 3043 3044 File tracesFile = new File(tracesPath); 3045 try { 3046 File tracesDir = tracesFile.getParentFile(); 3047 if (!tracesDir.exists()) tracesFile.mkdirs(); 3048 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3049 3050 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3051 tracesFile.createNewFile(); 3052 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3053 } catch (IOException e) { 3054 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3055 return null; 3056 } 3057 3058 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3059 return tracesFile; 3060 } 3061 3062 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3063 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3064 // Use a FileObserver to detect when traces finish writing. 3065 // The order of traces is considered important to maintain for legibility. 3066 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3067 public synchronized void onEvent(int event, String path) { notify(); } 3068 }; 3069 3070 try { 3071 observer.startWatching(); 3072 3073 // First collect all of the stacks of the most important pids. 3074 if (firstPids != null) { 3075 try { 3076 int num = firstPids.size(); 3077 for (int i = 0; i < num; i++) { 3078 synchronized (observer) { 3079 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3080 observer.wait(200); // Wait for write-close, give up after 200msec 3081 } 3082 } 3083 } catch (InterruptedException e) { 3084 Log.wtf(TAG, e); 3085 } 3086 } 3087 3088 // Next measure CPU usage. 3089 if (processStats != null) { 3090 processStats.init(); 3091 System.gc(); 3092 processStats.update(); 3093 try { 3094 synchronized (processStats) { 3095 processStats.wait(500); // measure over 1/2 second. 3096 } 3097 } catch (InterruptedException e) { 3098 } 3099 processStats.update(); 3100 3101 // We'll take the stack crawls of just the top apps using CPU. 3102 final int N = processStats.countWorkingStats(); 3103 int numProcs = 0; 3104 for (int i=0; i<N && numProcs<5; i++) { 3105 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3106 if (lastPids.indexOfKey(stats.pid) >= 0) { 3107 numProcs++; 3108 try { 3109 synchronized (observer) { 3110 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3111 observer.wait(200); // Wait for write-close, give up after 200msec 3112 } 3113 } catch (InterruptedException e) { 3114 Log.wtf(TAG, e); 3115 } 3116 3117 } 3118 } 3119 } 3120 3121 } finally { 3122 observer.stopWatching(); 3123 } 3124 3125 if (nativeProcs != null) { 3126 int[] pids = Process.getPidsForCommands(nativeProcs); 3127 if (pids != null) { 3128 for (int pid : pids) { 3129 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3130 } 3131 } 3132 } 3133 } 3134 3135 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3136 if (true || IS_USER_BUILD) { 3137 return; 3138 } 3139 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3140 if (tracesPath == null || tracesPath.length() == 0) { 3141 return; 3142 } 3143 3144 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3145 StrictMode.allowThreadDiskWrites(); 3146 try { 3147 final File tracesFile = new File(tracesPath); 3148 final File tracesDir = tracesFile.getParentFile(); 3149 final File tracesTmp = new File(tracesDir, "__tmp__"); 3150 try { 3151 if (!tracesDir.exists()) tracesFile.mkdirs(); 3152 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3153 3154 if (tracesFile.exists()) { 3155 tracesTmp.delete(); 3156 tracesFile.renameTo(tracesTmp); 3157 } 3158 StringBuilder sb = new StringBuilder(); 3159 Time tobj = new Time(); 3160 tobj.set(System.currentTimeMillis()); 3161 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3162 sb.append(": "); 3163 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3164 sb.append(" since "); 3165 sb.append(msg); 3166 FileOutputStream fos = new FileOutputStream(tracesFile); 3167 fos.write(sb.toString().getBytes()); 3168 if (app == null) { 3169 fos.write("\n*** No application process!".getBytes()); 3170 } 3171 fos.close(); 3172 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3173 } catch (IOException e) { 3174 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3175 return; 3176 } 3177 3178 if (app != null) { 3179 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3180 firstPids.add(app.pid); 3181 dumpStackTraces(tracesPath, firstPids, null, null, null); 3182 } 3183 3184 File lastTracesFile = null; 3185 File curTracesFile = null; 3186 for (int i=9; i>=0; i--) { 3187 String name = String.format("slow%02d.txt", i); 3188 curTracesFile = new File(tracesDir, name); 3189 if (curTracesFile.exists()) { 3190 if (lastTracesFile != null) { 3191 curTracesFile.renameTo(lastTracesFile); 3192 } else { 3193 curTracesFile.delete(); 3194 } 3195 } 3196 lastTracesFile = curTracesFile; 3197 } 3198 tracesFile.renameTo(curTracesFile); 3199 if (tracesTmp.exists()) { 3200 tracesTmp.renameTo(tracesFile); 3201 } 3202 } finally { 3203 StrictMode.setThreadPolicy(oldPolicy); 3204 } 3205 } 3206 3207 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3208 ActivityRecord parent, final String annotation) { 3209 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3210 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3211 3212 if (mController != null) { 3213 try { 3214 // 0 == continue, -1 = kill process immediately 3215 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3216 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3217 } catch (RemoteException e) { 3218 mController = null; 3219 } 3220 } 3221 3222 long anrTime = SystemClock.uptimeMillis(); 3223 if (MONITOR_CPU_USAGE) { 3224 updateCpuStatsNow(); 3225 } 3226 3227 synchronized (this) { 3228 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3229 if (mShuttingDown) { 3230 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3231 return; 3232 } else if (app.notResponding) { 3233 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3234 return; 3235 } else if (app.crashing) { 3236 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3237 return; 3238 } 3239 3240 // In case we come through here for the same app before completing 3241 // this one, mark as anring now so we will bail out. 3242 app.notResponding = true; 3243 3244 // Log the ANR to the event log. 3245 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3246 annotation); 3247 3248 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3249 firstPids.add(app.pid); 3250 3251 int parentPid = app.pid; 3252 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3253 if (parentPid != app.pid) firstPids.add(parentPid); 3254 3255 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3256 3257 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3258 ProcessRecord r = mLruProcesses.get(i); 3259 if (r != null && r.thread != null) { 3260 int pid = r.pid; 3261 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3262 if (r.persistent) { 3263 firstPids.add(pid); 3264 } else { 3265 lastPids.put(pid, Boolean.TRUE); 3266 } 3267 } 3268 } 3269 } 3270 } 3271 3272 // Log the ANR to the main log. 3273 StringBuilder info = new StringBuilder(); 3274 info.setLength(0); 3275 info.append("ANR in ").append(app.processName); 3276 if (activity != null && activity.shortComponentName != null) { 3277 info.append(" (").append(activity.shortComponentName).append(")"); 3278 } 3279 info.append("\n"); 3280 if (annotation != null) { 3281 info.append("Reason: ").append(annotation).append("\n"); 3282 } 3283 if (parent != null && parent != activity) { 3284 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3285 } 3286 3287 final ProcessStats processStats = new ProcessStats(true); 3288 3289 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3290 3291 String cpuInfo = null; 3292 if (MONITOR_CPU_USAGE) { 3293 updateCpuStatsNow(); 3294 synchronized (mProcessStatsThread) { 3295 cpuInfo = mProcessStats.printCurrentState(anrTime); 3296 } 3297 info.append(processStats.printCurrentLoad()); 3298 info.append(cpuInfo); 3299 } 3300 3301 info.append(processStats.printCurrentState(anrTime)); 3302 3303 Slog.e(TAG, info.toString()); 3304 if (tracesFile == null) { 3305 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3306 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3307 } 3308 3309 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3310 cpuInfo, tracesFile, null); 3311 3312 if (mController != null) { 3313 try { 3314 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3315 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3316 if (res != 0) { 3317 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3318 return; 3319 } 3320 } catch (RemoteException e) { 3321 mController = null; 3322 } 3323 } 3324 3325 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3326 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3327 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3328 3329 synchronized (this) { 3330 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3331 Slog.w(TAG, "Killing " + app + ": background ANR"); 3332 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3333 app.processName, app.setAdj, "background ANR"); 3334 Process.killProcessQuiet(app.pid); 3335 return; 3336 } 3337 3338 // Set the app's notResponding state, and look up the errorReportReceiver 3339 makeAppNotRespondingLocked(app, 3340 activity != null ? activity.shortComponentName : null, 3341 annotation != null ? "ANR " + annotation : "ANR", 3342 info.toString()); 3343 3344 // Bring up the infamous App Not Responding dialog 3345 Message msg = Message.obtain(); 3346 HashMap map = new HashMap(); 3347 msg.what = SHOW_NOT_RESPONDING_MSG; 3348 msg.obj = map; 3349 map.put("app", app); 3350 if (activity != null) { 3351 map.put("activity", activity); 3352 } 3353 3354 mHandler.sendMessage(msg); 3355 } 3356 } 3357 3358 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3359 if (!mLaunchWarningShown) { 3360 mLaunchWarningShown = true; 3361 mHandler.post(new Runnable() { 3362 @Override 3363 public void run() { 3364 synchronized (ActivityManagerService.this) { 3365 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3366 d.show(); 3367 mHandler.postDelayed(new Runnable() { 3368 @Override 3369 public void run() { 3370 synchronized (ActivityManagerService.this) { 3371 d.dismiss(); 3372 mLaunchWarningShown = false; 3373 } 3374 } 3375 }, 4000); 3376 } 3377 } 3378 }); 3379 } 3380 } 3381 3382 public boolean clearApplicationUserData(final String packageName, 3383 final IPackageDataObserver observer, final int userId) { 3384 enforceNotIsolatedCaller("clearApplicationUserData"); 3385 int uid = Binder.getCallingUid(); 3386 int pid = Binder.getCallingPid(); 3387 long callingId = Binder.clearCallingIdentity(); 3388 try { 3389 IPackageManager pm = AppGlobals.getPackageManager(); 3390 int pkgUid = -1; 3391 synchronized(this) { 3392 try { 3393 pkgUid = pm.getPackageUid(packageName, userId); 3394 } catch (RemoteException e) { 3395 } 3396 if (pkgUid == -1) { 3397 Slog.w(TAG, "Invalid packageName:" + packageName); 3398 return false; 3399 } 3400 if (uid == pkgUid || checkComponentPermission( 3401 android.Manifest.permission.CLEAR_APP_USER_DATA, 3402 pid, uid, -1, true) 3403 == PackageManager.PERMISSION_GRANTED) { 3404 forceStopPackageLocked(packageName, pkgUid); 3405 } else { 3406 throw new SecurityException(pid+" does not have permission:"+ 3407 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3408 "for process:"+packageName); 3409 } 3410 } 3411 3412 try { 3413 //clear application user data 3414 pm.clearApplicationUserData(packageName, observer, userId); 3415 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3416 Uri.fromParts("package", packageName, null)); 3417 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3418 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3419 null, null, 0, null, null, null, false, false, userId); 3420 } catch (RemoteException e) { 3421 } 3422 } finally { 3423 Binder.restoreCallingIdentity(callingId); 3424 } 3425 return true; 3426 } 3427 3428 public void killBackgroundProcesses(final String packageName) { 3429 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3430 != PackageManager.PERMISSION_GRANTED && 3431 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3432 != PackageManager.PERMISSION_GRANTED) { 3433 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3434 + Binder.getCallingPid() 3435 + ", uid=" + Binder.getCallingUid() 3436 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3437 Slog.w(TAG, msg); 3438 throw new SecurityException(msg); 3439 } 3440 3441 int userId = UserHandle.getCallingUserId(); 3442 long callingId = Binder.clearCallingIdentity(); 3443 try { 3444 IPackageManager pm = AppGlobals.getPackageManager(); 3445 int pkgUid = -1; 3446 synchronized(this) { 3447 try { 3448 pkgUid = pm.getPackageUid(packageName, userId); 3449 } catch (RemoteException e) { 3450 } 3451 if (pkgUid == -1) { 3452 Slog.w(TAG, "Invalid packageName: " + packageName); 3453 return; 3454 } 3455 killPackageProcessesLocked(packageName, pkgUid, 3456 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3457 } 3458 } finally { 3459 Binder.restoreCallingIdentity(callingId); 3460 } 3461 } 3462 3463 public void killAllBackgroundProcesses() { 3464 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3465 != PackageManager.PERMISSION_GRANTED) { 3466 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3467 + Binder.getCallingPid() 3468 + ", uid=" + Binder.getCallingUid() 3469 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3470 Slog.w(TAG, msg); 3471 throw new SecurityException(msg); 3472 } 3473 3474 long callingId = Binder.clearCallingIdentity(); 3475 try { 3476 synchronized(this) { 3477 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3478 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3479 final int NA = apps.size(); 3480 for (int ia=0; ia<NA; ia++) { 3481 ProcessRecord app = apps.valueAt(ia); 3482 if (app.persistent) { 3483 // we don't kill persistent processes 3484 continue; 3485 } 3486 if (app.removed) { 3487 procs.add(app); 3488 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3489 app.removed = true; 3490 procs.add(app); 3491 } 3492 } 3493 } 3494 3495 int N = procs.size(); 3496 for (int i=0; i<N; i++) { 3497 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3498 } 3499 } 3500 } finally { 3501 Binder.restoreCallingIdentity(callingId); 3502 } 3503 } 3504 3505 public void forceStopPackage(final String packageName) { 3506 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3507 != PackageManager.PERMISSION_GRANTED) { 3508 String msg = "Permission Denial: forceStopPackage() from pid=" 3509 + Binder.getCallingPid() 3510 + ", uid=" + Binder.getCallingUid() 3511 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3512 Slog.w(TAG, msg); 3513 throw new SecurityException(msg); 3514 } 3515 final int userId = UserHandle.getCallingUserId(); 3516 long callingId = Binder.clearCallingIdentity(); 3517 try { 3518 IPackageManager pm = AppGlobals.getPackageManager(); 3519 int pkgUid = -1; 3520 synchronized(this) { 3521 try { 3522 pkgUid = pm.getPackageUid(packageName, userId); 3523 } catch (RemoteException e) { 3524 } 3525 if (pkgUid == -1) { 3526 Slog.w(TAG, "Invalid packageName: " + packageName); 3527 return; 3528 } 3529 forceStopPackageLocked(packageName, pkgUid); 3530 try { 3531 pm.setPackageStoppedState(packageName, true, userId); 3532 } catch (RemoteException e) { 3533 } catch (IllegalArgumentException e) { 3534 Slog.w(TAG, "Failed trying to unstop package " 3535 + packageName + ": " + e); 3536 } 3537 } 3538 } finally { 3539 Binder.restoreCallingIdentity(callingId); 3540 } 3541 } 3542 3543 /* 3544 * The pkg name and uid have to be specified. 3545 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3546 */ 3547 public void killApplicationWithUid(String pkg, int uid) { 3548 if (pkg == null) { 3549 return; 3550 } 3551 // Make sure the uid is valid. 3552 if (uid < 0) { 3553 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3554 return; 3555 } 3556 int callerUid = Binder.getCallingUid(); 3557 // Only the system server can kill an application 3558 if (callerUid == Process.SYSTEM_UID) { 3559 // Post an aysnc message to kill the application 3560 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3561 msg.arg1 = uid; 3562 msg.arg2 = 0; 3563 msg.obj = pkg; 3564 mHandler.sendMessage(msg); 3565 } else { 3566 throw new SecurityException(callerUid + " cannot kill pkg: " + 3567 pkg); 3568 } 3569 } 3570 3571 public void closeSystemDialogs(String reason) { 3572 enforceNotIsolatedCaller("closeSystemDialogs"); 3573 3574 final int uid = Binder.getCallingUid(); 3575 final long origId = Binder.clearCallingIdentity(); 3576 synchronized (this) { 3577 closeSystemDialogsLocked(uid, reason); 3578 } 3579 Binder.restoreCallingIdentity(origId); 3580 } 3581 3582 void closeSystemDialogsLocked(int callingUid, String reason) { 3583 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3584 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3585 if (reason != null) { 3586 intent.putExtra("reason", reason); 3587 } 3588 mWindowManager.closeSystemDialogs(reason); 3589 3590 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3591 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3592 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3593 r.stack.finishActivityLocked(r, i, 3594 Activity.RESULT_CANCELED, null, "close-sys"); 3595 } 3596 } 3597 3598 broadcastIntentLocked(null, null, intent, null, 3599 null, 0, null, null, null, false, false, -1, 3600 callingUid, 0 /* TODO: Verify */); 3601 } 3602 3603 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3604 throws RemoteException { 3605 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3606 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3607 for (int i=pids.length-1; i>=0; i--) { 3608 infos[i] = new Debug.MemoryInfo(); 3609 Debug.getMemoryInfo(pids[i], infos[i]); 3610 } 3611 return infos; 3612 } 3613 3614 public long[] getProcessPss(int[] pids) throws RemoteException { 3615 enforceNotIsolatedCaller("getProcessPss"); 3616 long[] pss = new long[pids.length]; 3617 for (int i=pids.length-1; i>=0; i--) { 3618 pss[i] = Debug.getPss(pids[i]); 3619 } 3620 return pss; 3621 } 3622 3623 public void killApplicationProcess(String processName, int uid) { 3624 if (processName == null) { 3625 return; 3626 } 3627 3628 int callerUid = Binder.getCallingUid(); 3629 // Only the system server can kill an application 3630 if (callerUid == Process.SYSTEM_UID) { 3631 synchronized (this) { 3632 ProcessRecord app = getProcessRecordLocked(processName, uid); 3633 if (app != null && app.thread != null) { 3634 try { 3635 app.thread.scheduleSuicide(); 3636 } catch (RemoteException e) { 3637 // If the other end already died, then our work here is done. 3638 } 3639 } else { 3640 Slog.w(TAG, "Process/uid not found attempting kill of " 3641 + processName + " / " + uid); 3642 } 3643 } 3644 } else { 3645 throw new SecurityException(callerUid + " cannot kill app process: " + 3646 processName); 3647 } 3648 } 3649 3650 private void forceStopPackageLocked(final String packageName, int uid) { 3651 forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid)); 3652 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3653 Uri.fromParts("package", packageName, null)); 3654 if (!mProcessesReady) { 3655 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3656 } 3657 intent.putExtra(Intent.EXTRA_UID, uid); 3658 broadcastIntentLocked(null, null, intent, 3659 null, null, 0, null, null, null, 3660 false, false, 3661 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3662 } 3663 3664 private final boolean killPackageProcessesLocked(String packageName, int uid, 3665 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3666 boolean evenPersistent, String reason) { 3667 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3668 3669 // Remove all processes this package may have touched: all with the 3670 // same UID (except for the system or root user), and all whose name 3671 // matches the package name. 3672 final String procNamePrefix = packageName + ":"; 3673 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3674 final int NA = apps.size(); 3675 for (int ia=0; ia<NA; ia++) { 3676 ProcessRecord app = apps.valueAt(ia); 3677 if (app.persistent && !evenPersistent) { 3678 // we don't kill persistent processes 3679 continue; 3680 } 3681 if (app.removed) { 3682 if (doit) { 3683 procs.add(app); 3684 } 3685 // If uid is specified and the uid and process name match 3686 // Or, the uid is not specified and the process name matches 3687 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3688 || ((app.processName.equals(packageName) 3689 || app.processName.startsWith(procNamePrefix)) 3690 && uid < 0))) { 3691 if (app.setAdj >= minOomAdj) { 3692 if (!doit) { 3693 return true; 3694 } 3695 app.removed = true; 3696 procs.add(app); 3697 } 3698 } 3699 } 3700 } 3701 3702 int N = procs.size(); 3703 for (int i=0; i<N; i++) { 3704 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3705 } 3706 return N > 0; 3707 } 3708 3709 private final boolean forceStopPackageLocked(String name, int uid, 3710 boolean callerWillRestart, boolean purgeCache, boolean doit, 3711 boolean evenPersistent, int userId) { 3712 int i; 3713 int N; 3714 3715 if (uid < 0) { 3716 try { 3717 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3718 } catch (RemoteException e) { 3719 } 3720 } 3721 3722 if (doit) { 3723 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3724 3725 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3726 while (badApps.hasNext()) { 3727 SparseArray<Long> ba = badApps.next(); 3728 if (ba.get(uid) != null) { 3729 badApps.remove(); 3730 } 3731 } 3732 } 3733 3734 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3735 callerWillRestart, false, doit, evenPersistent, "force stop"); 3736 3737 TaskRecord lastTask = null; 3738 for (i=0; i<mMainStack.mHistory.size(); i++) { 3739 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3740 final boolean samePackage = r.packageName.equals(name); 3741 if (r.userId == userId 3742 && (samePackage || r.task == lastTask) 3743 && (r.app == null || evenPersistent || !r.app.persistent)) { 3744 if (!doit) { 3745 if (r.finishing) { 3746 // If this activity is just finishing, then it is not 3747 // interesting as far as something to stop. 3748 continue; 3749 } 3750 return true; 3751 } 3752 didSomething = true; 3753 Slog.i(TAG, " Force finishing activity " + r); 3754 if (samePackage) { 3755 if (r.app != null) { 3756 r.app.removed = true; 3757 } 3758 r.app = null; 3759 } 3760 lastTask = r.task; 3761 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3762 null, "force-stop", true)) { 3763 i--; 3764 } 3765 } 3766 } 3767 3768 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3769 if (!doit) { 3770 return true; 3771 } 3772 didSomething = true; 3773 } 3774 3775 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3776 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3777 if (provider.info.packageName.equals(name) 3778 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3779 if (!doit) { 3780 return true; 3781 } 3782 didSomething = true; 3783 providers.add(provider); 3784 } 3785 } 3786 3787 N = providers.size(); 3788 for (i=0; i<N; i++) { 3789 removeDyingProviderLocked(null, providers.get(i), true); 3790 } 3791 3792 if (doit) { 3793 if (purgeCache) { 3794 AttributeCache ac = AttributeCache.instance(); 3795 if (ac != null) { 3796 ac.removePackage(name); 3797 } 3798 } 3799 if (mBooted) { 3800 mMainStack.resumeTopActivityLocked(null); 3801 mMainStack.scheduleIdleLocked(); 3802 } 3803 } 3804 3805 return didSomething; 3806 } 3807 3808 private final boolean removeProcessLocked(ProcessRecord app, 3809 boolean callerWillRestart, boolean allowRestart, String reason) { 3810 final String name = app.processName; 3811 final int uid = app.uid; 3812 if (DEBUG_PROCESSES) Slog.d( 3813 TAG, "Force removing proc " + app.toShortString() + " (" + name 3814 + "/" + uid + ")"); 3815 3816 mProcessNames.remove(name, uid); 3817 mIsolatedProcesses.remove(app.uid); 3818 if (mHeavyWeightProcess == app) { 3819 mHeavyWeightProcess = null; 3820 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3821 } 3822 boolean needRestart = false; 3823 if (app.pid > 0 && app.pid != MY_PID) { 3824 int pid = app.pid; 3825 synchronized (mPidsSelfLocked) { 3826 mPidsSelfLocked.remove(pid); 3827 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3828 } 3829 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3830 handleAppDiedLocked(app, true, allowRestart); 3831 mLruProcesses.remove(app); 3832 Process.killProcessQuiet(pid); 3833 3834 if (app.persistent && !app.isolated) { 3835 if (!callerWillRestart) { 3836 addAppLocked(app.info, false); 3837 } else { 3838 needRestart = true; 3839 } 3840 } 3841 } else { 3842 mRemovedProcesses.add(app); 3843 } 3844 3845 return needRestart; 3846 } 3847 3848 private final void processStartTimedOutLocked(ProcessRecord app) { 3849 final int pid = app.pid; 3850 boolean gone = false; 3851 synchronized (mPidsSelfLocked) { 3852 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3853 if (knownApp != null && knownApp.thread == null) { 3854 mPidsSelfLocked.remove(pid); 3855 gone = true; 3856 } 3857 } 3858 3859 if (gone) { 3860 Slog.w(TAG, "Process " + app + " failed to attach"); 3861 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3862 app.processName); 3863 mProcessNames.remove(app.processName, app.uid); 3864 mIsolatedProcesses.remove(app.uid); 3865 if (mHeavyWeightProcess == app) { 3866 mHeavyWeightProcess = null; 3867 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3868 } 3869 // Take care of any launching providers waiting for this process. 3870 checkAppInLaunchingProvidersLocked(app, true); 3871 // Take care of any services that are waiting for the process. 3872 mServices.processStartTimedOutLocked(app); 3873 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3874 app.processName, app.setAdj, "start timeout"); 3875 Process.killProcessQuiet(pid); 3876 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3877 Slog.w(TAG, "Unattached app died before backup, skipping"); 3878 try { 3879 IBackupManager bm = IBackupManager.Stub.asInterface( 3880 ServiceManager.getService(Context.BACKUP_SERVICE)); 3881 bm.agentDisconnected(app.info.packageName); 3882 } catch (RemoteException e) { 3883 // Can't happen; the backup manager is local 3884 } 3885 } 3886 if (isPendingBroadcastProcessLocked(pid)) { 3887 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3888 skipPendingBroadcastLocked(pid); 3889 } 3890 } else { 3891 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3892 } 3893 } 3894 3895 private final boolean attachApplicationLocked(IApplicationThread thread, 3896 int pid) { 3897 3898 // Find the application record that is being attached... either via 3899 // the pid if we are running in multiple processes, or just pull the 3900 // next app record if we are emulating process with anonymous threads. 3901 ProcessRecord app; 3902 if (pid != MY_PID && pid >= 0) { 3903 synchronized (mPidsSelfLocked) { 3904 app = mPidsSelfLocked.get(pid); 3905 } 3906 } else { 3907 app = null; 3908 } 3909 3910 if (app == null) { 3911 Slog.w(TAG, "No pending application record for pid " + pid 3912 + " (IApplicationThread " + thread + "); dropping process"); 3913 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3914 if (pid > 0 && pid != MY_PID) { 3915 Process.killProcessQuiet(pid); 3916 } else { 3917 try { 3918 thread.scheduleExit(); 3919 } catch (Exception e) { 3920 // Ignore exceptions. 3921 } 3922 } 3923 return false; 3924 } 3925 3926 // If this application record is still attached to a previous 3927 // process, clean it up now. 3928 if (app.thread != null) { 3929 handleAppDiedLocked(app, true, true); 3930 } 3931 3932 // Tell the process all about itself. 3933 3934 if (localLOGV) Slog.v( 3935 TAG, "Binding process pid " + pid + " to record " + app); 3936 3937 String processName = app.processName; 3938 try { 3939 AppDeathRecipient adr = new AppDeathRecipient( 3940 app, pid, thread); 3941 thread.asBinder().linkToDeath(adr, 0); 3942 app.deathRecipient = adr; 3943 } catch (RemoteException e) { 3944 app.resetPackageList(); 3945 startProcessLocked(app, "link fail", processName); 3946 return false; 3947 } 3948 3949 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3950 3951 app.thread = thread; 3952 app.curAdj = app.setAdj = -100; 3953 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3954 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3955 app.forcingToForeground = null; 3956 app.foregroundServices = false; 3957 app.hasShownUi = false; 3958 app.debugging = false; 3959 3960 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3961 3962 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3963 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3964 3965 if (!normalMode) { 3966 Slog.i(TAG, "Launching preboot mode app: " + app); 3967 } 3968 3969 if (localLOGV) Slog.v( 3970 TAG, "New app record " + app 3971 + " thread=" + thread.asBinder() + " pid=" + pid); 3972 try { 3973 int testMode = IApplicationThread.DEBUG_OFF; 3974 if (mDebugApp != null && mDebugApp.equals(processName)) { 3975 testMode = mWaitForDebugger 3976 ? IApplicationThread.DEBUG_WAIT 3977 : IApplicationThread.DEBUG_ON; 3978 app.debugging = true; 3979 if (mDebugTransient) { 3980 mDebugApp = mOrigDebugApp; 3981 mWaitForDebugger = mOrigWaitForDebugger; 3982 } 3983 } 3984 String profileFile = app.instrumentationProfileFile; 3985 ParcelFileDescriptor profileFd = null; 3986 boolean profileAutoStop = false; 3987 if (mProfileApp != null && mProfileApp.equals(processName)) { 3988 mProfileProc = app; 3989 profileFile = mProfileFile; 3990 profileFd = mProfileFd; 3991 profileAutoStop = mAutoStopProfiler; 3992 } 3993 boolean enableOpenGlTrace = false; 3994 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3995 enableOpenGlTrace = true; 3996 mOpenGlTraceApp = null; 3997 } 3998 3999 // If the app is being launched for restore or full backup, set it up specially 4000 boolean isRestrictedBackupMode = false; 4001 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4002 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4003 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4004 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4005 } 4006 4007 ensurePackageDexOpt(app.instrumentationInfo != null 4008 ? app.instrumentationInfo.packageName 4009 : app.info.packageName); 4010 if (app.instrumentationClass != null) { 4011 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4012 } 4013 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4014 + processName + " with config " + mConfiguration); 4015 ApplicationInfo appInfo = app.instrumentationInfo != null 4016 ? app.instrumentationInfo : app.info; 4017 app.compat = compatibilityInfoForPackageLocked(appInfo); 4018 if (profileFd != null) { 4019 profileFd = profileFd.dup(); 4020 } 4021 thread.bindApplication(processName, appInfo, providers, 4022 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4023 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4024 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4025 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4026 mCoreSettingsObserver.getCoreSettingsLocked()); 4027 updateLruProcessLocked(app, false, true); 4028 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4029 } catch (Exception e) { 4030 // todo: Yikes! What should we do? For now we will try to 4031 // start another process, but that could easily get us in 4032 // an infinite loop of restarting processes... 4033 Slog.w(TAG, "Exception thrown during bind!", e); 4034 4035 app.resetPackageList(); 4036 app.unlinkDeathRecipient(); 4037 startProcessLocked(app, "bind fail", processName); 4038 return false; 4039 } 4040 4041 // Remove this record from the list of starting applications. 4042 mPersistentStartingProcesses.remove(app); 4043 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4044 "Attach application locked removing on hold: " + app); 4045 mProcessesOnHold.remove(app); 4046 4047 boolean badApp = false; 4048 boolean didSomething = false; 4049 4050 // See if the top visible activity is waiting to run in this process... 4051 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4052 if (hr != null && normalMode) { 4053 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4054 && processName.equals(hr.processName)) { 4055 try { 4056 if (mHeadless) { 4057 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4058 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4059 didSomething = true; 4060 } 4061 } catch (Exception e) { 4062 Slog.w(TAG, "Exception in new application when starting activity " 4063 + hr.intent.getComponent().flattenToShortString(), e); 4064 badApp = true; 4065 } 4066 } else { 4067 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4068 } 4069 } 4070 4071 // Find any services that should be running in this process... 4072 if (!badApp) { 4073 try { 4074 didSomething |= mServices.attachApplicationLocked(app, processName); 4075 } catch (Exception e) { 4076 badApp = true; 4077 } 4078 } 4079 4080 // Check if a next-broadcast receiver is in this process... 4081 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4082 try { 4083 didSomething = sendPendingBroadcastsLocked(app); 4084 } catch (Exception e) { 4085 // If the app died trying to launch the receiver we declare it 'bad' 4086 badApp = true; 4087 } 4088 } 4089 4090 // Check whether the next backup agent is in this process... 4091 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4092 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4093 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4094 try { 4095 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4096 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4097 mBackupTarget.backupMode); 4098 } catch (Exception e) { 4099 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4100 e.printStackTrace(); 4101 } 4102 } 4103 4104 if (badApp) { 4105 // todo: Also need to kill application to deal with all 4106 // kinds of exceptions. 4107 handleAppDiedLocked(app, false, true); 4108 return false; 4109 } 4110 4111 if (!didSomething) { 4112 updateOomAdjLocked(); 4113 } 4114 4115 return true; 4116 } 4117 4118 public final void attachApplication(IApplicationThread thread) { 4119 synchronized (this) { 4120 int callingPid = Binder.getCallingPid(); 4121 final long origId = Binder.clearCallingIdentity(); 4122 attachApplicationLocked(thread, callingPid); 4123 Binder.restoreCallingIdentity(origId); 4124 } 4125 } 4126 4127 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4128 final long origId = Binder.clearCallingIdentity(); 4129 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4130 if (stopProfiling) { 4131 synchronized (this) { 4132 if (mProfileProc == r.app) { 4133 if (mProfileFd != null) { 4134 try { 4135 mProfileFd.close(); 4136 } catch (IOException e) { 4137 } 4138 clearProfilerLocked(); 4139 } 4140 } 4141 } 4142 } 4143 Binder.restoreCallingIdentity(origId); 4144 } 4145 4146 void enableScreenAfterBoot() { 4147 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4148 SystemClock.uptimeMillis()); 4149 mWindowManager.enableScreenAfterBoot(); 4150 4151 synchronized (this) { 4152 updateEventDispatchingLocked(); 4153 } 4154 } 4155 4156 public void showBootMessage(final CharSequence msg, final boolean always) { 4157 enforceNotIsolatedCaller("showBootMessage"); 4158 mWindowManager.showBootMessage(msg, always); 4159 } 4160 4161 public void dismissKeyguardOnNextActivity() { 4162 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4163 final long token = Binder.clearCallingIdentity(); 4164 try { 4165 synchronized (this) { 4166 if (mLockScreenShown) { 4167 mLockScreenShown = false; 4168 comeOutOfSleepIfNeededLocked(); 4169 } 4170 mMainStack.dismissKeyguardOnNextActivityLocked(); 4171 } 4172 } finally { 4173 Binder.restoreCallingIdentity(token); 4174 } 4175 } 4176 4177 final void finishBooting() { 4178 IntentFilter pkgFilter = new IntentFilter(); 4179 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4180 pkgFilter.addDataScheme("package"); 4181 mContext.registerReceiver(new BroadcastReceiver() { 4182 @Override 4183 public void onReceive(Context context, Intent intent) { 4184 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4185 if (pkgs != null) { 4186 for (String pkg : pkgs) { 4187 synchronized (ActivityManagerService.this) { 4188 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4189 setResultCode(Activity.RESULT_OK); 4190 return; 4191 } 4192 } 4193 } 4194 } 4195 } 4196 }, pkgFilter); 4197 4198 IntentFilter userFilter = new IntentFilter(); 4199 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4200 mContext.registerReceiver(new BroadcastReceiver() { 4201 @Override 4202 public void onReceive(Context context, Intent intent) { 4203 onUserRemoved(intent); 4204 } 4205 }, userFilter); 4206 4207 synchronized (this) { 4208 // Ensure that any processes we had put on hold are now started 4209 // up. 4210 final int NP = mProcessesOnHold.size(); 4211 if (NP > 0) { 4212 ArrayList<ProcessRecord> procs = 4213 new ArrayList<ProcessRecord>(mProcessesOnHold); 4214 for (int ip=0; ip<NP; ip++) { 4215 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4216 + procs.get(ip)); 4217 startProcessLocked(procs.get(ip), "on-hold", null); 4218 } 4219 } 4220 4221 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4222 // Start looking for apps that are abusing wake locks. 4223 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4224 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4225 // Tell anyone interested that we are done booting! 4226 SystemProperties.set("sys.boot_completed", "1"); 4227 SystemProperties.set("dev.bootcomplete", "1"); 4228 List<UserInfo> users = getUserManager().getUsers(); 4229 for (UserInfo user : users) { 4230 broadcastIntentLocked(null, null, 4231 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4232 null, null, 0, null, null, 4233 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4234 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4235 } 4236 } 4237 } 4238 } 4239 4240 final void ensureBootCompleted() { 4241 boolean booting; 4242 boolean enableScreen; 4243 synchronized (this) { 4244 booting = mBooting; 4245 mBooting = false; 4246 enableScreen = !mBooted; 4247 mBooted = true; 4248 } 4249 4250 if (booting) { 4251 finishBooting(); 4252 } 4253 4254 if (enableScreen) { 4255 enableScreenAfterBoot(); 4256 } 4257 } 4258 4259 public final void activityPaused(IBinder token) { 4260 final long origId = Binder.clearCallingIdentity(); 4261 mMainStack.activityPaused(token, false); 4262 Binder.restoreCallingIdentity(origId); 4263 } 4264 4265 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4266 CharSequence description) { 4267 if (localLOGV) Slog.v( 4268 TAG, "Activity stopped: token=" + token); 4269 4270 // Refuse possible leaked file descriptors 4271 if (icicle != null && icicle.hasFileDescriptors()) { 4272 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4273 } 4274 4275 ActivityRecord r = null; 4276 4277 final long origId = Binder.clearCallingIdentity(); 4278 4279 synchronized (this) { 4280 r = mMainStack.isInStackLocked(token); 4281 if (r != null) { 4282 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4283 } 4284 } 4285 4286 if (r != null) { 4287 sendPendingThumbnail(r, null, null, null, false); 4288 } 4289 4290 trimApplications(); 4291 4292 Binder.restoreCallingIdentity(origId); 4293 } 4294 4295 public final void activityDestroyed(IBinder token) { 4296 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4297 mMainStack.activityDestroyed(token); 4298 } 4299 4300 public String getCallingPackage(IBinder token) { 4301 synchronized (this) { 4302 ActivityRecord r = getCallingRecordLocked(token); 4303 return r != null && r.app != null ? r.info.packageName : null; 4304 } 4305 } 4306 4307 public ComponentName getCallingActivity(IBinder token) { 4308 synchronized (this) { 4309 ActivityRecord r = getCallingRecordLocked(token); 4310 return r != null ? r.intent.getComponent() : null; 4311 } 4312 } 4313 4314 private ActivityRecord getCallingRecordLocked(IBinder token) { 4315 ActivityRecord r = mMainStack.isInStackLocked(token); 4316 if (r == null) { 4317 return null; 4318 } 4319 return r.resultTo; 4320 } 4321 4322 public ComponentName getActivityClassForToken(IBinder token) { 4323 synchronized(this) { 4324 ActivityRecord r = mMainStack.isInStackLocked(token); 4325 if (r == null) { 4326 return null; 4327 } 4328 return r.intent.getComponent(); 4329 } 4330 } 4331 4332 public String getPackageForToken(IBinder token) { 4333 synchronized(this) { 4334 ActivityRecord r = mMainStack.isInStackLocked(token); 4335 if (r == null) { 4336 return null; 4337 } 4338 return r.packageName; 4339 } 4340 } 4341 4342 public IIntentSender getIntentSender(int type, 4343 String packageName, IBinder token, String resultWho, 4344 int requestCode, Intent[] intents, String[] resolvedTypes, 4345 int flags, Bundle options) { 4346 enforceNotIsolatedCaller("getIntentSender"); 4347 // Refuse possible leaked file descriptors 4348 if (intents != null) { 4349 if (intents.length < 1) { 4350 throw new IllegalArgumentException("Intents array length must be >= 1"); 4351 } 4352 for (int i=0; i<intents.length; i++) { 4353 Intent intent = intents[i]; 4354 if (intent != null) { 4355 if (intent.hasFileDescriptors()) { 4356 throw new IllegalArgumentException("File descriptors passed in Intent"); 4357 } 4358 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4359 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4360 throw new IllegalArgumentException( 4361 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4362 } 4363 intents[i] = new Intent(intent); 4364 } 4365 } 4366 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4367 throw new IllegalArgumentException( 4368 "Intent array length does not match resolvedTypes length"); 4369 } 4370 } 4371 if (options != null) { 4372 if (options.hasFileDescriptors()) { 4373 throw new IllegalArgumentException("File descriptors passed in options"); 4374 } 4375 } 4376 4377 synchronized(this) { 4378 int callingUid = Binder.getCallingUid(); 4379 try { 4380 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4381 int uid = AppGlobals.getPackageManager() 4382 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4383 if (!UserHandle.isSameApp(callingUid, uid)) { 4384 String msg = "Permission Denial: getIntentSender() from pid=" 4385 + Binder.getCallingPid() 4386 + ", uid=" + Binder.getCallingUid() 4387 + ", (need uid=" + uid + ")" 4388 + " is not allowed to send as package " + packageName; 4389 Slog.w(TAG, msg); 4390 throw new SecurityException(msg); 4391 } 4392 } 4393 4394 if (DEBUG_MU) 4395 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4396 + Binder.getOrigCallingUid()); 4397 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4398 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4399 4400 } catch (RemoteException e) { 4401 throw new SecurityException(e); 4402 } 4403 } 4404 } 4405 4406 IIntentSender getIntentSenderLocked(int type, 4407 String packageName, int callingUid, IBinder token, String resultWho, 4408 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4409 Bundle options) { 4410 if (DEBUG_MU) 4411 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4412 ActivityRecord activity = null; 4413 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4414 activity = mMainStack.isInStackLocked(token); 4415 if (activity == null) { 4416 return null; 4417 } 4418 if (activity.finishing) { 4419 return null; 4420 } 4421 } 4422 4423 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4424 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4425 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4426 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4427 |PendingIntent.FLAG_UPDATE_CURRENT); 4428 4429 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4430 type, packageName, activity, resultWho, 4431 requestCode, intents, resolvedTypes, flags, options); 4432 WeakReference<PendingIntentRecord> ref; 4433 ref = mIntentSenderRecords.get(key); 4434 PendingIntentRecord rec = ref != null ? ref.get() : null; 4435 if (rec != null) { 4436 if (!cancelCurrent) { 4437 if (updateCurrent) { 4438 if (rec.key.requestIntent != null) { 4439 rec.key.requestIntent.replaceExtras(intents != null ? 4440 intents[intents.length - 1] : null); 4441 } 4442 if (intents != null) { 4443 intents[intents.length-1] = rec.key.requestIntent; 4444 rec.key.allIntents = intents; 4445 rec.key.allResolvedTypes = resolvedTypes; 4446 } else { 4447 rec.key.allIntents = null; 4448 rec.key.allResolvedTypes = null; 4449 } 4450 } 4451 return rec; 4452 } 4453 rec.canceled = true; 4454 mIntentSenderRecords.remove(key); 4455 } 4456 if (noCreate) { 4457 return rec; 4458 } 4459 rec = new PendingIntentRecord(this, key, callingUid); 4460 mIntentSenderRecords.put(key, rec.ref); 4461 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4462 if (activity.pendingResults == null) { 4463 activity.pendingResults 4464 = new HashSet<WeakReference<PendingIntentRecord>>(); 4465 } 4466 activity.pendingResults.add(rec.ref); 4467 } 4468 return rec; 4469 } 4470 4471 public void cancelIntentSender(IIntentSender sender) { 4472 if (!(sender instanceof PendingIntentRecord)) { 4473 return; 4474 } 4475 synchronized(this) { 4476 PendingIntentRecord rec = (PendingIntentRecord)sender; 4477 try { 4478 int uid = AppGlobals.getPackageManager() 4479 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4480 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4481 String msg = "Permission Denial: cancelIntentSender() from pid=" 4482 + Binder.getCallingPid() 4483 + ", uid=" + Binder.getCallingUid() 4484 + " is not allowed to cancel packges " 4485 + rec.key.packageName; 4486 Slog.w(TAG, msg); 4487 throw new SecurityException(msg); 4488 } 4489 } catch (RemoteException e) { 4490 throw new SecurityException(e); 4491 } 4492 cancelIntentSenderLocked(rec, true); 4493 } 4494 } 4495 4496 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4497 rec.canceled = true; 4498 mIntentSenderRecords.remove(rec.key); 4499 if (cleanActivity && rec.key.activity != null) { 4500 rec.key.activity.pendingResults.remove(rec.ref); 4501 } 4502 } 4503 4504 public String getPackageForIntentSender(IIntentSender pendingResult) { 4505 if (!(pendingResult instanceof PendingIntentRecord)) { 4506 return null; 4507 } 4508 try { 4509 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4510 return res.key.packageName; 4511 } catch (ClassCastException e) { 4512 } 4513 return null; 4514 } 4515 4516 public int getUidForIntentSender(IIntentSender sender) { 4517 if (sender instanceof PendingIntentRecord) { 4518 try { 4519 PendingIntentRecord res = (PendingIntentRecord)sender; 4520 return res.uid; 4521 } catch (ClassCastException e) { 4522 } 4523 } 4524 return -1; 4525 } 4526 4527 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4528 if (!(pendingResult instanceof PendingIntentRecord)) { 4529 return false; 4530 } 4531 try { 4532 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4533 if (res.key.allIntents == null) { 4534 return false; 4535 } 4536 for (int i=0; i<res.key.allIntents.length; i++) { 4537 Intent intent = res.key.allIntents[i]; 4538 if (intent.getPackage() != null && intent.getComponent() != null) { 4539 return false; 4540 } 4541 } 4542 return true; 4543 } catch (ClassCastException e) { 4544 } 4545 return false; 4546 } 4547 4548 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4549 if (!(pendingResult instanceof PendingIntentRecord)) { 4550 return false; 4551 } 4552 try { 4553 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4554 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4555 return true; 4556 } 4557 return false; 4558 } catch (ClassCastException e) { 4559 } 4560 return false; 4561 } 4562 4563 public void setProcessLimit(int max) { 4564 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4565 "setProcessLimit()"); 4566 synchronized (this) { 4567 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4568 mProcessLimitOverride = max; 4569 } 4570 trimApplications(); 4571 } 4572 4573 public int getProcessLimit() { 4574 synchronized (this) { 4575 return mProcessLimitOverride; 4576 } 4577 } 4578 4579 void foregroundTokenDied(ForegroundToken token) { 4580 synchronized (ActivityManagerService.this) { 4581 synchronized (mPidsSelfLocked) { 4582 ForegroundToken cur 4583 = mForegroundProcesses.get(token.pid); 4584 if (cur != token) { 4585 return; 4586 } 4587 mForegroundProcesses.remove(token.pid); 4588 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4589 if (pr == null) { 4590 return; 4591 } 4592 pr.forcingToForeground = null; 4593 pr.foregroundServices = false; 4594 } 4595 updateOomAdjLocked(); 4596 } 4597 } 4598 4599 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4600 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4601 "setProcessForeground()"); 4602 synchronized(this) { 4603 boolean changed = false; 4604 4605 synchronized (mPidsSelfLocked) { 4606 ProcessRecord pr = mPidsSelfLocked.get(pid); 4607 if (pr == null && isForeground) { 4608 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4609 return; 4610 } 4611 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4612 if (oldToken != null) { 4613 oldToken.token.unlinkToDeath(oldToken, 0); 4614 mForegroundProcesses.remove(pid); 4615 if (pr != null) { 4616 pr.forcingToForeground = null; 4617 } 4618 changed = true; 4619 } 4620 if (isForeground && token != null) { 4621 ForegroundToken newToken = new ForegroundToken() { 4622 public void binderDied() { 4623 foregroundTokenDied(this); 4624 } 4625 }; 4626 newToken.pid = pid; 4627 newToken.token = token; 4628 try { 4629 token.linkToDeath(newToken, 0); 4630 mForegroundProcesses.put(pid, newToken); 4631 pr.forcingToForeground = token; 4632 changed = true; 4633 } catch (RemoteException e) { 4634 // If the process died while doing this, we will later 4635 // do the cleanup with the process death link. 4636 } 4637 } 4638 } 4639 4640 if (changed) { 4641 updateOomAdjLocked(); 4642 } 4643 } 4644 } 4645 4646 // ========================================================= 4647 // PERMISSIONS 4648 // ========================================================= 4649 4650 static class PermissionController extends IPermissionController.Stub { 4651 ActivityManagerService mActivityManagerService; 4652 PermissionController(ActivityManagerService activityManagerService) { 4653 mActivityManagerService = activityManagerService; 4654 } 4655 4656 public boolean checkPermission(String permission, int pid, int uid) { 4657 return mActivityManagerService.checkPermission(permission, pid, 4658 uid) == PackageManager.PERMISSION_GRANTED; 4659 } 4660 } 4661 4662 /** 4663 * This can be called with or without the global lock held. 4664 */ 4665 int checkComponentPermission(String permission, int pid, int uid, 4666 int owningUid, boolean exported) { 4667 // We might be performing an operation on behalf of an indirect binder 4668 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4669 // client identity accordingly before proceeding. 4670 Identity tlsIdentity = sCallerIdentity.get(); 4671 if (tlsIdentity != null) { 4672 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4673 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4674 uid = tlsIdentity.uid; 4675 pid = tlsIdentity.pid; 4676 } 4677 4678 if (pid == MY_PID) { 4679 return PackageManager.PERMISSION_GRANTED; 4680 } 4681 4682 return ActivityManager.checkComponentPermission(permission, uid, 4683 owningUid, exported); 4684 } 4685 4686 /** 4687 * As the only public entry point for permissions checking, this method 4688 * can enforce the semantic that requesting a check on a null global 4689 * permission is automatically denied. (Internally a null permission 4690 * string is used when calling {@link #checkComponentPermission} in cases 4691 * when only uid-based security is needed.) 4692 * 4693 * This can be called with or without the global lock held. 4694 */ 4695 public int checkPermission(String permission, int pid, int uid) { 4696 if (permission == null) { 4697 return PackageManager.PERMISSION_DENIED; 4698 } 4699 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4700 } 4701 4702 /** 4703 * Binder IPC calls go through the public entry point. 4704 * This can be called with or without the global lock held. 4705 */ 4706 int checkCallingPermission(String permission) { 4707 return checkPermission(permission, 4708 Binder.getCallingPid(), 4709 UserHandle.getAppId(Binder.getCallingUid())); 4710 } 4711 4712 /** 4713 * This can be called with or without the global lock held. 4714 */ 4715 void enforceCallingPermission(String permission, String func) { 4716 if (checkCallingPermission(permission) 4717 == PackageManager.PERMISSION_GRANTED) { 4718 return; 4719 } 4720 4721 String msg = "Permission Denial: " + func + " from pid=" 4722 + Binder.getCallingPid() 4723 + ", uid=" + Binder.getCallingUid() 4724 + " requires " + permission; 4725 Slog.w(TAG, msg); 4726 throw new SecurityException(msg); 4727 } 4728 4729 /** 4730 * Determine if UID is holding permissions required to access {@link Uri} in 4731 * the given {@link ProviderInfo}. Final permission checking is always done 4732 * in {@link ContentProvider}. 4733 */ 4734 private final boolean checkHoldingPermissionsLocked( 4735 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4736 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4737 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4738 4739 if (pi.applicationInfo.uid == uid) { 4740 return true; 4741 } else if (!pi.exported) { 4742 return false; 4743 } 4744 4745 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4746 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4747 try { 4748 // check if target holds top-level <provider> permissions 4749 if (!readMet && pi.readPermission != null 4750 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4751 readMet = true; 4752 } 4753 if (!writeMet && pi.writePermission != null 4754 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4755 writeMet = true; 4756 } 4757 4758 // track if unprotected read/write is allowed; any denied 4759 // <path-permission> below removes this ability 4760 boolean allowDefaultRead = pi.readPermission == null; 4761 boolean allowDefaultWrite = pi.writePermission == null; 4762 4763 // check if target holds any <path-permission> that match uri 4764 final PathPermission[] pps = pi.pathPermissions; 4765 if (pps != null) { 4766 final String path = uri.getPath(); 4767 int i = pps.length; 4768 while (i > 0 && (!readMet || !writeMet)) { 4769 i--; 4770 PathPermission pp = pps[i]; 4771 if (pp.match(path)) { 4772 if (!readMet) { 4773 final String pprperm = pp.getReadPermission(); 4774 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4775 + pprperm + " for " + pp.getPath() 4776 + ": match=" + pp.match(path) 4777 + " check=" + pm.checkUidPermission(pprperm, uid)); 4778 if (pprperm != null) { 4779 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4780 readMet = true; 4781 } else { 4782 allowDefaultRead = false; 4783 } 4784 } 4785 } 4786 if (!writeMet) { 4787 final String ppwperm = pp.getWritePermission(); 4788 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4789 + ppwperm + " for " + pp.getPath() 4790 + ": match=" + pp.match(path) 4791 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4792 if (ppwperm != null) { 4793 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4794 writeMet = true; 4795 } else { 4796 allowDefaultWrite = false; 4797 } 4798 } 4799 } 4800 } 4801 } 4802 } 4803 4804 // grant unprotected <provider> read/write, if not blocked by 4805 // <path-permission> above 4806 if (allowDefaultRead) readMet = true; 4807 if (allowDefaultWrite) writeMet = true; 4808 4809 } catch (RemoteException e) { 4810 return false; 4811 } 4812 4813 return readMet && writeMet; 4814 } 4815 4816 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4817 int modeFlags) { 4818 // Root gets to do everything. 4819 if (uid == 0) { 4820 return true; 4821 } 4822 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4823 if (perms == null) return false; 4824 UriPermission perm = perms.get(uri); 4825 if (perm == null) return false; 4826 return (modeFlags&perm.modeFlags) == modeFlags; 4827 } 4828 4829 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4830 enforceNotIsolatedCaller("checkUriPermission"); 4831 4832 // Another redirected-binder-call permissions check as in 4833 // {@link checkComponentPermission}. 4834 Identity tlsIdentity = sCallerIdentity.get(); 4835 if (tlsIdentity != null) { 4836 uid = tlsIdentity.uid; 4837 pid = tlsIdentity.pid; 4838 } 4839 4840 uid = UserHandle.getAppId(uid); 4841 // Our own process gets to do everything. 4842 if (pid == MY_PID) { 4843 return PackageManager.PERMISSION_GRANTED; 4844 } 4845 synchronized(this) { 4846 return checkUriPermissionLocked(uri, uid, modeFlags) 4847 ? PackageManager.PERMISSION_GRANTED 4848 : PackageManager.PERMISSION_DENIED; 4849 } 4850 } 4851 4852 /** 4853 * Check if the targetPkg can be granted permission to access uri by 4854 * the callingUid using the given modeFlags. Throws a security exception 4855 * if callingUid is not allowed to do this. Returns the uid of the target 4856 * if the URI permission grant should be performed; returns -1 if it is not 4857 * needed (for example targetPkg already has permission to access the URI). 4858 * If you already know the uid of the target, you can supply it in 4859 * lastTargetUid else set that to -1. 4860 */ 4861 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4862 Uri uri, int modeFlags, int lastTargetUid) { 4863 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4864 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4865 if (modeFlags == 0) { 4866 return -1; 4867 } 4868 4869 if (targetPkg != null) { 4870 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4871 "Checking grant " + targetPkg + " permission to " + uri); 4872 } 4873 4874 final IPackageManager pm = AppGlobals.getPackageManager(); 4875 4876 // If this is not a content: uri, we can't do anything with it. 4877 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4878 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4879 "Can't grant URI permission for non-content URI: " + uri); 4880 return -1; 4881 } 4882 4883 String name = uri.getAuthority(); 4884 ProviderInfo pi = null; 4885 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4886 UserHandle.getUserId(callingUid)); 4887 if (cpr != null) { 4888 pi = cpr.info; 4889 } else { 4890 try { 4891 pi = pm.resolveContentProvider(name, 4892 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4893 } catch (RemoteException ex) { 4894 } 4895 } 4896 if (pi == null) { 4897 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4898 return -1; 4899 } 4900 4901 int targetUid = lastTargetUid; 4902 if (targetUid < 0 && targetPkg != null) { 4903 try { 4904 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4905 if (targetUid < 0) { 4906 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4907 "Can't grant URI permission no uid for: " + targetPkg); 4908 return -1; 4909 } 4910 } catch (RemoteException ex) { 4911 return -1; 4912 } 4913 } 4914 4915 if (targetUid >= 0) { 4916 // First... does the target actually need this permission? 4917 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4918 // No need to grant the target this permission. 4919 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4920 "Target " + targetPkg + " already has full permission to " + uri); 4921 return -1; 4922 } 4923 } else { 4924 // First... there is no target package, so can anyone access it? 4925 boolean allowed = pi.exported; 4926 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4927 if (pi.readPermission != null) { 4928 allowed = false; 4929 } 4930 } 4931 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4932 if (pi.writePermission != null) { 4933 allowed = false; 4934 } 4935 } 4936 if (allowed) { 4937 return -1; 4938 } 4939 } 4940 4941 // Second... is the provider allowing granting of URI permissions? 4942 if (!pi.grantUriPermissions) { 4943 throw new SecurityException("Provider " + pi.packageName 4944 + "/" + pi.name 4945 + " does not allow granting of Uri permissions (uri " 4946 + uri + ")"); 4947 } 4948 if (pi.uriPermissionPatterns != null) { 4949 final int N = pi.uriPermissionPatterns.length; 4950 boolean allowed = false; 4951 for (int i=0; i<N; i++) { 4952 if (pi.uriPermissionPatterns[i] != null 4953 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4954 allowed = true; 4955 break; 4956 } 4957 } 4958 if (!allowed) { 4959 throw new SecurityException("Provider " + pi.packageName 4960 + "/" + pi.name 4961 + " does not allow granting of permission to path of Uri " 4962 + uri); 4963 } 4964 } 4965 4966 // Third... does the caller itself have permission to access 4967 // this uri? 4968 if (callingUid != Process.myUid()) { 4969 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4970 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4971 throw new SecurityException("Uid " + callingUid 4972 + " does not have permission to uri " + uri); 4973 } 4974 } 4975 } 4976 4977 return targetUid; 4978 } 4979 4980 public int checkGrantUriPermission(int callingUid, String targetPkg, 4981 Uri uri, int modeFlags) { 4982 enforceNotIsolatedCaller("checkGrantUriPermission"); 4983 synchronized(this) { 4984 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4985 } 4986 } 4987 4988 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4989 Uri uri, int modeFlags, UriPermissionOwner owner) { 4990 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4991 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4992 if (modeFlags == 0) { 4993 return; 4994 } 4995 4996 // So here we are: the caller has the assumed permission 4997 // to the uri, and the target doesn't. Let's now give this to 4998 // the target. 4999 5000 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5001 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5002 5003 HashMap<Uri, UriPermission> targetUris 5004 = mGrantedUriPermissions.get(targetUid); 5005 if (targetUris == null) { 5006 targetUris = new HashMap<Uri, UriPermission>(); 5007 mGrantedUriPermissions.put(targetUid, targetUris); 5008 } 5009 5010 UriPermission perm = targetUris.get(uri); 5011 if (perm == null) { 5012 perm = new UriPermission(targetUid, uri); 5013 targetUris.put(uri, perm); 5014 } 5015 5016 perm.modeFlags |= modeFlags; 5017 if (owner == null) { 5018 perm.globalModeFlags |= modeFlags; 5019 } else { 5020 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5021 perm.readOwners.add(owner); 5022 owner.addReadPermission(perm); 5023 } 5024 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5025 perm.writeOwners.add(owner); 5026 owner.addWritePermission(perm); 5027 } 5028 } 5029 } 5030 5031 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5032 int modeFlags, UriPermissionOwner owner) { 5033 if (targetPkg == null) { 5034 throw new NullPointerException("targetPkg"); 5035 } 5036 5037 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5038 if (targetUid < 0) { 5039 return; 5040 } 5041 5042 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5043 } 5044 5045 static class NeededUriGrants extends ArrayList<Uri> { 5046 final String targetPkg; 5047 final int targetUid; 5048 final int flags; 5049 5050 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5051 targetPkg = _targetPkg; 5052 targetUid = _targetUid; 5053 flags = _flags; 5054 } 5055 } 5056 5057 /** 5058 * Like checkGrantUriPermissionLocked, but takes an Intent. 5059 */ 5060 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5061 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5062 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5063 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5064 + " clip=" + (intent != null ? intent.getClipData() : null) 5065 + " from " + intent + "; flags=0x" 5066 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5067 5068 if (targetPkg == null) { 5069 throw new NullPointerException("targetPkg"); 5070 } 5071 5072 if (intent == null) { 5073 return null; 5074 } 5075 Uri data = intent.getData(); 5076 ClipData clip = intent.getClipData(); 5077 if (data == null && clip == null) { 5078 return null; 5079 } 5080 if (data != null) { 5081 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5082 mode, needed != null ? needed.targetUid : -1); 5083 if (target > 0) { 5084 if (needed == null) { 5085 needed = new NeededUriGrants(targetPkg, target, mode); 5086 } 5087 needed.add(data); 5088 } 5089 } 5090 if (clip != null) { 5091 for (int i=0; i<clip.getItemCount(); i++) { 5092 Uri uri = clip.getItemAt(i).getUri(); 5093 if (uri != null) { 5094 int target = -1; 5095 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5096 mode, needed != null ? needed.targetUid : -1); 5097 if (target > 0) { 5098 if (needed == null) { 5099 needed = new NeededUriGrants(targetPkg, target, mode); 5100 } 5101 needed.add(uri); 5102 } 5103 } else { 5104 Intent clipIntent = clip.getItemAt(i).getIntent(); 5105 if (clipIntent != null) { 5106 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5107 callingUid, targetPkg, clipIntent, mode, needed); 5108 if (newNeeded != null) { 5109 needed = newNeeded; 5110 } 5111 } 5112 } 5113 } 5114 } 5115 5116 return needed; 5117 } 5118 5119 /** 5120 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5121 */ 5122 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5123 UriPermissionOwner owner) { 5124 if (needed != null) { 5125 for (int i=0; i<needed.size(); i++) { 5126 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5127 needed.get(i), needed.flags, owner); 5128 } 5129 } 5130 } 5131 5132 void grantUriPermissionFromIntentLocked(int callingUid, 5133 String targetPkg, Intent intent, UriPermissionOwner owner) { 5134 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5135 intent, intent != null ? intent.getFlags() : 0, null); 5136 if (needed == null) { 5137 return; 5138 } 5139 5140 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5141 } 5142 5143 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5144 Uri uri, int modeFlags) { 5145 enforceNotIsolatedCaller("grantUriPermission"); 5146 synchronized(this) { 5147 final ProcessRecord r = getRecordForAppLocked(caller); 5148 if (r == null) { 5149 throw new SecurityException("Unable to find app for caller " 5150 + caller 5151 + " when granting permission to uri " + uri); 5152 } 5153 if (targetPkg == null) { 5154 throw new IllegalArgumentException("null target"); 5155 } 5156 if (uri == null) { 5157 throw new IllegalArgumentException("null uri"); 5158 } 5159 5160 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5161 null); 5162 } 5163 } 5164 5165 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5166 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5167 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5168 HashMap<Uri, UriPermission> perms 5169 = mGrantedUriPermissions.get(perm.uid); 5170 if (perms != null) { 5171 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5172 "Removing " + perm.uid + " permission to " + perm.uri); 5173 perms.remove(perm.uri); 5174 if (perms.size() == 0) { 5175 mGrantedUriPermissions.remove(perm.uid); 5176 } 5177 } 5178 } 5179 } 5180 5181 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5182 int modeFlags) { 5183 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5184 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5185 if (modeFlags == 0) { 5186 return; 5187 } 5188 5189 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5190 "Revoking all granted permissions to " + uri); 5191 5192 final IPackageManager pm = AppGlobals.getPackageManager(); 5193 5194 final String authority = uri.getAuthority(); 5195 ProviderInfo pi = null; 5196 int userId = UserHandle.getUserId(callingUid); 5197 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5198 if (cpr != null) { 5199 pi = cpr.info; 5200 } else { 5201 try { 5202 pi = pm.resolveContentProvider(authority, 5203 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5204 } catch (RemoteException ex) { 5205 } 5206 } 5207 if (pi == null) { 5208 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5209 return; 5210 } 5211 5212 // Does the caller have this permission on the URI? 5213 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5214 // Right now, if you are not the original owner of the permission, 5215 // you are not allowed to revoke it. 5216 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5217 throw new SecurityException("Uid " + callingUid 5218 + " does not have permission to uri " + uri); 5219 //} 5220 } 5221 5222 // Go through all of the permissions and remove any that match. 5223 final List<String> SEGMENTS = uri.getPathSegments(); 5224 if (SEGMENTS != null) { 5225 final int NS = SEGMENTS.size(); 5226 int N = mGrantedUriPermissions.size(); 5227 for (int i=0; i<N; i++) { 5228 HashMap<Uri, UriPermission> perms 5229 = mGrantedUriPermissions.valueAt(i); 5230 Iterator<UriPermission> it = perms.values().iterator(); 5231 toploop: 5232 while (it.hasNext()) { 5233 UriPermission perm = it.next(); 5234 Uri targetUri = perm.uri; 5235 if (!authority.equals(targetUri.getAuthority())) { 5236 continue; 5237 } 5238 List<String> targetSegments = targetUri.getPathSegments(); 5239 if (targetSegments == null) { 5240 continue; 5241 } 5242 if (targetSegments.size() < NS) { 5243 continue; 5244 } 5245 for (int j=0; j<NS; j++) { 5246 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5247 continue toploop; 5248 } 5249 } 5250 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5251 "Revoking " + perm.uid + " permission to " + perm.uri); 5252 perm.clearModes(modeFlags); 5253 if (perm.modeFlags == 0) { 5254 it.remove(); 5255 } 5256 } 5257 if (perms.size() == 0) { 5258 mGrantedUriPermissions.remove( 5259 mGrantedUriPermissions.keyAt(i)); 5260 N--; 5261 i--; 5262 } 5263 } 5264 } 5265 } 5266 5267 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5268 int modeFlags) { 5269 enforceNotIsolatedCaller("revokeUriPermission"); 5270 synchronized(this) { 5271 final ProcessRecord r = getRecordForAppLocked(caller); 5272 if (r == null) { 5273 throw new SecurityException("Unable to find app for caller " 5274 + caller 5275 + " when revoking permission to uri " + uri); 5276 } 5277 if (uri == null) { 5278 Slog.w(TAG, "revokeUriPermission: null uri"); 5279 return; 5280 } 5281 5282 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5283 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5284 if (modeFlags == 0) { 5285 return; 5286 } 5287 5288 final IPackageManager pm = AppGlobals.getPackageManager(); 5289 5290 final String authority = uri.getAuthority(); 5291 ProviderInfo pi = null; 5292 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5293 if (cpr != null) { 5294 pi = cpr.info; 5295 } else { 5296 try { 5297 pi = pm.resolveContentProvider(authority, 5298 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5299 } catch (RemoteException ex) { 5300 } 5301 } 5302 if (pi == null) { 5303 Slog.w(TAG, "No content provider found for permission revoke: " 5304 + uri.toSafeString()); 5305 return; 5306 } 5307 5308 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5309 } 5310 } 5311 5312 @Override 5313 public IBinder newUriPermissionOwner(String name) { 5314 enforceNotIsolatedCaller("newUriPermissionOwner"); 5315 synchronized(this) { 5316 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5317 return owner.getExternalTokenLocked(); 5318 } 5319 } 5320 5321 @Override 5322 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5323 Uri uri, int modeFlags) { 5324 synchronized(this) { 5325 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5326 if (owner == null) { 5327 throw new IllegalArgumentException("Unknown owner: " + token); 5328 } 5329 if (fromUid != Binder.getCallingUid()) { 5330 if (Binder.getCallingUid() != Process.myUid()) { 5331 // Only system code can grant URI permissions on behalf 5332 // of other users. 5333 throw new SecurityException("nice try"); 5334 } 5335 } 5336 if (targetPkg == null) { 5337 throw new IllegalArgumentException("null target"); 5338 } 5339 if (uri == null) { 5340 throw new IllegalArgumentException("null uri"); 5341 } 5342 5343 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5344 } 5345 } 5346 5347 @Override 5348 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5349 synchronized(this) { 5350 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5351 if (owner == null) { 5352 throw new IllegalArgumentException("Unknown owner: " + token); 5353 } 5354 5355 if (uri == null) { 5356 owner.removeUriPermissionsLocked(mode); 5357 } else { 5358 owner.removeUriPermissionLocked(uri, mode); 5359 } 5360 } 5361 } 5362 5363 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5364 synchronized (this) { 5365 ProcessRecord app = 5366 who != null ? getRecordForAppLocked(who) : null; 5367 if (app == null) return; 5368 5369 Message msg = Message.obtain(); 5370 msg.what = WAIT_FOR_DEBUGGER_MSG; 5371 msg.obj = app; 5372 msg.arg1 = waiting ? 1 : 0; 5373 mHandler.sendMessage(msg); 5374 } 5375 } 5376 5377 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5378 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5379 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5380 outInfo.availMem = Process.getFreeMemory(); 5381 outInfo.totalMem = Process.getTotalMemory(); 5382 outInfo.threshold = homeAppMem; 5383 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5384 outInfo.hiddenAppThreshold = hiddenAppMem; 5385 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5386 ProcessList.SERVICE_ADJ); 5387 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5388 ProcessList.VISIBLE_APP_ADJ); 5389 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5390 ProcessList.FOREGROUND_APP_ADJ); 5391 } 5392 5393 // ========================================================= 5394 // TASK MANAGEMENT 5395 // ========================================================= 5396 5397 public List getTasks(int maxNum, int flags, 5398 IThumbnailReceiver receiver) { 5399 ArrayList list = new ArrayList(); 5400 5401 PendingThumbnailsRecord pending = null; 5402 IApplicationThread topThumbnail = null; 5403 ActivityRecord topRecord = null; 5404 5405 synchronized(this) { 5406 if (localLOGV) Slog.v( 5407 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5408 + ", receiver=" + receiver); 5409 5410 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5411 != PackageManager.PERMISSION_GRANTED) { 5412 if (receiver != null) { 5413 // If the caller wants to wait for pending thumbnails, 5414 // it ain't gonna get them. 5415 try { 5416 receiver.finished(); 5417 } catch (RemoteException ex) { 5418 } 5419 } 5420 String msg = "Permission Denial: getTasks() from pid=" 5421 + Binder.getCallingPid() 5422 + ", uid=" + Binder.getCallingUid() 5423 + " requires " + android.Manifest.permission.GET_TASKS; 5424 Slog.w(TAG, msg); 5425 throw new SecurityException(msg); 5426 } 5427 5428 int pos = mMainStack.mHistory.size()-1; 5429 ActivityRecord next = 5430 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5431 ActivityRecord top = null; 5432 TaskRecord curTask = null; 5433 int numActivities = 0; 5434 int numRunning = 0; 5435 while (pos >= 0 && maxNum > 0) { 5436 final ActivityRecord r = next; 5437 pos--; 5438 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5439 5440 // Initialize state for next task if needed. 5441 if (top == null || 5442 (top.state == ActivityState.INITIALIZING 5443 && top.task == r.task)) { 5444 top = r; 5445 curTask = r.task; 5446 numActivities = numRunning = 0; 5447 } 5448 5449 // Add 'r' into the current task. 5450 numActivities++; 5451 if (r.app != null && r.app.thread != null) { 5452 numRunning++; 5453 } 5454 5455 if (localLOGV) Slog.v( 5456 TAG, r.intent.getComponent().flattenToShortString() 5457 + ": task=" + r.task); 5458 5459 // If the next one is a different task, generate a new 5460 // TaskInfo entry for what we have. 5461 if (next == null || next.task != curTask) { 5462 ActivityManager.RunningTaskInfo ci 5463 = new ActivityManager.RunningTaskInfo(); 5464 ci.id = curTask.taskId; 5465 ci.baseActivity = r.intent.getComponent(); 5466 ci.topActivity = top.intent.getComponent(); 5467 if (top.thumbHolder != null) { 5468 ci.description = top.thumbHolder.lastDescription; 5469 } 5470 ci.numActivities = numActivities; 5471 ci.numRunning = numRunning; 5472 //System.out.println( 5473 // "#" + maxNum + ": " + " descr=" + ci.description); 5474 if (ci.thumbnail == null && receiver != null) { 5475 if (localLOGV) Slog.v( 5476 TAG, "State=" + top.state + "Idle=" + top.idle 5477 + " app=" + top.app 5478 + " thr=" + (top.app != null ? top.app.thread : null)); 5479 if (top.state == ActivityState.RESUMED 5480 || top.state == ActivityState.PAUSING) { 5481 if (top.idle && top.app != null 5482 && top.app.thread != null) { 5483 topRecord = top; 5484 topThumbnail = top.app.thread; 5485 } else { 5486 top.thumbnailNeeded = true; 5487 } 5488 } 5489 if (pending == null) { 5490 pending = new PendingThumbnailsRecord(receiver); 5491 } 5492 pending.pendingRecords.add(top); 5493 } 5494 list.add(ci); 5495 maxNum--; 5496 top = null; 5497 } 5498 } 5499 5500 if (pending != null) { 5501 mPendingThumbnails.add(pending); 5502 } 5503 } 5504 5505 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5506 5507 if (topThumbnail != null) { 5508 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5509 try { 5510 topThumbnail.requestThumbnail(topRecord.appToken); 5511 } catch (Exception e) { 5512 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5513 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5514 } 5515 } 5516 5517 if (pending == null && receiver != null) { 5518 // In this case all thumbnails were available and the client 5519 // is being asked to be told when the remaining ones come in... 5520 // which is unusually, since the top-most currently running 5521 // activity should never have a canned thumbnail! Oh well. 5522 try { 5523 receiver.finished(); 5524 } catch (RemoteException ex) { 5525 } 5526 } 5527 5528 return list; 5529 } 5530 5531 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5532 int flags, int userId) { 5533 final int callingUid = Binder.getCallingUid(); 5534 if (userId != UserHandle.getCallingUserId()) { 5535 // Check if the caller is holding permissions for cross-user requests. 5536 if (checkComponentPermission( 5537 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5538 Binder.getCallingPid(), callingUid, -1, true) 5539 != PackageManager.PERMISSION_GRANTED) { 5540 String msg = "Permission Denial: " 5541 + "Request to get recent tasks for user " + userId 5542 + " but is calling from user " + UserHandle.getUserId(callingUid) 5543 + "; this requires " 5544 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5545 Slog.w(TAG, msg); 5546 throw new SecurityException(msg); 5547 } else { 5548 if (userId == UserHandle.USER_CURRENT) { 5549 userId = mCurrentUserId; 5550 } 5551 } 5552 } 5553 5554 synchronized (this) { 5555 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5556 "getRecentTasks()"); 5557 final boolean detailed = checkCallingPermission( 5558 android.Manifest.permission.GET_DETAILED_TASKS) 5559 == PackageManager.PERMISSION_GRANTED; 5560 5561 IPackageManager pm = AppGlobals.getPackageManager(); 5562 5563 final int N = mRecentTasks.size(); 5564 ArrayList<ActivityManager.RecentTaskInfo> res 5565 = new ArrayList<ActivityManager.RecentTaskInfo>( 5566 maxNum < N ? maxNum : N); 5567 for (int i=0; i<N && maxNum > 0; i++) { 5568 TaskRecord tr = mRecentTasks.get(i); 5569 // Only add calling user's recent tasks 5570 if (tr.userId != userId) continue; 5571 // Return the entry if desired by the caller. We always return 5572 // the first entry, because callers always expect this to be the 5573 // foreground app. We may filter others if the caller has 5574 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5575 // we should exclude the entry. 5576 5577 if (i == 0 5578 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5579 || (tr.intent == null) 5580 || ((tr.intent.getFlags() 5581 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5582 ActivityManager.RecentTaskInfo rti 5583 = new ActivityManager.RecentTaskInfo(); 5584 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5585 rti.persistentId = tr.taskId; 5586 rti.baseIntent = new Intent( 5587 tr.intent != null ? tr.intent : tr.affinityIntent); 5588 if (!detailed) { 5589 rti.baseIntent.replaceExtras((Bundle)null); 5590 } 5591 rti.origActivity = tr.origActivity; 5592 rti.description = tr.lastDescription; 5593 5594 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5595 // Check whether this activity is currently available. 5596 try { 5597 if (rti.origActivity != null) { 5598 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5599 == null) { 5600 continue; 5601 } 5602 } else if (rti.baseIntent != null) { 5603 if (pm.queryIntentActivities(rti.baseIntent, 5604 null, 0, userId) == null) { 5605 continue; 5606 } 5607 } 5608 } catch (RemoteException e) { 5609 // Will never happen. 5610 } 5611 } 5612 5613 res.add(rti); 5614 maxNum--; 5615 } 5616 } 5617 return res; 5618 } 5619 } 5620 5621 private TaskRecord taskForIdLocked(int id) { 5622 final int N = mRecentTasks.size(); 5623 for (int i=0; i<N; i++) { 5624 TaskRecord tr = mRecentTasks.get(i); 5625 if (tr.taskId == id) { 5626 return tr; 5627 } 5628 } 5629 return null; 5630 } 5631 5632 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5633 synchronized (this) { 5634 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5635 "getTaskThumbnails()"); 5636 TaskRecord tr = taskForIdLocked(id); 5637 if (tr != null) { 5638 return mMainStack.getTaskThumbnailsLocked(tr); 5639 } 5640 } 5641 return null; 5642 } 5643 5644 public boolean removeSubTask(int taskId, int subTaskIndex) { 5645 synchronized (this) { 5646 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5647 "removeSubTask()"); 5648 long ident = Binder.clearCallingIdentity(); 5649 try { 5650 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5651 true) != null; 5652 } finally { 5653 Binder.restoreCallingIdentity(ident); 5654 } 5655 } 5656 } 5657 5658 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5659 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5660 Intent baseIntent = new Intent( 5661 tr.intent != null ? tr.intent : tr.affinityIntent); 5662 ComponentName component = baseIntent.getComponent(); 5663 if (component == null) { 5664 Slog.w(TAG, "Now component for base intent of task: " + tr); 5665 return; 5666 } 5667 5668 // Find any running services associated with this app. 5669 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5670 5671 if (killProcesses) { 5672 // Find any running processes associated with this app. 5673 final String pkg = component.getPackageName(); 5674 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5675 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5676 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5677 for (int i=0; i<uids.size(); i++) { 5678 ProcessRecord proc = uids.valueAt(i); 5679 if (proc.userId != tr.userId) { 5680 continue; 5681 } 5682 if (!proc.pkgList.contains(pkg)) { 5683 continue; 5684 } 5685 procs.add(proc); 5686 } 5687 } 5688 5689 // Kill the running processes. 5690 for (int i=0; i<procs.size(); i++) { 5691 ProcessRecord pr = procs.get(i); 5692 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5693 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5694 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5695 pr.processName, pr.setAdj, "remove task"); 5696 pr.killedBackground = true; 5697 Process.killProcessQuiet(pr.pid); 5698 } else { 5699 pr.waitingToKill = "remove task"; 5700 } 5701 } 5702 } 5703 } 5704 5705 public boolean removeTask(int taskId, int flags) { 5706 synchronized (this) { 5707 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5708 "removeTask()"); 5709 long ident = Binder.clearCallingIdentity(); 5710 try { 5711 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5712 false); 5713 if (r != null) { 5714 mRecentTasks.remove(r.task); 5715 cleanUpRemovedTaskLocked(r.task, flags); 5716 return true; 5717 } else { 5718 TaskRecord tr = null; 5719 int i=0; 5720 while (i < mRecentTasks.size()) { 5721 TaskRecord t = mRecentTasks.get(i); 5722 if (t.taskId == taskId) { 5723 tr = t; 5724 break; 5725 } 5726 i++; 5727 } 5728 if (tr != null) { 5729 if (tr.numActivities <= 0) { 5730 // Caller is just removing a recent task that is 5731 // not actively running. That is easy! 5732 mRecentTasks.remove(i); 5733 cleanUpRemovedTaskLocked(tr, flags); 5734 return true; 5735 } else { 5736 Slog.w(TAG, "removeTask: task " + taskId 5737 + " does not have activities to remove, " 5738 + " but numActivities=" + tr.numActivities 5739 + ": " + tr); 5740 } 5741 } 5742 } 5743 } finally { 5744 Binder.restoreCallingIdentity(ident); 5745 } 5746 } 5747 return false; 5748 } 5749 5750 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5751 int j; 5752 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5753 TaskRecord jt = startTask; 5754 5755 // First look backwards 5756 for (j=startIndex-1; j>=0; j--) { 5757 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5758 if (r.task != jt) { 5759 jt = r.task; 5760 if (affinity.equals(jt.affinity)) { 5761 return j; 5762 } 5763 } 5764 } 5765 5766 // Now look forwards 5767 final int N = mMainStack.mHistory.size(); 5768 jt = startTask; 5769 for (j=startIndex+1; j<N; j++) { 5770 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5771 if (r.task != jt) { 5772 if (affinity.equals(jt.affinity)) { 5773 return j; 5774 } 5775 jt = r.task; 5776 } 5777 } 5778 5779 // Might it be at the top? 5780 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5781 return N-1; 5782 } 5783 5784 return -1; 5785 } 5786 5787 /** 5788 * TODO: Add mController hook 5789 */ 5790 public void moveTaskToFront(int task, int flags, Bundle options) { 5791 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5792 "moveTaskToFront()"); 5793 5794 synchronized(this) { 5795 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5796 Binder.getCallingUid(), "Task to front")) { 5797 ActivityOptions.abort(options); 5798 return; 5799 } 5800 final long origId = Binder.clearCallingIdentity(); 5801 try { 5802 TaskRecord tr = taskForIdLocked(task); 5803 if (tr != null) { 5804 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5805 mMainStack.mUserLeaving = true; 5806 } 5807 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5808 // Caller wants the home activity moved with it. To accomplish this, 5809 // we'll just move the home task to the top first. 5810 mMainStack.moveHomeToFrontLocked(); 5811 } 5812 mMainStack.moveTaskToFrontLocked(tr, null, options); 5813 return; 5814 } 5815 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5816 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5817 if (hr.task.taskId == task) { 5818 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5819 mMainStack.mUserLeaving = true; 5820 } 5821 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5822 // Caller wants the home activity moved with it. To accomplish this, 5823 // we'll just move the home task to the top first. 5824 mMainStack.moveHomeToFrontLocked(); 5825 } 5826 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5827 return; 5828 } 5829 } 5830 } finally { 5831 Binder.restoreCallingIdentity(origId); 5832 } 5833 ActivityOptions.abort(options); 5834 } 5835 } 5836 5837 public void moveTaskToBack(int task) { 5838 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5839 "moveTaskToBack()"); 5840 5841 synchronized(this) { 5842 if (mMainStack.mResumedActivity != null 5843 && mMainStack.mResumedActivity.task.taskId == task) { 5844 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5845 Binder.getCallingUid(), "Task to back")) { 5846 return; 5847 } 5848 } 5849 final long origId = Binder.clearCallingIdentity(); 5850 mMainStack.moveTaskToBackLocked(task, null); 5851 Binder.restoreCallingIdentity(origId); 5852 } 5853 } 5854 5855 /** 5856 * Moves an activity, and all of the other activities within the same task, to the bottom 5857 * of the history stack. The activity's order within the task is unchanged. 5858 * 5859 * @param token A reference to the activity we wish to move 5860 * @param nonRoot If false then this only works if the activity is the root 5861 * of a task; if true it will work for any activity in a task. 5862 * @return Returns true if the move completed, false if not. 5863 */ 5864 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5865 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5866 synchronized(this) { 5867 final long origId = Binder.clearCallingIdentity(); 5868 int taskId = getTaskForActivityLocked(token, !nonRoot); 5869 if (taskId >= 0) { 5870 return mMainStack.moveTaskToBackLocked(taskId, null); 5871 } 5872 Binder.restoreCallingIdentity(origId); 5873 } 5874 return false; 5875 } 5876 5877 public void moveTaskBackwards(int task) { 5878 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5879 "moveTaskBackwards()"); 5880 5881 synchronized(this) { 5882 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5883 Binder.getCallingUid(), "Task backwards")) { 5884 return; 5885 } 5886 final long origId = Binder.clearCallingIdentity(); 5887 moveTaskBackwardsLocked(task); 5888 Binder.restoreCallingIdentity(origId); 5889 } 5890 } 5891 5892 private final void moveTaskBackwardsLocked(int task) { 5893 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5894 } 5895 5896 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5897 synchronized(this) { 5898 return getTaskForActivityLocked(token, onlyRoot); 5899 } 5900 } 5901 5902 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5903 final int N = mMainStack.mHistory.size(); 5904 TaskRecord lastTask = null; 5905 for (int i=0; i<N; i++) { 5906 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5907 if (r.appToken == token) { 5908 if (!onlyRoot || lastTask != r.task) { 5909 return r.task.taskId; 5910 } 5911 return -1; 5912 } 5913 lastTask = r.task; 5914 } 5915 5916 return -1; 5917 } 5918 5919 // ========================================================= 5920 // THUMBNAILS 5921 // ========================================================= 5922 5923 public void reportThumbnail(IBinder token, 5924 Bitmap thumbnail, CharSequence description) { 5925 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5926 final long origId = Binder.clearCallingIdentity(); 5927 sendPendingThumbnail(null, token, thumbnail, description, true); 5928 Binder.restoreCallingIdentity(origId); 5929 } 5930 5931 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5932 Bitmap thumbnail, CharSequence description, boolean always) { 5933 TaskRecord task = null; 5934 ArrayList receivers = null; 5935 5936 //System.out.println("Send pending thumbnail: " + r); 5937 5938 synchronized(this) { 5939 if (r == null) { 5940 r = mMainStack.isInStackLocked(token); 5941 if (r == null) { 5942 return; 5943 } 5944 } 5945 if (thumbnail == null && r.thumbHolder != null) { 5946 thumbnail = r.thumbHolder.lastThumbnail; 5947 description = r.thumbHolder.lastDescription; 5948 } 5949 if (thumbnail == null && !always) { 5950 // If there is no thumbnail, and this entry is not actually 5951 // going away, then abort for now and pick up the next 5952 // thumbnail we get. 5953 return; 5954 } 5955 task = r.task; 5956 5957 int N = mPendingThumbnails.size(); 5958 int i=0; 5959 while (i<N) { 5960 PendingThumbnailsRecord pr = 5961 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5962 //System.out.println("Looking in " + pr.pendingRecords); 5963 if (pr.pendingRecords.remove(r)) { 5964 if (receivers == null) { 5965 receivers = new ArrayList(); 5966 } 5967 receivers.add(pr); 5968 if (pr.pendingRecords.size() == 0) { 5969 pr.finished = true; 5970 mPendingThumbnails.remove(i); 5971 N--; 5972 continue; 5973 } 5974 } 5975 i++; 5976 } 5977 } 5978 5979 if (receivers != null) { 5980 final int N = receivers.size(); 5981 for (int i=0; i<N; i++) { 5982 try { 5983 PendingThumbnailsRecord pr = 5984 (PendingThumbnailsRecord)receivers.get(i); 5985 pr.receiver.newThumbnail( 5986 task != null ? task.taskId : -1, thumbnail, description); 5987 if (pr.finished) { 5988 pr.receiver.finished(); 5989 } 5990 } catch (Exception e) { 5991 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5992 } 5993 } 5994 } 5995 } 5996 5997 // ========================================================= 5998 // CONTENT PROVIDERS 5999 // ========================================================= 6000 6001 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6002 List<ProviderInfo> providers = null; 6003 try { 6004 providers = AppGlobals.getPackageManager(). 6005 queryContentProviders(app.processName, app.uid, 6006 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6007 } catch (RemoteException ex) { 6008 } 6009 if (DEBUG_MU) 6010 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6011 int userId = app.userId; 6012 if (providers != null) { 6013 int N = providers.size(); 6014 for (int i=0; i<N; i++) { 6015 ProviderInfo cpi = 6016 (ProviderInfo)providers.get(i); 6017 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6018 cpi.name, cpi.flags); 6019 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6020 // This is a singleton provider, but a user besides the 6021 // default user is asking to initialize a process it runs 6022 // in... well, no, it doesn't actually run in this process, 6023 // it runs in the process of the default user. Get rid of it. 6024 providers.remove(i); 6025 N--; 6026 continue; 6027 } 6028 6029 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6030 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6031 if (cpr == null) { 6032 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6033 mProviderMap.putProviderByClass(comp, cpr); 6034 } 6035 if (DEBUG_MU) 6036 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6037 app.pubProviders.put(cpi.name, cpr); 6038 app.addPackage(cpi.applicationInfo.packageName); 6039 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6040 } 6041 } 6042 return providers; 6043 } 6044 6045 /** 6046 * Check if {@link ProcessRecord} has a possible chance at accessing the 6047 * given {@link ProviderInfo}. Final permission checking is always done 6048 * in {@link ContentProvider}. 6049 */ 6050 private final String checkContentProviderPermissionLocked( 6051 ProviderInfo cpi, ProcessRecord r) { 6052 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6053 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6054 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6055 cpi.applicationInfo.uid, cpi.exported) 6056 == PackageManager.PERMISSION_GRANTED) { 6057 return null; 6058 } 6059 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6060 cpi.applicationInfo.uid, cpi.exported) 6061 == PackageManager.PERMISSION_GRANTED) { 6062 return null; 6063 } 6064 6065 PathPermission[] pps = cpi.pathPermissions; 6066 if (pps != null) { 6067 int i = pps.length; 6068 while (i > 0) { 6069 i--; 6070 PathPermission pp = pps[i]; 6071 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6072 cpi.applicationInfo.uid, cpi.exported) 6073 == PackageManager.PERMISSION_GRANTED) { 6074 return null; 6075 } 6076 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6077 cpi.applicationInfo.uid, cpi.exported) 6078 == PackageManager.PERMISSION_GRANTED) { 6079 return null; 6080 } 6081 } 6082 } 6083 6084 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6085 if (perms != null) { 6086 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6087 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6088 return null; 6089 } 6090 } 6091 } 6092 6093 String msg; 6094 if (!cpi.exported) { 6095 msg = "Permission Denial: opening provider " + cpi.name 6096 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6097 + ", uid=" + callingUid + ") that is not exported from uid " 6098 + cpi.applicationInfo.uid; 6099 } else { 6100 msg = "Permission Denial: opening provider " + cpi.name 6101 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6102 + ", uid=" + callingUid + ") requires " 6103 + cpi.readPermission + " or " + cpi.writePermission; 6104 } 6105 Slog.w(TAG, msg); 6106 return msg; 6107 } 6108 6109 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6110 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6111 if (r != null) { 6112 for (int i=0; i<r.conProviders.size(); i++) { 6113 ContentProviderConnection conn = r.conProviders.get(i); 6114 if (conn.provider == cpr) { 6115 if (DEBUG_PROVIDER) Slog.v(TAG, 6116 "Adding provider requested by " 6117 + r.processName + " from process " 6118 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6119 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6120 if (stable) { 6121 conn.stableCount++; 6122 conn.numStableIncs++; 6123 } else { 6124 conn.unstableCount++; 6125 conn.numUnstableIncs++; 6126 } 6127 return conn; 6128 } 6129 } 6130 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6131 if (stable) { 6132 conn.stableCount = 1; 6133 conn.numStableIncs = 1; 6134 } else { 6135 conn.unstableCount = 1; 6136 conn.numUnstableIncs = 1; 6137 } 6138 cpr.connections.add(conn); 6139 r.conProviders.add(conn); 6140 return conn; 6141 } 6142 cpr.addExternalProcessHandleLocked(externalProcessToken); 6143 return null; 6144 } 6145 6146 boolean decProviderCountLocked(ContentProviderConnection conn, 6147 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6148 if (conn != null) { 6149 cpr = conn.provider; 6150 if (DEBUG_PROVIDER) Slog.v(TAG, 6151 "Removing provider requested by " 6152 + conn.client.processName + " from process " 6153 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6154 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6155 if (stable) { 6156 conn.stableCount--; 6157 } else { 6158 conn.unstableCount--; 6159 } 6160 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6161 cpr.connections.remove(conn); 6162 conn.client.conProviders.remove(conn); 6163 return true; 6164 } 6165 return false; 6166 } 6167 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6168 return false; 6169 } 6170 6171 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6172 String name, IBinder token, boolean stable) { 6173 ContentProviderRecord cpr; 6174 ContentProviderConnection conn = null; 6175 ProviderInfo cpi = null; 6176 6177 synchronized(this) { 6178 ProcessRecord r = null; 6179 if (caller != null) { 6180 r = getRecordForAppLocked(caller); 6181 if (r == null) { 6182 throw new SecurityException( 6183 "Unable to find app for caller " + caller 6184 + " (pid=" + Binder.getCallingPid() 6185 + ") when getting content provider " + name); 6186 } 6187 } 6188 6189 // First check if this content provider has been published... 6190 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6191 cpr = mProviderMap.getProviderByName(name, userId); 6192 boolean providerRunning = cpr != null; 6193 if (providerRunning) { 6194 cpi = cpr.info; 6195 String msg; 6196 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6197 throw new SecurityException(msg); 6198 } 6199 6200 if (r != null && cpr.canRunHere(r)) { 6201 // This provider has been published or is in the process 6202 // of being published... but it is also allowed to run 6203 // in the caller's process, so don't make a connection 6204 // and just let the caller instantiate its own instance. 6205 ContentProviderHolder holder = cpr.newHolder(null); 6206 // don't give caller the provider object, it needs 6207 // to make its own. 6208 holder.provider = null; 6209 return holder; 6210 } 6211 6212 final long origId = Binder.clearCallingIdentity(); 6213 6214 // In this case the provider instance already exists, so we can 6215 // return it right away. 6216 conn = incProviderCountLocked(r, cpr, token, stable); 6217 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6218 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6219 // If this is a perceptible app accessing the provider, 6220 // make sure to count it as being accessed and thus 6221 // back up on the LRU list. This is good because 6222 // content providers are often expensive to start. 6223 updateLruProcessLocked(cpr.proc, false, true); 6224 } 6225 } 6226 6227 if (cpr.proc != null) { 6228 if (false) { 6229 if (cpr.name.flattenToShortString().equals( 6230 "com.android.providers.calendar/.CalendarProvider2")) { 6231 Slog.v(TAG, "****************** KILLING " 6232 + cpr.name.flattenToShortString()); 6233 Process.killProcess(cpr.proc.pid); 6234 } 6235 } 6236 boolean success = updateOomAdjLocked(cpr.proc); 6237 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6238 // NOTE: there is still a race here where a signal could be 6239 // pending on the process even though we managed to update its 6240 // adj level. Not sure what to do about this, but at least 6241 // the race is now smaller. 6242 if (!success) { 6243 // Uh oh... it looks like the provider's process 6244 // has been killed on us. We need to wait for a new 6245 // process to be started, and make sure its death 6246 // doesn't kill our process. 6247 Slog.i(TAG, 6248 "Existing provider " + cpr.name.flattenToShortString() 6249 + " is crashing; detaching " + r); 6250 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6251 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6252 if (!lastRef) { 6253 // This wasn't the last ref our process had on 6254 // the provider... we have now been killed, bail. 6255 return null; 6256 } 6257 providerRunning = false; 6258 conn = null; 6259 } 6260 } 6261 6262 Binder.restoreCallingIdentity(origId); 6263 } 6264 6265 boolean singleton; 6266 if (!providerRunning) { 6267 try { 6268 cpi = AppGlobals.getPackageManager(). 6269 resolveContentProvider(name, 6270 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6271 } catch (RemoteException ex) { 6272 } 6273 if (cpi == null) { 6274 return null; 6275 } 6276 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6277 cpi.name, cpi.flags); 6278 if (singleton) { 6279 userId = 0; 6280 } 6281 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6282 6283 String msg; 6284 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6285 throw new SecurityException(msg); 6286 } 6287 6288 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6289 && !cpi.processName.equals("system")) { 6290 // If this content provider does not run in the system 6291 // process, and the system is not yet ready to run other 6292 // processes, then fail fast instead of hanging. 6293 throw new IllegalArgumentException( 6294 "Attempt to launch content provider before system ready"); 6295 } 6296 6297 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6298 cpr = mProviderMap.getProviderByClass(comp, userId); 6299 final boolean firstClass = cpr == null; 6300 if (firstClass) { 6301 try { 6302 ApplicationInfo ai = 6303 AppGlobals.getPackageManager(). 6304 getApplicationInfo( 6305 cpi.applicationInfo.packageName, 6306 STOCK_PM_FLAGS, userId); 6307 if (ai == null) { 6308 Slog.w(TAG, "No package info for content provider " 6309 + cpi.name); 6310 return null; 6311 } 6312 ai = getAppInfoForUser(ai, userId); 6313 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6314 } catch (RemoteException ex) { 6315 // pm is in same process, this will never happen. 6316 } 6317 } 6318 6319 if (r != null && cpr.canRunHere(r)) { 6320 // If this is a multiprocess provider, then just return its 6321 // info and allow the caller to instantiate it. Only do 6322 // this if the provider is the same user as the caller's 6323 // process, or can run as root (so can be in any process). 6324 return cpr.newHolder(null); 6325 } 6326 6327 if (DEBUG_PROVIDER) { 6328 RuntimeException e = new RuntimeException("here"); 6329 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6330 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6331 } 6332 6333 // This is single process, and our app is now connecting to it. 6334 // See if we are already in the process of launching this 6335 // provider. 6336 final int N = mLaunchingProviders.size(); 6337 int i; 6338 for (i=0; i<N; i++) { 6339 if (mLaunchingProviders.get(i) == cpr) { 6340 break; 6341 } 6342 } 6343 6344 // If the provider is not already being launched, then get it 6345 // started. 6346 if (i >= N) { 6347 final long origId = Binder.clearCallingIdentity(); 6348 6349 try { 6350 // Content provider is now in use, its package can't be stopped. 6351 try { 6352 AppGlobals.getPackageManager().setPackageStoppedState( 6353 cpr.appInfo.packageName, false, userId); 6354 } catch (RemoteException e) { 6355 } catch (IllegalArgumentException e) { 6356 Slog.w(TAG, "Failed trying to unstop package " 6357 + cpr.appInfo.packageName + ": " + e); 6358 } 6359 6360 ProcessRecord proc = startProcessLocked(cpi.processName, 6361 cpr.appInfo, false, 0, "content provider", 6362 new ComponentName(cpi.applicationInfo.packageName, 6363 cpi.name), false, false); 6364 if (proc == null) { 6365 Slog.w(TAG, "Unable to launch app " 6366 + cpi.applicationInfo.packageName + "/" 6367 + cpi.applicationInfo.uid + " for provider " 6368 + name + ": process is bad"); 6369 return null; 6370 } 6371 cpr.launchingApp = proc; 6372 mLaunchingProviders.add(cpr); 6373 } finally { 6374 Binder.restoreCallingIdentity(origId); 6375 } 6376 } 6377 6378 // Make sure the provider is published (the same provider class 6379 // may be published under multiple names). 6380 if (firstClass) { 6381 mProviderMap.putProviderByClass(comp, cpr); 6382 } 6383 6384 mProviderMap.putProviderByName(name, cpr); 6385 conn = incProviderCountLocked(r, cpr, token, stable); 6386 if (conn != null) { 6387 conn.waiting = true; 6388 } 6389 } 6390 } 6391 6392 // Wait for the provider to be published... 6393 synchronized (cpr) { 6394 while (cpr.provider == null) { 6395 if (cpr.launchingApp == null) { 6396 Slog.w(TAG, "Unable to launch app " 6397 + cpi.applicationInfo.packageName + "/" 6398 + cpi.applicationInfo.uid + " for provider " 6399 + name + ": launching app became null"); 6400 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6401 cpi.applicationInfo.packageName, 6402 cpi.applicationInfo.uid, name); 6403 return null; 6404 } 6405 try { 6406 if (DEBUG_MU) { 6407 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6408 + cpr.launchingApp); 6409 } 6410 if (conn != null) { 6411 conn.waiting = true; 6412 } 6413 cpr.wait(); 6414 } catch (InterruptedException ex) { 6415 } finally { 6416 if (conn != null) { 6417 conn.waiting = false; 6418 } 6419 } 6420 } 6421 } 6422 return cpr != null ? cpr.newHolder(conn) : null; 6423 } 6424 6425 public final ContentProviderHolder getContentProvider( 6426 IApplicationThread caller, String name, boolean stable) { 6427 enforceNotIsolatedCaller("getContentProvider"); 6428 if (caller == null) { 6429 String msg = "null IApplicationThread when getting content provider " 6430 + name; 6431 Slog.w(TAG, msg); 6432 throw new SecurityException(msg); 6433 } 6434 6435 return getContentProviderImpl(caller, name, null, stable); 6436 } 6437 6438 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6439 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6440 "Do not have permission in call getContentProviderExternal()"); 6441 return getContentProviderExternalUnchecked(name, token); 6442 } 6443 6444 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6445 return getContentProviderImpl(null, name, token, true); 6446 } 6447 6448 /** 6449 * Drop a content provider from a ProcessRecord's bookkeeping 6450 * @param cpr 6451 */ 6452 public void removeContentProvider(IBinder connection, boolean stable) { 6453 enforceNotIsolatedCaller("removeContentProvider"); 6454 synchronized (this) { 6455 ContentProviderConnection conn; 6456 try { 6457 conn = (ContentProviderConnection)connection; 6458 } catch (ClassCastException e) { 6459 String msg ="removeContentProvider: " + connection 6460 + " not a ContentProviderConnection"; 6461 Slog.w(TAG, msg); 6462 throw new IllegalArgumentException(msg); 6463 } 6464 if (conn == null) { 6465 throw new NullPointerException("connection is null"); 6466 } 6467 if (decProviderCountLocked(conn, null, null, stable)) { 6468 updateOomAdjLocked(); 6469 } 6470 } 6471 } 6472 6473 public void removeContentProviderExternal(String name, IBinder token) { 6474 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6475 "Do not have permission in call removeContentProviderExternal()"); 6476 removeContentProviderExternalUnchecked(name, token); 6477 } 6478 6479 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6480 synchronized (this) { 6481 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6482 Binder.getOrigCallingUser()); 6483 if(cpr == null) { 6484 //remove from mProvidersByClass 6485 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6486 return; 6487 } 6488 6489 //update content provider record entry info 6490 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6491 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6492 Binder.getOrigCallingUser()); 6493 if (localCpr.hasExternalProcessHandles()) { 6494 if (localCpr.removeExternalProcessHandleLocked(token)) { 6495 updateOomAdjLocked(); 6496 } else { 6497 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6498 + " with no external reference for token: " 6499 + token + "."); 6500 } 6501 } else { 6502 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6503 + " with no external references."); 6504 } 6505 } 6506 } 6507 6508 public final void publishContentProviders(IApplicationThread caller, 6509 List<ContentProviderHolder> providers) { 6510 if (providers == null) { 6511 return; 6512 } 6513 6514 enforceNotIsolatedCaller("publishContentProviders"); 6515 synchronized (this) { 6516 final ProcessRecord r = getRecordForAppLocked(caller); 6517 if (DEBUG_MU) 6518 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6519 if (r == null) { 6520 throw new SecurityException( 6521 "Unable to find app for caller " + caller 6522 + " (pid=" + Binder.getCallingPid() 6523 + ") when publishing content providers"); 6524 } 6525 6526 final long origId = Binder.clearCallingIdentity(); 6527 6528 final int N = providers.size(); 6529 for (int i=0; i<N; i++) { 6530 ContentProviderHolder src = providers.get(i); 6531 if (src == null || src.info == null || src.provider == null) { 6532 continue; 6533 } 6534 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6535 if (DEBUG_MU) 6536 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6537 if (dst != null) { 6538 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6539 mProviderMap.putProviderByClass(comp, dst); 6540 String names[] = dst.info.authority.split(";"); 6541 for (int j = 0; j < names.length; j++) { 6542 mProviderMap.putProviderByName(names[j], dst); 6543 } 6544 6545 int NL = mLaunchingProviders.size(); 6546 int j; 6547 for (j=0; j<NL; j++) { 6548 if (mLaunchingProviders.get(j) == dst) { 6549 mLaunchingProviders.remove(j); 6550 j--; 6551 NL--; 6552 } 6553 } 6554 synchronized (dst) { 6555 dst.provider = src.provider; 6556 dst.proc = r; 6557 dst.notifyAll(); 6558 } 6559 updateOomAdjLocked(r); 6560 } 6561 } 6562 6563 Binder.restoreCallingIdentity(origId); 6564 } 6565 } 6566 6567 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6568 ContentProviderConnection conn; 6569 try { 6570 conn = (ContentProviderConnection)connection; 6571 } catch (ClassCastException e) { 6572 String msg ="refContentProvider: " + connection 6573 + " not a ContentProviderConnection"; 6574 Slog.w(TAG, msg); 6575 throw new IllegalArgumentException(msg); 6576 } 6577 if (conn == null) { 6578 throw new NullPointerException("connection is null"); 6579 } 6580 6581 synchronized (this) { 6582 if (stable > 0) { 6583 conn.numStableIncs += stable; 6584 } 6585 stable = conn.stableCount + stable; 6586 if (stable < 0) { 6587 throw new IllegalStateException("stableCount < 0: " + stable); 6588 } 6589 6590 if (unstable > 0) { 6591 conn.numUnstableIncs += unstable; 6592 } 6593 unstable = conn.unstableCount + unstable; 6594 if (unstable < 0) { 6595 throw new IllegalStateException("unstableCount < 0: " + unstable); 6596 } 6597 6598 if ((stable+unstable) <= 0) { 6599 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6600 + stable + " unstable=" + unstable); 6601 } 6602 conn.stableCount = stable; 6603 conn.unstableCount = unstable; 6604 return !conn.dead; 6605 } 6606 } 6607 6608 public void unstableProviderDied(IBinder connection) { 6609 ContentProviderConnection conn; 6610 try { 6611 conn = (ContentProviderConnection)connection; 6612 } catch (ClassCastException e) { 6613 String msg ="refContentProvider: " + connection 6614 + " not a ContentProviderConnection"; 6615 Slog.w(TAG, msg); 6616 throw new IllegalArgumentException(msg); 6617 } 6618 if (conn == null) { 6619 throw new NullPointerException("connection is null"); 6620 } 6621 6622 // Safely retrieve the content provider associated with the connection. 6623 IContentProvider provider; 6624 synchronized (this) { 6625 provider = conn.provider.provider; 6626 } 6627 6628 if (provider == null) { 6629 // Um, yeah, we're way ahead of you. 6630 return; 6631 } 6632 6633 // Make sure the caller is being honest with us. 6634 if (provider.asBinder().pingBinder()) { 6635 // Er, no, still looks good to us. 6636 synchronized (this) { 6637 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6638 + " says " + conn + " died, but we don't agree"); 6639 return; 6640 } 6641 } 6642 6643 // Well look at that! It's dead! 6644 synchronized (this) { 6645 if (conn.provider.provider != provider) { 6646 // But something changed... good enough. 6647 return; 6648 } 6649 6650 ProcessRecord proc = conn.provider.proc; 6651 if (proc == null || proc.thread == null) { 6652 // Seems like the process is already cleaned up. 6653 return; 6654 } 6655 6656 // As far as we're concerned, this is just like receiving a 6657 // death notification... just a bit prematurely. 6658 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6659 + ") early provider death"); 6660 final long ident = Binder.clearCallingIdentity(); 6661 try { 6662 appDiedLocked(proc, proc.pid, proc.thread); 6663 } finally { 6664 Binder.restoreCallingIdentity(ident); 6665 } 6666 } 6667 } 6668 6669 public static final void installSystemProviders() { 6670 List<ProviderInfo> providers; 6671 synchronized (mSelf) { 6672 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6673 providers = mSelf.generateApplicationProvidersLocked(app); 6674 if (providers != null) { 6675 for (int i=providers.size()-1; i>=0; i--) { 6676 ProviderInfo pi = (ProviderInfo)providers.get(i); 6677 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6678 Slog.w(TAG, "Not installing system proc provider " + pi.name 6679 + ": not system .apk"); 6680 providers.remove(i); 6681 } 6682 } 6683 } 6684 } 6685 if (providers != null) { 6686 mSystemThread.installSystemProviders(providers); 6687 } 6688 6689 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6690 6691 mSelf.mUsageStatsService.monitorPackages(); 6692 } 6693 6694 /** 6695 * Allows app to retrieve the MIME type of a URI without having permission 6696 * to access its content provider. 6697 * 6698 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6699 * 6700 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6701 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6702 */ 6703 public String getProviderMimeType(Uri uri) { 6704 enforceNotIsolatedCaller("getProviderMimeType"); 6705 final String name = uri.getAuthority(); 6706 final long ident = Binder.clearCallingIdentity(); 6707 ContentProviderHolder holder = null; 6708 6709 try { 6710 holder = getContentProviderExternalUnchecked(name, null); 6711 if (holder != null) { 6712 return holder.provider.getType(uri); 6713 } 6714 } catch (RemoteException e) { 6715 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6716 return null; 6717 } finally { 6718 if (holder != null) { 6719 removeContentProviderExternalUnchecked(name, null); 6720 } 6721 Binder.restoreCallingIdentity(ident); 6722 } 6723 6724 return null; 6725 } 6726 6727 // ========================================================= 6728 // GLOBAL MANAGEMENT 6729 // ========================================================= 6730 6731 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6732 ApplicationInfo info, String customProcess, boolean isolated) { 6733 String proc = customProcess != null ? customProcess : info.processName; 6734 BatteryStatsImpl.Uid.Proc ps = null; 6735 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6736 int uid = info.uid; 6737 if (isolated) { 6738 int userId = UserHandle.getUserId(uid); 6739 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6740 uid = 0; 6741 while (true) { 6742 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6743 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6744 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6745 } 6746 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6747 mNextIsolatedProcessUid++; 6748 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6749 // No process for this uid, use it. 6750 break; 6751 } 6752 stepsLeft--; 6753 if (stepsLeft <= 0) { 6754 return null; 6755 } 6756 } 6757 } 6758 synchronized (stats) { 6759 ps = stats.getProcessStatsLocked(info.uid, proc); 6760 } 6761 return new ProcessRecord(ps, thread, info, proc, uid); 6762 } 6763 6764 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6765 ProcessRecord app; 6766 if (!isolated) { 6767 app = getProcessRecordLocked(info.processName, info.uid); 6768 } else { 6769 app = null; 6770 } 6771 6772 if (app == null) { 6773 app = newProcessRecordLocked(null, info, null, isolated); 6774 mProcessNames.put(info.processName, app.uid, app); 6775 if (isolated) { 6776 mIsolatedProcesses.put(app.uid, app); 6777 } 6778 updateLruProcessLocked(app, true, true); 6779 } 6780 6781 // This package really, really can not be stopped. 6782 try { 6783 AppGlobals.getPackageManager().setPackageStoppedState( 6784 info.packageName, false, UserHandle.getUserId(app.uid)); 6785 } catch (RemoteException e) { 6786 } catch (IllegalArgumentException e) { 6787 Slog.w(TAG, "Failed trying to unstop package " 6788 + info.packageName + ": " + e); 6789 } 6790 6791 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6792 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6793 app.persistent = true; 6794 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6795 } 6796 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6797 mPersistentStartingProcesses.add(app); 6798 startProcessLocked(app, "added application", app.processName); 6799 } 6800 6801 return app; 6802 } 6803 6804 public void unhandledBack() { 6805 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6806 "unhandledBack()"); 6807 6808 synchronized(this) { 6809 int count = mMainStack.mHistory.size(); 6810 if (DEBUG_SWITCH) Slog.d( 6811 TAG, "Performing unhandledBack(): stack size = " + count); 6812 if (count > 1) { 6813 final long origId = Binder.clearCallingIdentity(); 6814 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6815 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6816 Binder.restoreCallingIdentity(origId); 6817 } 6818 } 6819 } 6820 6821 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6822 enforceNotIsolatedCaller("openContentUri"); 6823 String name = uri.getAuthority(); 6824 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6825 ParcelFileDescriptor pfd = null; 6826 if (cph != null) { 6827 // We record the binder invoker's uid in thread-local storage before 6828 // going to the content provider to open the file. Later, in the code 6829 // that handles all permissions checks, we look for this uid and use 6830 // that rather than the Activity Manager's own uid. The effect is that 6831 // we do the check against the caller's permissions even though it looks 6832 // to the content provider like the Activity Manager itself is making 6833 // the request. 6834 sCallerIdentity.set(new Identity( 6835 Binder.getCallingPid(), Binder.getCallingUid())); 6836 try { 6837 pfd = cph.provider.openFile(uri, "r"); 6838 } catch (FileNotFoundException e) { 6839 // do nothing; pfd will be returned null 6840 } finally { 6841 // Ensure that whatever happens, we clean up the identity state 6842 sCallerIdentity.remove(); 6843 } 6844 6845 // We've got the fd now, so we're done with the provider. 6846 removeContentProviderExternalUnchecked(name, null); 6847 } else { 6848 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6849 } 6850 return pfd; 6851 } 6852 6853 // Actually is sleeping or shutting down or whatever else in the future 6854 // is an inactive state. 6855 public boolean isSleeping() { 6856 return mSleeping || mShuttingDown; 6857 } 6858 6859 public void goingToSleep() { 6860 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6861 != PackageManager.PERMISSION_GRANTED) { 6862 throw new SecurityException("Requires permission " 6863 + android.Manifest.permission.DEVICE_POWER); 6864 } 6865 6866 synchronized(this) { 6867 mWentToSleep = true; 6868 updateEventDispatchingLocked(); 6869 6870 if (!mSleeping) { 6871 mSleeping = true; 6872 mMainStack.stopIfSleepingLocked(); 6873 6874 // Initialize the wake times of all processes. 6875 checkExcessivePowerUsageLocked(false); 6876 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6877 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6878 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6879 } 6880 } 6881 } 6882 6883 public boolean shutdown(int timeout) { 6884 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6885 != PackageManager.PERMISSION_GRANTED) { 6886 throw new SecurityException("Requires permission " 6887 + android.Manifest.permission.SHUTDOWN); 6888 } 6889 6890 boolean timedout = false; 6891 6892 synchronized(this) { 6893 mShuttingDown = true; 6894 updateEventDispatchingLocked(); 6895 6896 if (mMainStack.mResumedActivity != null) { 6897 mMainStack.stopIfSleepingLocked(); 6898 final long endTime = System.currentTimeMillis() + timeout; 6899 while (mMainStack.mResumedActivity != null 6900 || mMainStack.mPausingActivity != null) { 6901 long delay = endTime - System.currentTimeMillis(); 6902 if (delay <= 0) { 6903 Slog.w(TAG, "Activity manager shutdown timed out"); 6904 timedout = true; 6905 break; 6906 } 6907 try { 6908 this.wait(); 6909 } catch (InterruptedException e) { 6910 } 6911 } 6912 } 6913 } 6914 6915 mUsageStatsService.shutdown(); 6916 mBatteryStatsService.shutdown(); 6917 6918 return timedout; 6919 } 6920 6921 public final void activitySlept(IBinder token) { 6922 if (localLOGV) Slog.v( 6923 TAG, "Activity slept: token=" + token); 6924 6925 ActivityRecord r = null; 6926 6927 final long origId = Binder.clearCallingIdentity(); 6928 6929 synchronized (this) { 6930 r = mMainStack.isInStackLocked(token); 6931 if (r != null) { 6932 mMainStack.activitySleptLocked(r); 6933 } 6934 } 6935 6936 Binder.restoreCallingIdentity(origId); 6937 } 6938 6939 private void comeOutOfSleepIfNeededLocked() { 6940 if (!mWentToSleep && !mLockScreenShown) { 6941 if (mSleeping) { 6942 mSleeping = false; 6943 mMainStack.awakeFromSleepingLocked(); 6944 mMainStack.resumeTopActivityLocked(null); 6945 } 6946 } 6947 } 6948 6949 public void wakingUp() { 6950 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6951 != PackageManager.PERMISSION_GRANTED) { 6952 throw new SecurityException("Requires permission " 6953 + android.Manifest.permission.DEVICE_POWER); 6954 } 6955 6956 synchronized(this) { 6957 mWentToSleep = false; 6958 updateEventDispatchingLocked(); 6959 comeOutOfSleepIfNeededLocked(); 6960 } 6961 } 6962 6963 private void updateEventDispatchingLocked() { 6964 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6965 } 6966 6967 public void setLockScreenShown(boolean shown) { 6968 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6969 != PackageManager.PERMISSION_GRANTED) { 6970 throw new SecurityException("Requires permission " 6971 + android.Manifest.permission.DEVICE_POWER); 6972 } 6973 6974 synchronized(this) { 6975 mLockScreenShown = shown; 6976 comeOutOfSleepIfNeededLocked(); 6977 } 6978 } 6979 6980 public void stopAppSwitches() { 6981 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6982 != PackageManager.PERMISSION_GRANTED) { 6983 throw new SecurityException("Requires permission " 6984 + android.Manifest.permission.STOP_APP_SWITCHES); 6985 } 6986 6987 synchronized(this) { 6988 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6989 + APP_SWITCH_DELAY_TIME; 6990 mDidAppSwitch = false; 6991 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6992 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6993 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6994 } 6995 } 6996 6997 public void resumeAppSwitches() { 6998 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6999 != PackageManager.PERMISSION_GRANTED) { 7000 throw new SecurityException("Requires permission " 7001 + android.Manifest.permission.STOP_APP_SWITCHES); 7002 } 7003 7004 synchronized(this) { 7005 // Note that we don't execute any pending app switches... we will 7006 // let those wait until either the timeout, or the next start 7007 // activity request. 7008 mAppSwitchesAllowedTime = 0; 7009 } 7010 } 7011 7012 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7013 String name) { 7014 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7015 return true; 7016 } 7017 7018 final int perm = checkComponentPermission( 7019 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7020 callingUid, -1, true); 7021 if (perm == PackageManager.PERMISSION_GRANTED) { 7022 return true; 7023 } 7024 7025 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7026 return false; 7027 } 7028 7029 public void setDebugApp(String packageName, boolean waitForDebugger, 7030 boolean persistent) { 7031 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7032 "setDebugApp()"); 7033 7034 // Note that this is not really thread safe if there are multiple 7035 // callers into it at the same time, but that's not a situation we 7036 // care about. 7037 if (persistent) { 7038 final ContentResolver resolver = mContext.getContentResolver(); 7039 Settings.System.putString( 7040 resolver, Settings.System.DEBUG_APP, 7041 packageName); 7042 Settings.System.putInt( 7043 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7044 waitForDebugger ? 1 : 0); 7045 } 7046 7047 synchronized (this) { 7048 if (!persistent) { 7049 mOrigDebugApp = mDebugApp; 7050 mOrigWaitForDebugger = mWaitForDebugger; 7051 } 7052 mDebugApp = packageName; 7053 mWaitForDebugger = waitForDebugger; 7054 mDebugTransient = !persistent; 7055 if (packageName != null) { 7056 final long origId = Binder.clearCallingIdentity(); 7057 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7058 Binder.restoreCallingIdentity(origId); 7059 } 7060 } 7061 } 7062 7063 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7064 synchronized (this) { 7065 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7066 if (!isDebuggable) { 7067 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7068 throw new SecurityException("Process not debuggable: " + app.packageName); 7069 } 7070 } 7071 7072 mOpenGlTraceApp = processName; 7073 } 7074 } 7075 7076 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7077 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7078 synchronized (this) { 7079 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7080 if (!isDebuggable) { 7081 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7082 throw new SecurityException("Process not debuggable: " + app.packageName); 7083 } 7084 } 7085 mProfileApp = processName; 7086 mProfileFile = profileFile; 7087 if (mProfileFd != null) { 7088 try { 7089 mProfileFd.close(); 7090 } catch (IOException e) { 7091 } 7092 mProfileFd = null; 7093 } 7094 mProfileFd = profileFd; 7095 mProfileType = 0; 7096 mAutoStopProfiler = autoStopProfiler; 7097 } 7098 } 7099 7100 public void setAlwaysFinish(boolean enabled) { 7101 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7102 "setAlwaysFinish()"); 7103 7104 Settings.System.putInt( 7105 mContext.getContentResolver(), 7106 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7107 7108 synchronized (this) { 7109 mAlwaysFinishActivities = enabled; 7110 } 7111 } 7112 7113 public void setActivityController(IActivityController controller) { 7114 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7115 "setActivityController()"); 7116 synchronized (this) { 7117 mController = controller; 7118 } 7119 } 7120 7121 public boolean isUserAMonkey() { 7122 // For now the fact that there is a controller implies 7123 // we have a monkey. 7124 synchronized (this) { 7125 return mController != null; 7126 } 7127 } 7128 7129 public void registerProcessObserver(IProcessObserver observer) { 7130 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7131 "registerProcessObserver()"); 7132 synchronized (this) { 7133 mProcessObservers.register(observer); 7134 } 7135 } 7136 7137 public void unregisterProcessObserver(IProcessObserver observer) { 7138 synchronized (this) { 7139 mProcessObservers.unregister(observer); 7140 } 7141 } 7142 7143 public void setImmersive(IBinder token, boolean immersive) { 7144 synchronized(this) { 7145 ActivityRecord r = mMainStack.isInStackLocked(token); 7146 if (r == null) { 7147 throw new IllegalArgumentException(); 7148 } 7149 r.immersive = immersive; 7150 } 7151 } 7152 7153 public boolean isImmersive(IBinder token) { 7154 synchronized (this) { 7155 ActivityRecord r = mMainStack.isInStackLocked(token); 7156 if (r == null) { 7157 throw new IllegalArgumentException(); 7158 } 7159 return r.immersive; 7160 } 7161 } 7162 7163 public boolean isTopActivityImmersive() { 7164 enforceNotIsolatedCaller("startActivity"); 7165 synchronized (this) { 7166 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7167 return (r != null) ? r.immersive : false; 7168 } 7169 } 7170 7171 public final void enterSafeMode() { 7172 synchronized(this) { 7173 // It only makes sense to do this before the system is ready 7174 // and started launching other packages. 7175 if (!mSystemReady) { 7176 try { 7177 AppGlobals.getPackageManager().enterSafeMode(); 7178 } catch (RemoteException e) { 7179 } 7180 } 7181 } 7182 } 7183 7184 public final void showSafeModeOverlay() { 7185 View v = LayoutInflater.from(mContext).inflate( 7186 com.android.internal.R.layout.safe_mode, null); 7187 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7188 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7189 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7190 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7191 lp.gravity = Gravity.BOTTOM | Gravity.START; 7192 lp.format = v.getBackground().getOpacity(); 7193 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7194 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7195 ((WindowManager)mContext.getSystemService( 7196 Context.WINDOW_SERVICE)).addView(v, lp); 7197 } 7198 7199 public void noteWakeupAlarm(IIntentSender sender) { 7200 if (!(sender instanceof PendingIntentRecord)) { 7201 return; 7202 } 7203 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7204 synchronized (stats) { 7205 if (mBatteryStatsService.isOnBattery()) { 7206 mBatteryStatsService.enforceCallingPermission(); 7207 PendingIntentRecord rec = (PendingIntentRecord)sender; 7208 int MY_UID = Binder.getCallingUid(); 7209 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7210 BatteryStatsImpl.Uid.Pkg pkg = 7211 stats.getPackageStatsLocked(uid, rec.key.packageName); 7212 pkg.incWakeupsLocked(); 7213 } 7214 } 7215 } 7216 7217 public boolean killPids(int[] pids, String pReason, boolean secure) { 7218 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7219 throw new SecurityException("killPids only available to the system"); 7220 } 7221 String reason = (pReason == null) ? "Unknown" : pReason; 7222 // XXX Note: don't acquire main activity lock here, because the window 7223 // manager calls in with its locks held. 7224 7225 boolean killed = false; 7226 synchronized (mPidsSelfLocked) { 7227 int[] types = new int[pids.length]; 7228 int worstType = 0; 7229 for (int i=0; i<pids.length; i++) { 7230 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7231 if (proc != null) { 7232 int type = proc.setAdj; 7233 types[i] = type; 7234 if (type > worstType) { 7235 worstType = type; 7236 } 7237 } 7238 } 7239 7240 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7241 // then constrain it so we will kill all hidden procs. 7242 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7243 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7244 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7245 } 7246 7247 // If this is not a secure call, don't let it kill processes that 7248 // are important. 7249 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7250 worstType = ProcessList.SERVICE_ADJ; 7251 } 7252 7253 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7254 for (int i=0; i<pids.length; i++) { 7255 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7256 if (proc == null) { 7257 continue; 7258 } 7259 int adj = proc.setAdj; 7260 if (adj >= worstType && !proc.killedBackground) { 7261 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7262 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7263 proc.processName, adj, reason); 7264 killed = true; 7265 proc.killedBackground = true; 7266 Process.killProcessQuiet(pids[i]); 7267 } 7268 } 7269 } 7270 return killed; 7271 } 7272 7273 @Override 7274 public boolean killProcessesBelowForeground(String reason) { 7275 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7276 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7277 } 7278 7279 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7280 } 7281 7282 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7283 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7284 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7285 } 7286 7287 boolean killed = false; 7288 synchronized (mPidsSelfLocked) { 7289 final int size = mPidsSelfLocked.size(); 7290 for (int i = 0; i < size; i++) { 7291 final int pid = mPidsSelfLocked.keyAt(i); 7292 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7293 if (proc == null) continue; 7294 7295 final int adj = proc.setAdj; 7296 if (adj > belowAdj && !proc.killedBackground) { 7297 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7298 EventLog.writeEvent( 7299 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7300 killed = true; 7301 proc.killedBackground = true; 7302 Process.killProcessQuiet(pid); 7303 } 7304 } 7305 } 7306 return killed; 7307 } 7308 7309 public final void startRunning(String pkg, String cls, String action, 7310 String data) { 7311 synchronized(this) { 7312 if (mStartRunning) { 7313 return; 7314 } 7315 mStartRunning = true; 7316 mTopComponent = pkg != null && cls != null 7317 ? new ComponentName(pkg, cls) : null; 7318 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7319 mTopData = data; 7320 if (!mSystemReady) { 7321 return; 7322 } 7323 } 7324 7325 systemReady(null); 7326 } 7327 7328 private void retrieveSettings() { 7329 final ContentResolver resolver = mContext.getContentResolver(); 7330 String debugApp = Settings.System.getString( 7331 resolver, Settings.System.DEBUG_APP); 7332 boolean waitForDebugger = Settings.System.getInt( 7333 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7334 boolean alwaysFinishActivities = Settings.System.getInt( 7335 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7336 7337 Configuration configuration = new Configuration(); 7338 Settings.System.getConfiguration(resolver, configuration); 7339 7340 synchronized (this) { 7341 mDebugApp = mOrigDebugApp = debugApp; 7342 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7343 mAlwaysFinishActivities = alwaysFinishActivities; 7344 // This happens before any activities are started, so we can 7345 // change mConfiguration in-place. 7346 updateConfigurationLocked(configuration, null, false, true); 7347 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7348 } 7349 } 7350 7351 public boolean testIsSystemReady() { 7352 // no need to synchronize(this) just to read & return the value 7353 return mSystemReady; 7354 } 7355 7356 private static File getCalledPreBootReceiversFile() { 7357 File dataDir = Environment.getDataDirectory(); 7358 File systemDir = new File(dataDir, "system"); 7359 File fname = new File(systemDir, "called_pre_boots.dat"); 7360 return fname; 7361 } 7362 7363 static final int LAST_DONE_VERSION = 10000; 7364 7365 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7366 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7367 File file = getCalledPreBootReceiversFile(); 7368 FileInputStream fis = null; 7369 try { 7370 fis = new FileInputStream(file); 7371 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7372 int fvers = dis.readInt(); 7373 if (fvers == LAST_DONE_VERSION) { 7374 String vers = dis.readUTF(); 7375 String codename = dis.readUTF(); 7376 String build = dis.readUTF(); 7377 if (android.os.Build.VERSION.RELEASE.equals(vers) 7378 && android.os.Build.VERSION.CODENAME.equals(codename) 7379 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7380 int num = dis.readInt(); 7381 while (num > 0) { 7382 num--; 7383 String pkg = dis.readUTF(); 7384 String cls = dis.readUTF(); 7385 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7386 } 7387 } 7388 } 7389 } catch (FileNotFoundException e) { 7390 } catch (IOException e) { 7391 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7392 } finally { 7393 if (fis != null) { 7394 try { 7395 fis.close(); 7396 } catch (IOException e) { 7397 } 7398 } 7399 } 7400 return lastDoneReceivers; 7401 } 7402 7403 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7404 File file = getCalledPreBootReceiversFile(); 7405 FileOutputStream fos = null; 7406 DataOutputStream dos = null; 7407 try { 7408 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7409 fos = new FileOutputStream(file); 7410 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7411 dos.writeInt(LAST_DONE_VERSION); 7412 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7413 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7414 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7415 dos.writeInt(list.size()); 7416 for (int i=0; i<list.size(); i++) { 7417 dos.writeUTF(list.get(i).getPackageName()); 7418 dos.writeUTF(list.get(i).getClassName()); 7419 } 7420 } catch (IOException e) { 7421 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7422 file.delete(); 7423 } finally { 7424 FileUtils.sync(fos); 7425 if (dos != null) { 7426 try { 7427 dos.close(); 7428 } catch (IOException e) { 7429 // TODO Auto-generated catch block 7430 e.printStackTrace(); 7431 } 7432 } 7433 } 7434 } 7435 7436 public void systemReady(final Runnable goingCallback) { 7437 synchronized(this) { 7438 if (mSystemReady) { 7439 if (goingCallback != null) goingCallback.run(); 7440 return; 7441 } 7442 7443 // Check to see if there are any update receivers to run. 7444 if (!mDidUpdate) { 7445 if (mWaitingUpdate) { 7446 return; 7447 } 7448 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7449 List<ResolveInfo> ris = null; 7450 try { 7451 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7452 intent, null, 0, 0); 7453 } catch (RemoteException e) { 7454 } 7455 if (ris != null) { 7456 for (int i=ris.size()-1; i>=0; i--) { 7457 if ((ris.get(i).activityInfo.applicationInfo.flags 7458 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7459 ris.remove(i); 7460 } 7461 } 7462 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7463 7464 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7465 7466 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7467 for (int i=0; i<ris.size(); i++) { 7468 ActivityInfo ai = ris.get(i).activityInfo; 7469 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7470 if (lastDoneReceivers.contains(comp)) { 7471 ris.remove(i); 7472 i--; 7473 } 7474 } 7475 7476 for (int i=0; i<ris.size(); i++) { 7477 ActivityInfo ai = ris.get(i).activityInfo; 7478 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7479 doneReceivers.add(comp); 7480 intent.setComponent(comp); 7481 IIntentReceiver finisher = null; 7482 if (i == ris.size()-1) { 7483 finisher = new IIntentReceiver.Stub() { 7484 public void performReceive(Intent intent, int resultCode, 7485 String data, Bundle extras, boolean ordered, 7486 boolean sticky) { 7487 // The raw IIntentReceiver interface is called 7488 // with the AM lock held, so redispatch to 7489 // execute our code without the lock. 7490 mHandler.post(new Runnable() { 7491 public void run() { 7492 synchronized (ActivityManagerService.this) { 7493 mDidUpdate = true; 7494 } 7495 writeLastDonePreBootReceivers(doneReceivers); 7496 showBootMessage(mContext.getText( 7497 R.string.android_upgrading_complete), 7498 false); 7499 systemReady(goingCallback); 7500 } 7501 }); 7502 } 7503 }; 7504 } 7505 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7506 /* TODO: Send this to all users */ 7507 broadcastIntentLocked(null, null, intent, null, finisher, 7508 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7509 0 /* UserId zero */); 7510 if (finisher != null) { 7511 mWaitingUpdate = true; 7512 } 7513 } 7514 } 7515 if (mWaitingUpdate) { 7516 return; 7517 } 7518 mDidUpdate = true; 7519 } 7520 7521 mSystemReady = true; 7522 if (!mStartRunning) { 7523 return; 7524 } 7525 } 7526 7527 ArrayList<ProcessRecord> procsToKill = null; 7528 synchronized(mPidsSelfLocked) { 7529 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7530 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7531 if (!isAllowedWhileBooting(proc.info)){ 7532 if (procsToKill == null) { 7533 procsToKill = new ArrayList<ProcessRecord>(); 7534 } 7535 procsToKill.add(proc); 7536 } 7537 } 7538 } 7539 7540 synchronized(this) { 7541 if (procsToKill != null) { 7542 for (int i=procsToKill.size()-1; i>=0; i--) { 7543 ProcessRecord proc = procsToKill.get(i); 7544 Slog.i(TAG, "Removing system update proc: " + proc); 7545 removeProcessLocked(proc, true, false, "system update done"); 7546 } 7547 } 7548 7549 // Now that we have cleaned up any update processes, we 7550 // are ready to start launching real processes and know that 7551 // we won't trample on them any more. 7552 mProcessesReady = true; 7553 } 7554 7555 Slog.i(TAG, "System now ready"); 7556 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7557 SystemClock.uptimeMillis()); 7558 7559 synchronized(this) { 7560 // Make sure we have no pre-ready processes sitting around. 7561 7562 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7563 ResolveInfo ri = mContext.getPackageManager() 7564 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7565 STOCK_PM_FLAGS); 7566 CharSequence errorMsg = null; 7567 if (ri != null) { 7568 ActivityInfo ai = ri.activityInfo; 7569 ApplicationInfo app = ai.applicationInfo; 7570 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7571 mTopAction = Intent.ACTION_FACTORY_TEST; 7572 mTopData = null; 7573 mTopComponent = new ComponentName(app.packageName, 7574 ai.name); 7575 } else { 7576 errorMsg = mContext.getResources().getText( 7577 com.android.internal.R.string.factorytest_not_system); 7578 } 7579 } else { 7580 errorMsg = mContext.getResources().getText( 7581 com.android.internal.R.string.factorytest_no_action); 7582 } 7583 if (errorMsg != null) { 7584 mTopAction = null; 7585 mTopData = null; 7586 mTopComponent = null; 7587 Message msg = Message.obtain(); 7588 msg.what = SHOW_FACTORY_ERROR_MSG; 7589 msg.getData().putCharSequence("msg", errorMsg); 7590 mHandler.sendMessage(msg); 7591 } 7592 } 7593 } 7594 7595 retrieveSettings(); 7596 7597 if (goingCallback != null) goingCallback.run(); 7598 7599 synchronized (this) { 7600 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7601 try { 7602 List apps = AppGlobals.getPackageManager(). 7603 getPersistentApplications(STOCK_PM_FLAGS); 7604 if (apps != null) { 7605 int N = apps.size(); 7606 int i; 7607 for (i=0; i<N; i++) { 7608 ApplicationInfo info 7609 = (ApplicationInfo)apps.get(i); 7610 if (info != null && 7611 !info.packageName.equals("android")) { 7612 addAppLocked(info, false); 7613 } 7614 } 7615 } 7616 } catch (RemoteException ex) { 7617 // pm is in same process, this will never happen. 7618 } 7619 } 7620 7621 // Start up initial activity. 7622 mBooting = true; 7623 7624 try { 7625 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7626 Message msg = Message.obtain(); 7627 msg.what = SHOW_UID_ERROR_MSG; 7628 mHandler.sendMessage(msg); 7629 } 7630 } catch (RemoteException e) { 7631 } 7632 7633 mMainStack.resumeTopActivityLocked(null); 7634 } 7635 } 7636 7637 private boolean makeAppCrashingLocked(ProcessRecord app, 7638 String shortMsg, String longMsg, String stackTrace) { 7639 app.crashing = true; 7640 app.crashingReport = generateProcessError(app, 7641 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7642 startAppProblemLocked(app); 7643 app.stopFreezingAllLocked(); 7644 return handleAppCrashLocked(app); 7645 } 7646 7647 private void makeAppNotRespondingLocked(ProcessRecord app, 7648 String activity, String shortMsg, String longMsg) { 7649 app.notResponding = true; 7650 app.notRespondingReport = generateProcessError(app, 7651 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7652 activity, shortMsg, longMsg, null); 7653 startAppProblemLocked(app); 7654 app.stopFreezingAllLocked(); 7655 } 7656 7657 /** 7658 * Generate a process error record, suitable for attachment to a ProcessRecord. 7659 * 7660 * @param app The ProcessRecord in which the error occurred. 7661 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7662 * ActivityManager.AppErrorStateInfo 7663 * @param activity The activity associated with the crash, if known. 7664 * @param shortMsg Short message describing the crash. 7665 * @param longMsg Long message describing the crash. 7666 * @param stackTrace Full crash stack trace, may be null. 7667 * 7668 * @return Returns a fully-formed AppErrorStateInfo record. 7669 */ 7670 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7671 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7672 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7673 7674 report.condition = condition; 7675 report.processName = app.processName; 7676 report.pid = app.pid; 7677 report.uid = app.info.uid; 7678 report.tag = activity; 7679 report.shortMsg = shortMsg; 7680 report.longMsg = longMsg; 7681 report.stackTrace = stackTrace; 7682 7683 return report; 7684 } 7685 7686 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7687 synchronized (this) { 7688 app.crashing = false; 7689 app.crashingReport = null; 7690 app.notResponding = false; 7691 app.notRespondingReport = null; 7692 if (app.anrDialog == fromDialog) { 7693 app.anrDialog = null; 7694 } 7695 if (app.waitDialog == fromDialog) { 7696 app.waitDialog = null; 7697 } 7698 if (app.pid > 0 && app.pid != MY_PID) { 7699 handleAppCrashLocked(app); 7700 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7701 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7702 app.processName, app.setAdj, "user's request after error"); 7703 Process.killProcessQuiet(app.pid); 7704 } 7705 } 7706 } 7707 7708 private boolean handleAppCrashLocked(ProcessRecord app) { 7709 if (mHeadless) { 7710 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7711 return false; 7712 } 7713 long now = SystemClock.uptimeMillis(); 7714 7715 Long crashTime; 7716 if (!app.isolated) { 7717 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7718 } else { 7719 crashTime = null; 7720 } 7721 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7722 // This process loses! 7723 Slog.w(TAG, "Process " + app.info.processName 7724 + " has crashed too many times: killing!"); 7725 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7726 app.info.processName, app.uid); 7727 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7728 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7729 if (r.app == app) { 7730 Slog.w(TAG, " Force finishing activity " 7731 + r.intent.getComponent().flattenToShortString()); 7732 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7733 } 7734 } 7735 if (!app.persistent) { 7736 // We don't want to start this process again until the user 7737 // explicitly does so... but for persistent process, we really 7738 // need to keep it running. If a persistent process is actually 7739 // repeatedly crashing, then badness for everyone. 7740 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7741 app.info.processName); 7742 if (!app.isolated) { 7743 // XXX We don't have a way to mark isolated processes 7744 // as bad, since they don't have a peristent identity. 7745 mBadProcesses.put(app.info.processName, app.uid, now); 7746 mProcessCrashTimes.remove(app.info.processName, app.uid); 7747 } 7748 app.bad = true; 7749 app.removed = true; 7750 // Don't let services in this process be restarted and potentially 7751 // annoy the user repeatedly. Unless it is persistent, since those 7752 // processes run critical code. 7753 removeProcessLocked(app, false, false, "crash"); 7754 mMainStack.resumeTopActivityLocked(null); 7755 return false; 7756 } 7757 mMainStack.resumeTopActivityLocked(null); 7758 } else { 7759 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7760 if (r != null && r.app == app) { 7761 // If the top running activity is from this crashing 7762 // process, then terminate it to avoid getting in a loop. 7763 Slog.w(TAG, " Force finishing activity " 7764 + r.intent.getComponent().flattenToShortString()); 7765 int index = mMainStack.indexOfActivityLocked(r); 7766 r.stack.finishActivityLocked(r, index, 7767 Activity.RESULT_CANCELED, null, "crashed"); 7768 // Also terminate any activities below it that aren't yet 7769 // stopped, to avoid a situation where one will get 7770 // re-start our crashing activity once it gets resumed again. 7771 index--; 7772 if (index >= 0) { 7773 r = (ActivityRecord)mMainStack.mHistory.get(index); 7774 if (r.state == ActivityState.RESUMED 7775 || r.state == ActivityState.PAUSING 7776 || r.state == ActivityState.PAUSED) { 7777 if (!r.isHomeActivity || mHomeProcess != r.app) { 7778 Slog.w(TAG, " Force finishing activity " 7779 + r.intent.getComponent().flattenToShortString()); 7780 r.stack.finishActivityLocked(r, index, 7781 Activity.RESULT_CANCELED, null, "crashed"); 7782 } 7783 } 7784 } 7785 } 7786 } 7787 7788 // Bump up the crash count of any services currently running in the proc. 7789 if (app.services.size() != 0) { 7790 // Any services running in the application need to be placed 7791 // back in the pending list. 7792 Iterator<ServiceRecord> it = app.services.iterator(); 7793 while (it.hasNext()) { 7794 ServiceRecord sr = it.next(); 7795 sr.crashCount++; 7796 } 7797 } 7798 7799 // If the crashing process is what we consider to be the "home process" and it has been 7800 // replaced by a third-party app, clear the package preferred activities from packages 7801 // with a home activity running in the process to prevent a repeatedly crashing app 7802 // from blocking the user to manually clear the list. 7803 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7804 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7805 Iterator it = mHomeProcess.activities.iterator(); 7806 while (it.hasNext()) { 7807 ActivityRecord r = (ActivityRecord)it.next(); 7808 if (r.isHomeActivity) { 7809 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7810 try { 7811 ActivityThread.getPackageManager() 7812 .clearPackagePreferredActivities(r.packageName); 7813 } catch (RemoteException c) { 7814 // pm is in same process, this will never happen. 7815 } 7816 } 7817 } 7818 } 7819 7820 if (!app.isolated) { 7821 // XXX Can't keep track of crash times for isolated processes, 7822 // because they don't have a perisistent identity. 7823 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7824 } 7825 7826 return true; 7827 } 7828 7829 void startAppProblemLocked(ProcessRecord app) { 7830 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7831 mContext, app.info.packageName, app.info.flags); 7832 skipCurrentReceiverLocked(app); 7833 } 7834 7835 void skipCurrentReceiverLocked(ProcessRecord app) { 7836 for (BroadcastQueue queue : mBroadcastQueues) { 7837 queue.skipCurrentReceiverLocked(app); 7838 } 7839 } 7840 7841 /** 7842 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7843 * The application process will exit immediately after this call returns. 7844 * @param app object of the crashing app, null for the system server 7845 * @param crashInfo describing the exception 7846 */ 7847 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7848 ProcessRecord r = findAppProcess(app, "Crash"); 7849 final String processName = app == null ? "system_server" 7850 : (r == null ? "unknown" : r.processName); 7851 7852 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7853 processName, 7854 r == null ? -1 : r.info.flags, 7855 crashInfo.exceptionClassName, 7856 crashInfo.exceptionMessage, 7857 crashInfo.throwFileName, 7858 crashInfo.throwLineNumber); 7859 7860 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7861 7862 crashApplication(r, crashInfo); 7863 } 7864 7865 public void handleApplicationStrictModeViolation( 7866 IBinder app, 7867 int violationMask, 7868 StrictMode.ViolationInfo info) { 7869 ProcessRecord r = findAppProcess(app, "StrictMode"); 7870 if (r == null) { 7871 return; 7872 } 7873 7874 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7875 Integer stackFingerprint = info.hashCode(); 7876 boolean logIt = true; 7877 synchronized (mAlreadyLoggedViolatedStacks) { 7878 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7879 logIt = false; 7880 // TODO: sub-sample into EventLog for these, with 7881 // the info.durationMillis? Then we'd get 7882 // the relative pain numbers, without logging all 7883 // the stack traces repeatedly. We'd want to do 7884 // likewise in the client code, which also does 7885 // dup suppression, before the Binder call. 7886 } else { 7887 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7888 mAlreadyLoggedViolatedStacks.clear(); 7889 } 7890 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7891 } 7892 } 7893 if (logIt) { 7894 logStrictModeViolationToDropBox(r, info); 7895 } 7896 } 7897 7898 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7899 AppErrorResult result = new AppErrorResult(); 7900 synchronized (this) { 7901 final long origId = Binder.clearCallingIdentity(); 7902 7903 Message msg = Message.obtain(); 7904 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7905 HashMap<String, Object> data = new HashMap<String, Object>(); 7906 data.put("result", result); 7907 data.put("app", r); 7908 data.put("violationMask", violationMask); 7909 data.put("info", info); 7910 msg.obj = data; 7911 mHandler.sendMessage(msg); 7912 7913 Binder.restoreCallingIdentity(origId); 7914 } 7915 int res = result.get(); 7916 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7917 } 7918 } 7919 7920 // Depending on the policy in effect, there could be a bunch of 7921 // these in quick succession so we try to batch these together to 7922 // minimize disk writes, number of dropbox entries, and maximize 7923 // compression, by having more fewer, larger records. 7924 private void logStrictModeViolationToDropBox( 7925 ProcessRecord process, 7926 StrictMode.ViolationInfo info) { 7927 if (info == null) { 7928 return; 7929 } 7930 final boolean isSystemApp = process == null || 7931 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7932 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7933 final String processName = process == null ? "unknown" : process.processName; 7934 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7935 final DropBoxManager dbox = (DropBoxManager) 7936 mContext.getSystemService(Context.DROPBOX_SERVICE); 7937 7938 // Exit early if the dropbox isn't configured to accept this report type. 7939 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7940 7941 boolean bufferWasEmpty; 7942 boolean needsFlush; 7943 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7944 synchronized (sb) { 7945 bufferWasEmpty = sb.length() == 0; 7946 appendDropBoxProcessHeaders(process, processName, sb); 7947 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7948 sb.append("System-App: ").append(isSystemApp).append("\n"); 7949 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7950 if (info.violationNumThisLoop != 0) { 7951 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7952 } 7953 if (info.numAnimationsRunning != 0) { 7954 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7955 } 7956 if (info.broadcastIntentAction != null) { 7957 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7958 } 7959 if (info.durationMillis != -1) { 7960 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7961 } 7962 if (info.numInstances != -1) { 7963 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7964 } 7965 if (info.tags != null) { 7966 for (String tag : info.tags) { 7967 sb.append("Span-Tag: ").append(tag).append("\n"); 7968 } 7969 } 7970 sb.append("\n"); 7971 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7972 sb.append(info.crashInfo.stackTrace); 7973 } 7974 sb.append("\n"); 7975 7976 // Only buffer up to ~64k. Various logging bits truncate 7977 // things at 128k. 7978 needsFlush = (sb.length() > 64 * 1024); 7979 } 7980 7981 // Flush immediately if the buffer's grown too large, or this 7982 // is a non-system app. Non-system apps are isolated with a 7983 // different tag & policy and not batched. 7984 // 7985 // Batching is useful during internal testing with 7986 // StrictMode settings turned up high. Without batching, 7987 // thousands of separate files could be created on boot. 7988 if (!isSystemApp || needsFlush) { 7989 new Thread("Error dump: " + dropboxTag) { 7990 @Override 7991 public void run() { 7992 String report; 7993 synchronized (sb) { 7994 report = sb.toString(); 7995 sb.delete(0, sb.length()); 7996 sb.trimToSize(); 7997 } 7998 if (report.length() != 0) { 7999 dbox.addText(dropboxTag, report); 8000 } 8001 } 8002 }.start(); 8003 return; 8004 } 8005 8006 // System app batching: 8007 if (!bufferWasEmpty) { 8008 // An existing dropbox-writing thread is outstanding, so 8009 // we don't need to start it up. The existing thread will 8010 // catch the buffer appends we just did. 8011 return; 8012 } 8013 8014 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8015 // (After this point, we shouldn't access AMS internal data structures.) 8016 new Thread("Error dump: " + dropboxTag) { 8017 @Override 8018 public void run() { 8019 // 5 second sleep to let stacks arrive and be batched together 8020 try { 8021 Thread.sleep(5000); // 5 seconds 8022 } catch (InterruptedException e) {} 8023 8024 String errorReport; 8025 synchronized (mStrictModeBuffer) { 8026 errorReport = mStrictModeBuffer.toString(); 8027 if (errorReport.length() == 0) { 8028 return; 8029 } 8030 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8031 mStrictModeBuffer.trimToSize(); 8032 } 8033 dbox.addText(dropboxTag, errorReport); 8034 } 8035 }.start(); 8036 } 8037 8038 /** 8039 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8040 * @param app object of the crashing app, null for the system server 8041 * @param tag reported by the caller 8042 * @param crashInfo describing the context of the error 8043 * @return true if the process should exit immediately (WTF is fatal) 8044 */ 8045 public boolean handleApplicationWtf(IBinder app, String tag, 8046 ApplicationErrorReport.CrashInfo crashInfo) { 8047 ProcessRecord r = findAppProcess(app, "WTF"); 8048 final String processName = app == null ? "system_server" 8049 : (r == null ? "unknown" : r.processName); 8050 8051 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8052 processName, 8053 r == null ? -1 : r.info.flags, 8054 tag, crashInfo.exceptionMessage); 8055 8056 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8057 8058 if (r != null && r.pid != Process.myPid() && 8059 Settings.Secure.getInt(mContext.getContentResolver(), 8060 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8061 crashApplication(r, crashInfo); 8062 return true; 8063 } else { 8064 return false; 8065 } 8066 } 8067 8068 /** 8069 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8070 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8071 */ 8072 private ProcessRecord findAppProcess(IBinder app, String reason) { 8073 if (app == null) { 8074 return null; 8075 } 8076 8077 synchronized (this) { 8078 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8079 final int NA = apps.size(); 8080 for (int ia=0; ia<NA; ia++) { 8081 ProcessRecord p = apps.valueAt(ia); 8082 if (p.thread != null && p.thread.asBinder() == app) { 8083 return p; 8084 } 8085 } 8086 } 8087 8088 Slog.w(TAG, "Can't find mystery application for " + reason 8089 + " from pid=" + Binder.getCallingPid() 8090 + " uid=" + Binder.getCallingUid() + ": " + app); 8091 return null; 8092 } 8093 } 8094 8095 /** 8096 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8097 * to append various headers to the dropbox log text. 8098 */ 8099 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8100 StringBuilder sb) { 8101 // Watchdog thread ends up invoking this function (with 8102 // a null ProcessRecord) to add the stack file to dropbox. 8103 // Do not acquire a lock on this (am) in such cases, as it 8104 // could cause a potential deadlock, if and when watchdog 8105 // is invoked due to unavailability of lock on am and it 8106 // would prevent watchdog from killing system_server. 8107 if (process == null) { 8108 sb.append("Process: ").append(processName).append("\n"); 8109 return; 8110 } 8111 // Note: ProcessRecord 'process' is guarded by the service 8112 // instance. (notably process.pkgList, which could otherwise change 8113 // concurrently during execution of this method) 8114 synchronized (this) { 8115 sb.append("Process: ").append(processName).append("\n"); 8116 int flags = process.info.flags; 8117 IPackageManager pm = AppGlobals.getPackageManager(); 8118 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8119 for (String pkg : process.pkgList) { 8120 sb.append("Package: ").append(pkg); 8121 try { 8122 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8123 if (pi != null) { 8124 sb.append(" v").append(pi.versionCode); 8125 if (pi.versionName != null) { 8126 sb.append(" (").append(pi.versionName).append(")"); 8127 } 8128 } 8129 } catch (RemoteException e) { 8130 Slog.e(TAG, "Error getting package info: " + pkg, e); 8131 } 8132 sb.append("\n"); 8133 } 8134 } 8135 } 8136 8137 private static String processClass(ProcessRecord process) { 8138 if (process == null || process.pid == MY_PID) { 8139 return "system_server"; 8140 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8141 return "system_app"; 8142 } else { 8143 return "data_app"; 8144 } 8145 } 8146 8147 /** 8148 * Write a description of an error (crash, WTF, ANR) to the drop box. 8149 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8150 * @param process which caused the error, null means the system server 8151 * @param activity which triggered the error, null if unknown 8152 * @param parent activity related to the error, null if unknown 8153 * @param subject line related to the error, null if absent 8154 * @param report in long form describing the error, null if absent 8155 * @param logFile to include in the report, null if none 8156 * @param crashInfo giving an application stack trace, null if absent 8157 */ 8158 public void addErrorToDropBox(String eventType, 8159 ProcessRecord process, String processName, ActivityRecord activity, 8160 ActivityRecord parent, String subject, 8161 final String report, final File logFile, 8162 final ApplicationErrorReport.CrashInfo crashInfo) { 8163 // NOTE -- this must never acquire the ActivityManagerService lock, 8164 // otherwise the watchdog may be prevented from resetting the system. 8165 8166 final String dropboxTag = processClass(process) + "_" + eventType; 8167 final DropBoxManager dbox = (DropBoxManager) 8168 mContext.getSystemService(Context.DROPBOX_SERVICE); 8169 8170 // Exit early if the dropbox isn't configured to accept this report type. 8171 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8172 8173 final StringBuilder sb = new StringBuilder(1024); 8174 appendDropBoxProcessHeaders(process, processName, sb); 8175 if (activity != null) { 8176 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8177 } 8178 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8179 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8180 } 8181 if (parent != null && parent != activity) { 8182 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8183 } 8184 if (subject != null) { 8185 sb.append("Subject: ").append(subject).append("\n"); 8186 } 8187 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8188 if (Debug.isDebuggerConnected()) { 8189 sb.append("Debugger: Connected\n"); 8190 } 8191 sb.append("\n"); 8192 8193 // Do the rest in a worker thread to avoid blocking the caller on I/O 8194 // (After this point, we shouldn't access AMS internal data structures.) 8195 Thread worker = new Thread("Error dump: " + dropboxTag) { 8196 @Override 8197 public void run() { 8198 if (report != null) { 8199 sb.append(report); 8200 } 8201 if (logFile != null) { 8202 try { 8203 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8204 } catch (IOException e) { 8205 Slog.e(TAG, "Error reading " + logFile, e); 8206 } 8207 } 8208 if (crashInfo != null && crashInfo.stackTrace != null) { 8209 sb.append(crashInfo.stackTrace); 8210 } 8211 8212 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8213 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8214 if (lines > 0) { 8215 sb.append("\n"); 8216 8217 // Merge several logcat streams, and take the last N lines 8218 InputStreamReader input = null; 8219 try { 8220 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8221 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8222 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8223 8224 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8225 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8226 input = new InputStreamReader(logcat.getInputStream()); 8227 8228 int num; 8229 char[] buf = new char[8192]; 8230 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8231 } catch (IOException e) { 8232 Slog.e(TAG, "Error running logcat", e); 8233 } finally { 8234 if (input != null) try { input.close(); } catch (IOException e) {} 8235 } 8236 } 8237 8238 dbox.addText(dropboxTag, sb.toString()); 8239 } 8240 }; 8241 8242 if (process == null) { 8243 // If process is null, we are being called from some internal code 8244 // and may be about to die -- run this synchronously. 8245 worker.run(); 8246 } else { 8247 worker.start(); 8248 } 8249 } 8250 8251 /** 8252 * Bring up the "unexpected error" dialog box for a crashing app. 8253 * Deal with edge cases (intercepts from instrumented applications, 8254 * ActivityController, error intent receivers, that sort of thing). 8255 * @param r the application crashing 8256 * @param crashInfo describing the failure 8257 */ 8258 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8259 long timeMillis = System.currentTimeMillis(); 8260 String shortMsg = crashInfo.exceptionClassName; 8261 String longMsg = crashInfo.exceptionMessage; 8262 String stackTrace = crashInfo.stackTrace; 8263 if (shortMsg != null && longMsg != null) { 8264 longMsg = shortMsg + ": " + longMsg; 8265 } else if (shortMsg != null) { 8266 longMsg = shortMsg; 8267 } 8268 8269 AppErrorResult result = new AppErrorResult(); 8270 synchronized (this) { 8271 if (mController != null) { 8272 try { 8273 String name = r != null ? r.processName : null; 8274 int pid = r != null ? r.pid : Binder.getCallingPid(); 8275 if (!mController.appCrashed(name, pid, 8276 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8277 Slog.w(TAG, "Force-killing crashed app " + name 8278 + " at watcher's request"); 8279 Process.killProcess(pid); 8280 return; 8281 } 8282 } catch (RemoteException e) { 8283 mController = null; 8284 } 8285 } 8286 8287 final long origId = Binder.clearCallingIdentity(); 8288 8289 // If this process is running instrumentation, finish it. 8290 if (r != null && r.instrumentationClass != null) { 8291 Slog.w(TAG, "Error in app " + r.processName 8292 + " running instrumentation " + r.instrumentationClass + ":"); 8293 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8294 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8295 Bundle info = new Bundle(); 8296 info.putString("shortMsg", shortMsg); 8297 info.putString("longMsg", longMsg); 8298 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8299 Binder.restoreCallingIdentity(origId); 8300 return; 8301 } 8302 8303 // If we can't identify the process or it's already exceeded its crash quota, 8304 // quit right away without showing a crash dialog. 8305 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8306 Binder.restoreCallingIdentity(origId); 8307 return; 8308 } 8309 8310 Message msg = Message.obtain(); 8311 msg.what = SHOW_ERROR_MSG; 8312 HashMap data = new HashMap(); 8313 data.put("result", result); 8314 data.put("app", r); 8315 msg.obj = data; 8316 mHandler.sendMessage(msg); 8317 8318 Binder.restoreCallingIdentity(origId); 8319 } 8320 8321 int res = result.get(); 8322 8323 Intent appErrorIntent = null; 8324 synchronized (this) { 8325 if (r != null && !r.isolated) { 8326 // XXX Can't keep track of crash time for isolated processes, 8327 // since they don't have a persistent identity. 8328 mProcessCrashTimes.put(r.info.processName, r.uid, 8329 SystemClock.uptimeMillis()); 8330 } 8331 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8332 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8333 } 8334 } 8335 8336 if (appErrorIntent != null) { 8337 try { 8338 mContext.startActivity(appErrorIntent); 8339 } catch (ActivityNotFoundException e) { 8340 Slog.w(TAG, "bug report receiver dissappeared", e); 8341 } 8342 } 8343 } 8344 8345 Intent createAppErrorIntentLocked(ProcessRecord r, 8346 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8347 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8348 if (report == null) { 8349 return null; 8350 } 8351 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8352 result.setComponent(r.errorReportReceiver); 8353 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8354 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8355 return result; 8356 } 8357 8358 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8359 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8360 if (r.errorReportReceiver == null) { 8361 return null; 8362 } 8363 8364 if (!r.crashing && !r.notResponding) { 8365 return null; 8366 } 8367 8368 ApplicationErrorReport report = new ApplicationErrorReport(); 8369 report.packageName = r.info.packageName; 8370 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8371 report.processName = r.processName; 8372 report.time = timeMillis; 8373 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8374 8375 if (r.crashing) { 8376 report.type = ApplicationErrorReport.TYPE_CRASH; 8377 report.crashInfo = crashInfo; 8378 } else if (r.notResponding) { 8379 report.type = ApplicationErrorReport.TYPE_ANR; 8380 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8381 8382 report.anrInfo.activity = r.notRespondingReport.tag; 8383 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8384 report.anrInfo.info = r.notRespondingReport.longMsg; 8385 } 8386 8387 return report; 8388 } 8389 8390 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8391 enforceNotIsolatedCaller("getProcessesInErrorState"); 8392 // assume our apps are happy - lazy create the list 8393 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8394 8395 synchronized (this) { 8396 8397 // iterate across all processes 8398 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8399 ProcessRecord app = mLruProcesses.get(i); 8400 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8401 // This one's in trouble, so we'll generate a report for it 8402 // crashes are higher priority (in case there's a crash *and* an anr) 8403 ActivityManager.ProcessErrorStateInfo report = null; 8404 if (app.crashing) { 8405 report = app.crashingReport; 8406 } else if (app.notResponding) { 8407 report = app.notRespondingReport; 8408 } 8409 8410 if (report != null) { 8411 if (errList == null) { 8412 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8413 } 8414 errList.add(report); 8415 } else { 8416 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8417 " crashing = " + app.crashing + 8418 " notResponding = " + app.notResponding); 8419 } 8420 } 8421 } 8422 } 8423 8424 return errList; 8425 } 8426 8427 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8428 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8429 if (currApp != null) { 8430 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8431 } 8432 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8433 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8434 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8435 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8436 if (currApp != null) { 8437 currApp.lru = 0; 8438 } 8439 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8440 } else if (adj >= ProcessList.SERVICE_ADJ) { 8441 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8442 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8443 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8444 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8445 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8446 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8447 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8448 } else { 8449 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8450 } 8451 } 8452 8453 private void fillInProcMemInfo(ProcessRecord app, 8454 ActivityManager.RunningAppProcessInfo outInfo) { 8455 outInfo.pid = app.pid; 8456 outInfo.uid = app.info.uid; 8457 if (mHeavyWeightProcess == app) { 8458 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8459 } 8460 if (app.persistent) { 8461 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8462 } 8463 outInfo.lastTrimLevel = app.trimMemoryLevel; 8464 int adj = app.curAdj; 8465 outInfo.importance = oomAdjToImportance(adj, outInfo); 8466 outInfo.importanceReasonCode = app.adjTypeCode; 8467 } 8468 8469 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8470 enforceNotIsolatedCaller("getRunningAppProcesses"); 8471 // Lazy instantiation of list 8472 List<ActivityManager.RunningAppProcessInfo> runList = null; 8473 synchronized (this) { 8474 // Iterate across all processes 8475 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8476 ProcessRecord app = mLruProcesses.get(i); 8477 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8478 // Generate process state info for running application 8479 ActivityManager.RunningAppProcessInfo currApp = 8480 new ActivityManager.RunningAppProcessInfo(app.processName, 8481 app.pid, app.getPackageList()); 8482 fillInProcMemInfo(app, currApp); 8483 if (app.adjSource instanceof ProcessRecord) { 8484 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8485 currApp.importanceReasonImportance = oomAdjToImportance( 8486 app.adjSourceOom, null); 8487 } else if (app.adjSource instanceof ActivityRecord) { 8488 ActivityRecord r = (ActivityRecord)app.adjSource; 8489 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8490 } 8491 if (app.adjTarget instanceof ComponentName) { 8492 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8493 } 8494 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8495 // + " lru=" + currApp.lru); 8496 if (runList == null) { 8497 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8498 } 8499 runList.add(currApp); 8500 } 8501 } 8502 } 8503 return runList; 8504 } 8505 8506 public List<ApplicationInfo> getRunningExternalApplications() { 8507 enforceNotIsolatedCaller("getRunningExternalApplications"); 8508 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8509 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8510 if (runningApps != null && runningApps.size() > 0) { 8511 Set<String> extList = new HashSet<String>(); 8512 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8513 if (app.pkgList != null) { 8514 for (String pkg : app.pkgList) { 8515 extList.add(pkg); 8516 } 8517 } 8518 } 8519 IPackageManager pm = AppGlobals.getPackageManager(); 8520 for (String pkg : extList) { 8521 try { 8522 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8523 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8524 retList.add(info); 8525 } 8526 } catch (RemoteException e) { 8527 } 8528 } 8529 } 8530 return retList; 8531 } 8532 8533 @Override 8534 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8535 enforceNotIsolatedCaller("getMyMemoryState"); 8536 synchronized (this) { 8537 ProcessRecord proc; 8538 synchronized (mPidsSelfLocked) { 8539 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8540 } 8541 fillInProcMemInfo(proc, outInfo); 8542 } 8543 } 8544 8545 @Override 8546 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8547 if (checkCallingPermission(android.Manifest.permission.DUMP) 8548 != PackageManager.PERMISSION_GRANTED) { 8549 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8550 + Binder.getCallingPid() 8551 + ", uid=" + Binder.getCallingUid() 8552 + " without permission " 8553 + android.Manifest.permission.DUMP); 8554 return; 8555 } 8556 8557 boolean dumpAll = false; 8558 boolean dumpClient = false; 8559 String dumpPackage = null; 8560 8561 int opti = 0; 8562 while (opti < args.length) { 8563 String opt = args[opti]; 8564 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8565 break; 8566 } 8567 opti++; 8568 if ("-a".equals(opt)) { 8569 dumpAll = true; 8570 } else if ("-c".equals(opt)) { 8571 dumpClient = true; 8572 } else if ("-h".equals(opt)) { 8573 pw.println("Activity manager dump options:"); 8574 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8575 pw.println(" cmd may be one of:"); 8576 pw.println(" a[ctivities]: activity stack state"); 8577 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8578 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8579 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8580 pw.println(" o[om]: out of memory management"); 8581 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8582 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8583 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8584 pw.println(" service [COMP_SPEC]: service client-side state"); 8585 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8586 pw.println(" all: dump all activities"); 8587 pw.println(" top: dump the top activity"); 8588 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8589 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8590 pw.println(" a partial substring in a component name, a"); 8591 pw.println(" hex object identifier."); 8592 pw.println(" -a: include all available server state."); 8593 pw.println(" -c: include client state."); 8594 return; 8595 } else { 8596 pw.println("Unknown argument: " + opt + "; use -h for help"); 8597 } 8598 } 8599 8600 long origId = Binder.clearCallingIdentity(); 8601 boolean more = false; 8602 // Is the caller requesting to dump a particular piece of data? 8603 if (opti < args.length) { 8604 String cmd = args[opti]; 8605 opti++; 8606 if ("activities".equals(cmd) || "a".equals(cmd)) { 8607 synchronized (this) { 8608 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8609 } 8610 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8611 String[] newArgs; 8612 String name; 8613 if (opti >= args.length) { 8614 name = null; 8615 newArgs = EMPTY_STRING_ARRAY; 8616 } else { 8617 name = args[opti]; 8618 opti++; 8619 newArgs = new String[args.length - opti]; 8620 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8621 args.length - opti); 8622 } 8623 synchronized (this) { 8624 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8625 } 8626 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8627 String[] newArgs; 8628 String name; 8629 if (opti >= args.length) { 8630 name = null; 8631 newArgs = EMPTY_STRING_ARRAY; 8632 } else { 8633 name = args[opti]; 8634 opti++; 8635 newArgs = new String[args.length - opti]; 8636 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8637 args.length - opti); 8638 } 8639 synchronized (this) { 8640 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8641 } 8642 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8643 String[] newArgs; 8644 String name; 8645 if (opti >= args.length) { 8646 name = null; 8647 newArgs = EMPTY_STRING_ARRAY; 8648 } else { 8649 name = args[opti]; 8650 opti++; 8651 newArgs = new String[args.length - opti]; 8652 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8653 args.length - opti); 8654 } 8655 synchronized (this) { 8656 dumpProcessesLocked(fd, pw, args, opti, true, name); 8657 } 8658 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8659 synchronized (this) { 8660 dumpOomLocked(fd, pw, args, opti, true); 8661 } 8662 } else if ("provider".equals(cmd)) { 8663 String[] newArgs; 8664 String name; 8665 if (opti >= args.length) { 8666 name = null; 8667 newArgs = EMPTY_STRING_ARRAY; 8668 } else { 8669 name = args[opti]; 8670 opti++; 8671 newArgs = new String[args.length - opti]; 8672 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8673 } 8674 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8675 pw.println("No providers match: " + name); 8676 pw.println("Use -h for help."); 8677 } 8678 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8679 synchronized (this) { 8680 dumpProvidersLocked(fd, pw, args, opti, true, null); 8681 } 8682 } else if ("service".equals(cmd)) { 8683 String[] newArgs; 8684 String name; 8685 if (opti >= args.length) { 8686 name = null; 8687 newArgs = EMPTY_STRING_ARRAY; 8688 } else { 8689 name = args[opti]; 8690 opti++; 8691 newArgs = new String[args.length - opti]; 8692 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8693 args.length - opti); 8694 } 8695 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8696 pw.println("No services match: " + name); 8697 pw.println("Use -h for help."); 8698 } 8699 } else if ("package".equals(cmd)) { 8700 String[] newArgs; 8701 if (opti >= args.length) { 8702 pw.println("package: no package name specified"); 8703 pw.println("Use -h for help."); 8704 } else { 8705 dumpPackage = args[opti]; 8706 opti++; 8707 newArgs = new String[args.length - opti]; 8708 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8709 args.length - opti); 8710 args = newArgs; 8711 opti = 0; 8712 more = true; 8713 } 8714 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8715 synchronized (this) { 8716 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8717 } 8718 } else { 8719 // Dumping a single activity? 8720 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8721 pw.println("Bad activity command, or no activities match: " + cmd); 8722 pw.println("Use -h for help."); 8723 } 8724 } 8725 if (!more) { 8726 Binder.restoreCallingIdentity(origId); 8727 return; 8728 } 8729 } 8730 8731 // No piece of data specified, dump everything. 8732 synchronized (this) { 8733 boolean needSep; 8734 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8735 if (needSep) { 8736 pw.println(" "); 8737 } 8738 if (dumpAll) { 8739 pw.println("-------------------------------------------------------------------------------"); 8740 } 8741 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8742 if (needSep) { 8743 pw.println(" "); 8744 } 8745 if (dumpAll) { 8746 pw.println("-------------------------------------------------------------------------------"); 8747 } 8748 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8749 if (needSep) { 8750 pw.println(" "); 8751 } 8752 if (dumpAll) { 8753 pw.println("-------------------------------------------------------------------------------"); 8754 } 8755 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8756 if (needSep) { 8757 pw.println(" "); 8758 } 8759 if (dumpAll) { 8760 pw.println("-------------------------------------------------------------------------------"); 8761 } 8762 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8763 if (needSep) { 8764 pw.println(" "); 8765 } 8766 if (dumpAll) { 8767 pw.println("-------------------------------------------------------------------------------"); 8768 } 8769 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8770 } 8771 Binder.restoreCallingIdentity(origId); 8772 } 8773 8774 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8775 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8776 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8777 pw.println(" Main stack:"); 8778 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8779 dumpPackage); 8780 pw.println(" "); 8781 pw.println(" Running activities (most recent first):"); 8782 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8783 dumpPackage); 8784 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8785 pw.println(" "); 8786 pw.println(" Activities waiting for another to become visible:"); 8787 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8788 !dumpAll, false, dumpPackage); 8789 } 8790 if (mMainStack.mStoppingActivities.size() > 0) { 8791 pw.println(" "); 8792 pw.println(" Activities waiting to stop:"); 8793 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8794 !dumpAll, false, dumpPackage); 8795 } 8796 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8797 pw.println(" "); 8798 pw.println(" Activities waiting to sleep:"); 8799 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8800 !dumpAll, false, dumpPackage); 8801 } 8802 if (mMainStack.mFinishingActivities.size() > 0) { 8803 pw.println(" "); 8804 pw.println(" Activities waiting to finish:"); 8805 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8806 !dumpAll, false, dumpPackage); 8807 } 8808 8809 pw.println(" "); 8810 if (mMainStack.mPausingActivity != null) { 8811 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8812 } 8813 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8814 pw.println(" mFocusedActivity: " + mFocusedActivity); 8815 if (dumpAll) { 8816 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8817 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8818 pw.println(" mDismissKeyguardOnNextActivity: " 8819 + mMainStack.mDismissKeyguardOnNextActivity); 8820 } 8821 8822 if (mRecentTasks.size() > 0) { 8823 pw.println(); 8824 pw.println(" Recent tasks:"); 8825 8826 final int N = mRecentTasks.size(); 8827 for (int i=0; i<N; i++) { 8828 TaskRecord tr = mRecentTasks.get(i); 8829 if (dumpPackage != null) { 8830 if (tr.realActivity == null || 8831 !dumpPackage.equals(tr.realActivity)) { 8832 continue; 8833 } 8834 } 8835 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8836 pw.println(tr); 8837 if (dumpAll) { 8838 mRecentTasks.get(i).dump(pw, " "); 8839 } 8840 } 8841 } 8842 8843 if (dumpAll) { 8844 pw.println(" "); 8845 pw.println(" mCurTask: " + mCurTask); 8846 } 8847 8848 return true; 8849 } 8850 8851 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8852 int opti, boolean dumpAll, String dumpPackage) { 8853 boolean needSep = false; 8854 int numPers = 0; 8855 8856 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8857 8858 if (dumpAll) { 8859 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8860 final int NA = procs.size(); 8861 for (int ia=0; ia<NA; ia++) { 8862 ProcessRecord r = procs.valueAt(ia); 8863 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8864 continue; 8865 } 8866 if (!needSep) { 8867 pw.println(" All known processes:"); 8868 needSep = true; 8869 } 8870 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8871 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8872 pw.print(" "); pw.println(r); 8873 r.dump(pw, " "); 8874 if (r.persistent) { 8875 numPers++; 8876 } 8877 } 8878 } 8879 } 8880 8881 if (mIsolatedProcesses.size() > 0) { 8882 if (needSep) pw.println(" "); 8883 needSep = true; 8884 pw.println(" Isolated process list (sorted by uid):"); 8885 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8886 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8887 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8888 continue; 8889 } 8890 pw.println(String.format("%sIsolated #%2d: %s", 8891 " ", i, r.toString())); 8892 } 8893 } 8894 8895 if (mLruProcesses.size() > 0) { 8896 if (needSep) pw.println(" "); 8897 needSep = true; 8898 pw.println(" Process LRU list (sorted by oom_adj):"); 8899 dumpProcessOomList(pw, this, mLruProcesses, " ", 8900 "Proc", "PERS", false, dumpPackage); 8901 needSep = true; 8902 } 8903 8904 if (dumpAll) { 8905 synchronized (mPidsSelfLocked) { 8906 boolean printed = false; 8907 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8908 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8909 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8910 continue; 8911 } 8912 if (!printed) { 8913 if (needSep) pw.println(" "); 8914 needSep = true; 8915 pw.println(" PID mappings:"); 8916 printed = true; 8917 } 8918 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8919 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8920 } 8921 } 8922 } 8923 8924 if (mForegroundProcesses.size() > 0) { 8925 synchronized (mPidsSelfLocked) { 8926 boolean printed = false; 8927 for (int i=0; i<mForegroundProcesses.size(); i++) { 8928 ProcessRecord r = mPidsSelfLocked.get( 8929 mForegroundProcesses.valueAt(i).pid); 8930 if (dumpPackage != null && (r == null 8931 || !dumpPackage.equals(r.info.packageName))) { 8932 continue; 8933 } 8934 if (!printed) { 8935 if (needSep) pw.println(" "); 8936 needSep = true; 8937 pw.println(" Foreground Processes:"); 8938 printed = true; 8939 } 8940 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8941 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8942 } 8943 } 8944 } 8945 8946 if (mPersistentStartingProcesses.size() > 0) { 8947 if (needSep) pw.println(" "); 8948 needSep = true; 8949 pw.println(" Persisent processes that are starting:"); 8950 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8951 "Starting Norm", "Restarting PERS", dumpPackage); 8952 } 8953 8954 if (mRemovedProcesses.size() > 0) { 8955 if (needSep) pw.println(" "); 8956 needSep = true; 8957 pw.println(" Processes that are being removed:"); 8958 dumpProcessList(pw, this, mRemovedProcesses, " ", 8959 "Removed Norm", "Removed PERS", dumpPackage); 8960 } 8961 8962 if (mProcessesOnHold.size() > 0) { 8963 if (needSep) pw.println(" "); 8964 needSep = true; 8965 pw.println(" Processes that are on old until the system is ready:"); 8966 dumpProcessList(pw, this, mProcessesOnHold, " ", 8967 "OnHold Norm", "OnHold PERS", dumpPackage); 8968 } 8969 8970 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8971 8972 if (mProcessCrashTimes.getMap().size() > 0) { 8973 boolean printed = false; 8974 long now = SystemClock.uptimeMillis(); 8975 for (Map.Entry<String, SparseArray<Long>> procs 8976 : mProcessCrashTimes.getMap().entrySet()) { 8977 String pname = procs.getKey(); 8978 SparseArray<Long> uids = procs.getValue(); 8979 final int N = uids.size(); 8980 for (int i=0; i<N; i++) { 8981 int puid = uids.keyAt(i); 8982 ProcessRecord r = mProcessNames.get(pname, puid); 8983 if (dumpPackage != null && (r == null 8984 || !dumpPackage.equals(r.info.packageName))) { 8985 continue; 8986 } 8987 if (!printed) { 8988 if (needSep) pw.println(" "); 8989 needSep = true; 8990 pw.println(" Time since processes crashed:"); 8991 printed = true; 8992 } 8993 pw.print(" Process "); pw.print(pname); 8994 pw.print(" uid "); pw.print(puid); 8995 pw.print(": last crashed "); 8996 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8997 pw.println(" ago"); 8998 } 8999 } 9000 } 9001 9002 if (mBadProcesses.getMap().size() > 0) { 9003 boolean printed = false; 9004 for (Map.Entry<String, SparseArray<Long>> procs 9005 : mBadProcesses.getMap().entrySet()) { 9006 String pname = procs.getKey(); 9007 SparseArray<Long> uids = procs.getValue(); 9008 final int N = uids.size(); 9009 for (int i=0; i<N; i++) { 9010 int puid = uids.keyAt(i); 9011 ProcessRecord r = mProcessNames.get(pname, puid); 9012 if (dumpPackage != null && (r == null 9013 || !dumpPackage.equals(r.info.packageName))) { 9014 continue; 9015 } 9016 if (!printed) { 9017 if (needSep) pw.println(" "); 9018 needSep = true; 9019 pw.println(" Bad processes:"); 9020 } 9021 pw.print(" Bad process "); pw.print(pname); 9022 pw.print(" uid "); pw.print(puid); 9023 pw.print(": crashed at time "); 9024 pw.println(uids.valueAt(i)); 9025 } 9026 } 9027 } 9028 9029 pw.println(); 9030 pw.println(" mHomeProcess: " + mHomeProcess); 9031 pw.println(" mPreviousProcess: " + mPreviousProcess); 9032 if (dumpAll) { 9033 StringBuilder sb = new StringBuilder(128); 9034 sb.append(" mPreviousProcessVisibleTime: "); 9035 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9036 pw.println(sb); 9037 } 9038 if (mHeavyWeightProcess != null) { 9039 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9040 } 9041 pw.println(" mConfiguration: " + mConfiguration); 9042 if (dumpAll) { 9043 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9044 if (mCompatModePackages.getPackages().size() > 0) { 9045 boolean printed = false; 9046 for (Map.Entry<String, Integer> entry 9047 : mCompatModePackages.getPackages().entrySet()) { 9048 String pkg = entry.getKey(); 9049 int mode = entry.getValue(); 9050 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9051 continue; 9052 } 9053 if (!printed) { 9054 pw.println(" mScreenCompatPackages:"); 9055 printed = true; 9056 } 9057 pw.print(" "); pw.print(pkg); pw.print(": "); 9058 pw.print(mode); pw.println(); 9059 } 9060 } 9061 } 9062 if (mSleeping || mWentToSleep || mLockScreenShown) { 9063 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9064 + " mLockScreenShown " + mLockScreenShown); 9065 } 9066 if (mShuttingDown) { 9067 pw.println(" mShuttingDown=" + mShuttingDown); 9068 } 9069 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9070 || mOrigWaitForDebugger) { 9071 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9072 + " mDebugTransient=" + mDebugTransient 9073 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9074 } 9075 if (mOpenGlTraceApp != null) { 9076 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9077 } 9078 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9079 || mProfileFd != null) { 9080 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9081 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9082 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9083 + mAutoStopProfiler); 9084 } 9085 if (mAlwaysFinishActivities || mController != null) { 9086 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9087 + " mController=" + mController); 9088 } 9089 if (dumpAll) { 9090 pw.println(" Total persistent processes: " + numPers); 9091 pw.println(" mStartRunning=" + mStartRunning 9092 + " mProcessesReady=" + mProcessesReady 9093 + " mSystemReady=" + mSystemReady); 9094 pw.println(" mBooting=" + mBooting 9095 + " mBooted=" + mBooted 9096 + " mFactoryTest=" + mFactoryTest); 9097 pw.print(" mLastPowerCheckRealtime="); 9098 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9099 pw.println(""); 9100 pw.print(" mLastPowerCheckUptime="); 9101 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9102 pw.println(""); 9103 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9104 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9105 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9106 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9107 + " mNumHiddenProcs=" + mNumHiddenProcs 9108 + " mNumServiceProcs=" + mNumServiceProcs 9109 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9110 } 9111 9112 return true; 9113 } 9114 9115 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9116 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9117 if (mProcessesToGc.size() > 0) { 9118 boolean printed = false; 9119 long now = SystemClock.uptimeMillis(); 9120 for (int i=0; i<mProcessesToGc.size(); i++) { 9121 ProcessRecord proc = mProcessesToGc.get(i); 9122 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9123 continue; 9124 } 9125 if (!printed) { 9126 if (needSep) pw.println(" "); 9127 needSep = true; 9128 pw.println(" Processes that are waiting to GC:"); 9129 printed = true; 9130 } 9131 pw.print(" Process "); pw.println(proc); 9132 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9133 pw.print(", last gced="); 9134 pw.print(now-proc.lastRequestedGc); 9135 pw.print(" ms ago, last lowMem="); 9136 pw.print(now-proc.lastLowMemory); 9137 pw.println(" ms ago"); 9138 9139 } 9140 } 9141 return needSep; 9142 } 9143 9144 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9145 int opti, boolean dumpAll) { 9146 boolean needSep = false; 9147 9148 if (mLruProcesses.size() > 0) { 9149 if (needSep) pw.println(" "); 9150 needSep = true; 9151 pw.println(" OOM levels:"); 9152 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9153 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9154 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9155 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9156 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9157 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9158 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9159 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9160 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9161 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9162 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9163 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9164 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9165 9166 if (needSep) pw.println(" "); 9167 needSep = true; 9168 pw.println(" Process OOM control:"); 9169 dumpProcessOomList(pw, this, mLruProcesses, " ", 9170 "Proc", "PERS", true, null); 9171 needSep = true; 9172 } 9173 9174 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9175 9176 pw.println(); 9177 pw.println(" mHomeProcess: " + mHomeProcess); 9178 pw.println(" mPreviousProcess: " + mPreviousProcess); 9179 if (mHeavyWeightProcess != null) { 9180 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9181 } 9182 9183 return true; 9184 } 9185 9186 /** 9187 * There are three ways to call this: 9188 * - no provider specified: dump all the providers 9189 * - a flattened component name that matched an existing provider was specified as the 9190 * first arg: dump that one provider 9191 * - the first arg isn't the flattened component name of an existing provider: 9192 * dump all providers whose component contains the first arg as a substring 9193 */ 9194 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9195 int opti, boolean dumpAll) { 9196 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9197 } 9198 9199 static class ItemMatcher { 9200 ArrayList<ComponentName> components; 9201 ArrayList<String> strings; 9202 ArrayList<Integer> objects; 9203 boolean all; 9204 9205 ItemMatcher() { 9206 all = true; 9207 } 9208 9209 void build(String name) { 9210 ComponentName componentName = ComponentName.unflattenFromString(name); 9211 if (componentName != null) { 9212 if (components == null) { 9213 components = new ArrayList<ComponentName>(); 9214 } 9215 components.add(componentName); 9216 all = false; 9217 } else { 9218 int objectId = 0; 9219 // Not a '/' separated full component name; maybe an object ID? 9220 try { 9221 objectId = Integer.parseInt(name, 16); 9222 if (objects == null) { 9223 objects = new ArrayList<Integer>(); 9224 } 9225 objects.add(objectId); 9226 all = false; 9227 } catch (RuntimeException e) { 9228 // Not an integer; just do string match. 9229 if (strings == null) { 9230 strings = new ArrayList<String>(); 9231 } 9232 strings.add(name); 9233 all = false; 9234 } 9235 } 9236 } 9237 9238 int build(String[] args, int opti) { 9239 for (; opti<args.length; opti++) { 9240 String name = args[opti]; 9241 if ("--".equals(name)) { 9242 return opti+1; 9243 } 9244 build(name); 9245 } 9246 return opti; 9247 } 9248 9249 boolean match(Object object, ComponentName comp) { 9250 if (all) { 9251 return true; 9252 } 9253 if (components != null) { 9254 for (int i=0; i<components.size(); i++) { 9255 if (components.get(i).equals(comp)) { 9256 return true; 9257 } 9258 } 9259 } 9260 if (objects != null) { 9261 for (int i=0; i<objects.size(); i++) { 9262 if (System.identityHashCode(object) == objects.get(i)) { 9263 return true; 9264 } 9265 } 9266 } 9267 if (strings != null) { 9268 String flat = comp.flattenToString(); 9269 for (int i=0; i<strings.size(); i++) { 9270 if (flat.contains(strings.get(i))) { 9271 return true; 9272 } 9273 } 9274 } 9275 return false; 9276 } 9277 } 9278 9279 /** 9280 * There are three things that cmd can be: 9281 * - a flattened component name that matches an existing activity 9282 * - the cmd arg isn't the flattened component name of an existing activity: 9283 * dump all activity whose component contains the cmd as a substring 9284 * - A hex number of the ActivityRecord object instance. 9285 */ 9286 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9287 int opti, boolean dumpAll) { 9288 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9289 9290 if ("all".equals(name)) { 9291 synchronized (this) { 9292 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9293 activities.add(r1); 9294 } 9295 } 9296 } else if ("top".equals(name)) { 9297 synchronized (this) { 9298 final int N = mMainStack.mHistory.size(); 9299 if (N > 0) { 9300 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9301 } 9302 } 9303 } else { 9304 ItemMatcher matcher = new ItemMatcher(); 9305 matcher.build(name); 9306 9307 synchronized (this) { 9308 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9309 if (matcher.match(r1, r1.intent.getComponent())) { 9310 activities.add(r1); 9311 } 9312 } 9313 } 9314 } 9315 9316 if (activities.size() <= 0) { 9317 return false; 9318 } 9319 9320 String[] newArgs = new String[args.length - opti]; 9321 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9322 9323 TaskRecord lastTask = null; 9324 boolean needSep = false; 9325 for (int i=activities.size()-1; i>=0; i--) { 9326 ActivityRecord r = (ActivityRecord)activities.get(i); 9327 if (needSep) { 9328 pw.println(); 9329 } 9330 needSep = true; 9331 synchronized (this) { 9332 if (lastTask != r.task) { 9333 lastTask = r.task; 9334 pw.print("TASK "); pw.print(lastTask.affinity); 9335 pw.print(" id="); pw.println(lastTask.taskId); 9336 if (dumpAll) { 9337 lastTask.dump(pw, " "); 9338 } 9339 } 9340 } 9341 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9342 } 9343 return true; 9344 } 9345 9346 /** 9347 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9348 * there is a thread associated with the activity. 9349 */ 9350 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9351 final ActivityRecord r, String[] args, boolean dumpAll) { 9352 String innerPrefix = prefix + " "; 9353 synchronized (this) { 9354 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9355 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9356 pw.print(" pid="); 9357 if (r.app != null) pw.println(r.app.pid); 9358 else pw.println("(not running)"); 9359 if (dumpAll) { 9360 r.dump(pw, innerPrefix); 9361 } 9362 } 9363 if (r.app != null && r.app.thread != null) { 9364 // flush anything that is already in the PrintWriter since the thread is going 9365 // to write to the file descriptor directly 9366 pw.flush(); 9367 try { 9368 TransferPipe tp = new TransferPipe(); 9369 try { 9370 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9371 r.appToken, innerPrefix, args); 9372 tp.go(fd); 9373 } finally { 9374 tp.kill(); 9375 } 9376 } catch (IOException e) { 9377 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9378 } catch (RemoteException e) { 9379 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9380 } 9381 } 9382 } 9383 9384 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9385 int opti, boolean dumpAll, String dumpPackage) { 9386 boolean needSep = false; 9387 9388 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9389 if (dumpAll) { 9390 if (mRegisteredReceivers.size() > 0) { 9391 boolean printed = false; 9392 Iterator it = mRegisteredReceivers.values().iterator(); 9393 while (it.hasNext()) { 9394 ReceiverList r = (ReceiverList)it.next(); 9395 if (dumpPackage != null && (r.app == null || 9396 !dumpPackage.equals(r.app.info.packageName))) { 9397 continue; 9398 } 9399 if (!printed) { 9400 pw.println(" Registered Receivers:"); 9401 needSep = true; 9402 printed = true; 9403 } 9404 pw.print(" * "); pw.println(r); 9405 r.dump(pw, " "); 9406 } 9407 } 9408 9409 if (mReceiverResolver.dump(pw, needSep ? 9410 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9411 " ", dumpPackage, false)) { 9412 needSep = true; 9413 } 9414 } 9415 9416 for (BroadcastQueue q : mBroadcastQueues) { 9417 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9418 } 9419 9420 needSep = true; 9421 9422 if (mStickyBroadcasts != null && dumpPackage == null) { 9423 if (needSep) { 9424 pw.println(); 9425 } 9426 needSep = true; 9427 pw.println(" Sticky broadcasts:"); 9428 StringBuilder sb = new StringBuilder(128); 9429 for (Map.Entry<String, ArrayList<Intent>> ent 9430 : mStickyBroadcasts.entrySet()) { 9431 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9432 if (dumpAll) { 9433 pw.println(":"); 9434 ArrayList<Intent> intents = ent.getValue(); 9435 final int N = intents.size(); 9436 for (int i=0; i<N; i++) { 9437 sb.setLength(0); 9438 sb.append(" Intent: "); 9439 intents.get(i).toShortString(sb, false, true, false, false); 9440 pw.println(sb.toString()); 9441 Bundle bundle = intents.get(i).getExtras(); 9442 if (bundle != null) { 9443 pw.print(" "); 9444 pw.println(bundle.toString()); 9445 } 9446 } 9447 } else { 9448 pw.println(""); 9449 } 9450 } 9451 needSep = true; 9452 } 9453 9454 if (dumpAll) { 9455 pw.println(); 9456 for (BroadcastQueue queue : mBroadcastQueues) { 9457 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9458 + queue.mBroadcastsScheduled); 9459 } 9460 pw.println(" mHandler:"); 9461 mHandler.dump(new PrintWriterPrinter(pw), " "); 9462 needSep = true; 9463 } 9464 9465 return needSep; 9466 } 9467 9468 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9469 int opti, boolean dumpAll, String dumpPackage) { 9470 boolean needSep = true; 9471 9472 ItemMatcher matcher = new ItemMatcher(); 9473 matcher.build(args, opti); 9474 9475 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9476 9477 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9478 9479 if (mLaunchingProviders.size() > 0) { 9480 boolean printed = false; 9481 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9482 ContentProviderRecord r = mLaunchingProviders.get(i); 9483 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9484 continue; 9485 } 9486 if (!printed) { 9487 if (needSep) pw.println(" "); 9488 needSep = true; 9489 pw.println(" Launching content providers:"); 9490 printed = true; 9491 } 9492 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9493 pw.println(r); 9494 } 9495 } 9496 9497 if (mGrantedUriPermissions.size() > 0) { 9498 if (needSep) pw.println(); 9499 needSep = true; 9500 pw.println("Granted Uri Permissions:"); 9501 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9502 int uid = mGrantedUriPermissions.keyAt(i); 9503 HashMap<Uri, UriPermission> perms 9504 = mGrantedUriPermissions.valueAt(i); 9505 pw.print(" * UID "); pw.print(uid); 9506 pw.println(" holds:"); 9507 for (UriPermission perm : perms.values()) { 9508 pw.print(" "); pw.println(perm); 9509 if (dumpAll) { 9510 perm.dump(pw, " "); 9511 } 9512 } 9513 } 9514 needSep = true; 9515 } 9516 9517 return needSep; 9518 } 9519 9520 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9521 int opti, boolean dumpAll, String dumpPackage) { 9522 boolean needSep = false; 9523 9524 if (mIntentSenderRecords.size() > 0) { 9525 boolean printed = false; 9526 Iterator<WeakReference<PendingIntentRecord>> it 9527 = mIntentSenderRecords.values().iterator(); 9528 while (it.hasNext()) { 9529 WeakReference<PendingIntentRecord> ref = it.next(); 9530 PendingIntentRecord rec = ref != null ? ref.get(): null; 9531 if (dumpPackage != null && (rec == null 9532 || !dumpPackage.equals(rec.key.packageName))) { 9533 continue; 9534 } 9535 if (!printed) { 9536 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9537 printed = true; 9538 } 9539 needSep = true; 9540 if (rec != null) { 9541 pw.print(" * "); pw.println(rec); 9542 if (dumpAll) { 9543 rec.dump(pw, " "); 9544 } 9545 } else { 9546 pw.print(" * "); pw.println(ref); 9547 } 9548 } 9549 } 9550 9551 return needSep; 9552 } 9553 9554 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9555 String prefix, String label, boolean complete, boolean brief, boolean client, 9556 String dumpPackage) { 9557 TaskRecord lastTask = null; 9558 boolean needNL = false; 9559 final String innerPrefix = prefix + " "; 9560 final String[] args = new String[0]; 9561 for (int i=list.size()-1; i>=0; i--) { 9562 final ActivityRecord r = (ActivityRecord)list.get(i); 9563 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9564 continue; 9565 } 9566 final boolean full = !brief && (complete || !r.isInHistory()); 9567 if (needNL) { 9568 pw.println(" "); 9569 needNL = false; 9570 } 9571 if (lastTask != r.task) { 9572 lastTask = r.task; 9573 pw.print(prefix); 9574 pw.print(full ? "* " : " "); 9575 pw.println(lastTask); 9576 if (full) { 9577 lastTask.dump(pw, prefix + " "); 9578 } else if (complete) { 9579 // Complete + brief == give a summary. Isn't that obvious?!? 9580 if (lastTask.intent != null) { 9581 pw.print(prefix); pw.print(" "); 9582 pw.println(lastTask.intent.toInsecureStringWithClip()); 9583 } 9584 } 9585 } 9586 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9587 pw.print(" #"); pw.print(i); pw.print(": "); 9588 pw.println(r); 9589 if (full) { 9590 r.dump(pw, innerPrefix); 9591 } else if (complete) { 9592 // Complete + brief == give a summary. Isn't that obvious?!? 9593 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9594 if (r.app != null) { 9595 pw.print(innerPrefix); pw.println(r.app); 9596 } 9597 } 9598 if (client && r.app != null && r.app.thread != null) { 9599 // flush anything that is already in the PrintWriter since the thread is going 9600 // to write to the file descriptor directly 9601 pw.flush(); 9602 try { 9603 TransferPipe tp = new TransferPipe(); 9604 try { 9605 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9606 r.appToken, innerPrefix, args); 9607 // Short timeout, since blocking here can 9608 // deadlock with the application. 9609 tp.go(fd, 2000); 9610 } finally { 9611 tp.kill(); 9612 } 9613 } catch (IOException e) { 9614 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9615 } catch (RemoteException e) { 9616 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9617 } 9618 needNL = true; 9619 } 9620 } 9621 } 9622 9623 private static String buildOomTag(String prefix, String space, int val, int base) { 9624 if (val == base) { 9625 if (space == null) return prefix; 9626 return prefix + " "; 9627 } 9628 return prefix + "+" + Integer.toString(val-base); 9629 } 9630 9631 private static final int dumpProcessList(PrintWriter pw, 9632 ActivityManagerService service, List list, 9633 String prefix, String normalLabel, String persistentLabel, 9634 String dumpPackage) { 9635 int numPers = 0; 9636 final int N = list.size()-1; 9637 for (int i=N; i>=0; i--) { 9638 ProcessRecord r = (ProcessRecord)list.get(i); 9639 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9640 continue; 9641 } 9642 pw.println(String.format("%s%s #%2d: %s", 9643 prefix, (r.persistent ? persistentLabel : normalLabel), 9644 i, r.toString())); 9645 if (r.persistent) { 9646 numPers++; 9647 } 9648 } 9649 return numPers; 9650 } 9651 9652 private static final boolean dumpProcessOomList(PrintWriter pw, 9653 ActivityManagerService service, List<ProcessRecord> origList, 9654 String prefix, String normalLabel, String persistentLabel, 9655 boolean inclDetails, String dumpPackage) { 9656 9657 ArrayList<Pair<ProcessRecord, Integer>> list 9658 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9659 for (int i=0; i<origList.size(); i++) { 9660 ProcessRecord r = origList.get(i); 9661 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9662 continue; 9663 } 9664 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9665 } 9666 9667 if (list.size() <= 0) { 9668 return false; 9669 } 9670 9671 Comparator<Pair<ProcessRecord, Integer>> comparator 9672 = new Comparator<Pair<ProcessRecord, Integer>>() { 9673 @Override 9674 public int compare(Pair<ProcessRecord, Integer> object1, 9675 Pair<ProcessRecord, Integer> object2) { 9676 if (object1.first.setAdj != object2.first.setAdj) { 9677 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9678 } 9679 if (object1.second.intValue() != object2.second.intValue()) { 9680 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9681 } 9682 return 0; 9683 } 9684 }; 9685 9686 Collections.sort(list, comparator); 9687 9688 final long curRealtime = SystemClock.elapsedRealtime(); 9689 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9690 final long curUptime = SystemClock.uptimeMillis(); 9691 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9692 9693 for (int i=list.size()-1; i>=0; i--) { 9694 ProcessRecord r = list.get(i).first; 9695 String oomAdj; 9696 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9697 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9698 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9699 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9700 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9701 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9702 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9703 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9704 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9705 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9706 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9707 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9708 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9709 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9710 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9711 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9712 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9713 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9714 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9715 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9716 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9717 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9718 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9719 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9720 } else { 9721 oomAdj = Integer.toString(r.setAdj); 9722 } 9723 String schedGroup; 9724 switch (r.setSchedGroup) { 9725 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9726 schedGroup = "B"; 9727 break; 9728 case Process.THREAD_GROUP_DEFAULT: 9729 schedGroup = "F"; 9730 break; 9731 default: 9732 schedGroup = Integer.toString(r.setSchedGroup); 9733 break; 9734 } 9735 String foreground; 9736 if (r.foregroundActivities) { 9737 foreground = "A"; 9738 } else if (r.foregroundServices) { 9739 foreground = "S"; 9740 } else { 9741 foreground = " "; 9742 } 9743 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9744 prefix, (r.persistent ? persistentLabel : normalLabel), 9745 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9746 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9747 if (r.adjSource != null || r.adjTarget != null) { 9748 pw.print(prefix); 9749 pw.print(" "); 9750 if (r.adjTarget instanceof ComponentName) { 9751 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9752 } else if (r.adjTarget != null) { 9753 pw.print(r.adjTarget.toString()); 9754 } else { 9755 pw.print("{null}"); 9756 } 9757 pw.print("<="); 9758 if (r.adjSource instanceof ProcessRecord) { 9759 pw.print("Proc{"); 9760 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9761 pw.println("}"); 9762 } else if (r.adjSource != null) { 9763 pw.println(r.adjSource.toString()); 9764 } else { 9765 pw.println("{null}"); 9766 } 9767 } 9768 if (inclDetails) { 9769 pw.print(prefix); 9770 pw.print(" "); 9771 pw.print("oom: max="); pw.print(r.maxAdj); 9772 pw.print(" hidden="); pw.print(r.hiddenAdj); 9773 pw.print(" empty="); pw.print(r.emptyAdj); 9774 pw.print(" curRaw="); pw.print(r.curRawAdj); 9775 pw.print(" setRaw="); pw.print(r.setRawAdj); 9776 pw.print(" cur="); pw.print(r.curAdj); 9777 pw.print(" set="); pw.println(r.setAdj); 9778 pw.print(prefix); 9779 pw.print(" "); 9780 pw.print("keeping="); pw.print(r.keeping); 9781 pw.print(" hidden="); pw.print(r.hidden); 9782 pw.print(" empty="); pw.print(r.empty); 9783 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9784 9785 if (!r.keeping) { 9786 if (r.lastWakeTime != 0) { 9787 long wtime; 9788 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9789 synchronized (stats) { 9790 wtime = stats.getProcessWakeTime(r.info.uid, 9791 r.pid, curRealtime); 9792 } 9793 long timeUsed = wtime - r.lastWakeTime; 9794 pw.print(prefix); 9795 pw.print(" "); 9796 pw.print("keep awake over "); 9797 TimeUtils.formatDuration(realtimeSince, pw); 9798 pw.print(" used "); 9799 TimeUtils.formatDuration(timeUsed, pw); 9800 pw.print(" ("); 9801 pw.print((timeUsed*100)/realtimeSince); 9802 pw.println("%)"); 9803 } 9804 if (r.lastCpuTime != 0) { 9805 long timeUsed = r.curCpuTime - r.lastCpuTime; 9806 pw.print(prefix); 9807 pw.print(" "); 9808 pw.print("run cpu over "); 9809 TimeUtils.formatDuration(uptimeSince, pw); 9810 pw.print(" used "); 9811 TimeUtils.formatDuration(timeUsed, pw); 9812 pw.print(" ("); 9813 pw.print((timeUsed*100)/uptimeSince); 9814 pw.println("%)"); 9815 } 9816 } 9817 } 9818 } 9819 return true; 9820 } 9821 9822 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9823 ArrayList<ProcessRecord> procs; 9824 synchronized (this) { 9825 if (args != null && args.length > start 9826 && args[start].charAt(0) != '-') { 9827 procs = new ArrayList<ProcessRecord>(); 9828 int pid = -1; 9829 try { 9830 pid = Integer.parseInt(args[start]); 9831 } catch (NumberFormatException e) { 9832 9833 } 9834 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9835 ProcessRecord proc = mLruProcesses.get(i); 9836 if (proc.pid == pid) { 9837 procs.add(proc); 9838 } else if (proc.processName.equals(args[start])) { 9839 procs.add(proc); 9840 } 9841 } 9842 if (procs.size() <= 0) { 9843 pw.println("No process found for: " + args[start]); 9844 return null; 9845 } 9846 } else { 9847 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9848 } 9849 } 9850 return procs; 9851 } 9852 9853 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9854 PrintWriter pw, String[] args) { 9855 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9856 if (procs == null) { 9857 return; 9858 } 9859 9860 long uptime = SystemClock.uptimeMillis(); 9861 long realtime = SystemClock.elapsedRealtime(); 9862 pw.println("Applications Graphics Acceleration Info:"); 9863 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9864 9865 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9866 ProcessRecord r = procs.get(i); 9867 if (r.thread != null) { 9868 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9869 pw.flush(); 9870 try { 9871 TransferPipe tp = new TransferPipe(); 9872 try { 9873 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9874 tp.go(fd); 9875 } finally { 9876 tp.kill(); 9877 } 9878 } catch (IOException e) { 9879 pw.println("Failure while dumping the app: " + r); 9880 pw.flush(); 9881 } catch (RemoteException e) { 9882 pw.println("Got a RemoteException while dumping the app " + r); 9883 pw.flush(); 9884 } 9885 } 9886 } 9887 } 9888 9889 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9890 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9891 if (procs == null) { 9892 return; 9893 } 9894 9895 pw.println("Applications Database Info:"); 9896 9897 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9898 ProcessRecord r = procs.get(i); 9899 if (r.thread != null) { 9900 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9901 pw.flush(); 9902 try { 9903 TransferPipe tp = new TransferPipe(); 9904 try { 9905 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9906 tp.go(fd); 9907 } finally { 9908 tp.kill(); 9909 } 9910 } catch (IOException e) { 9911 pw.println("Failure while dumping the app: " + r); 9912 pw.flush(); 9913 } catch (RemoteException e) { 9914 pw.println("Got a RemoteException while dumping the app " + r); 9915 pw.flush(); 9916 } 9917 } 9918 } 9919 } 9920 9921 final static class MemItem { 9922 final String label; 9923 final String shortLabel; 9924 final long pss; 9925 final int id; 9926 ArrayList<MemItem> subitems; 9927 9928 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9929 label = _label; 9930 shortLabel = _shortLabel; 9931 pss = _pss; 9932 id = _id; 9933 } 9934 } 9935 9936 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9937 boolean sort) { 9938 if (sort) { 9939 Collections.sort(items, new Comparator<MemItem>() { 9940 @Override 9941 public int compare(MemItem lhs, MemItem rhs) { 9942 if (lhs.pss < rhs.pss) { 9943 return 1; 9944 } else if (lhs.pss > rhs.pss) { 9945 return -1; 9946 } 9947 return 0; 9948 } 9949 }); 9950 } 9951 9952 for (int i=0; i<items.size(); i++) { 9953 MemItem mi = items.get(i); 9954 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9955 if (mi.subitems != null) { 9956 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9957 } 9958 } 9959 } 9960 9961 // These are in KB. 9962 static final long[] DUMP_MEM_BUCKETS = new long[] { 9963 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9964 120*1024, 160*1024, 200*1024, 9965 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9966 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9967 }; 9968 9969 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9970 boolean stackLike) { 9971 int start = label.lastIndexOf('.'); 9972 if (start >= 0) start++; 9973 else start = 0; 9974 int end = label.length(); 9975 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9976 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9977 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9978 out.append(bucket); 9979 out.append(stackLike ? "MB." : "MB "); 9980 out.append(label, start, end); 9981 return; 9982 } 9983 } 9984 out.append(memKB/1024); 9985 out.append(stackLike ? "MB." : "MB "); 9986 out.append(label, start, end); 9987 } 9988 9989 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9990 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9991 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9992 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9993 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9994 }; 9995 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9996 "System", "Persistent", "Foreground", 9997 "Visible", "Perceptible", "Heavy Weight", 9998 "Backup", "A Services", "Home", "Previous", 9999 "B Services", "Background" 10000 }; 10001 10002 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10003 PrintWriter pw, String prefix, String[] args, boolean brief, 10004 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10005 boolean dumpAll = false; 10006 boolean oomOnly = false; 10007 10008 int opti = 0; 10009 while (opti < args.length) { 10010 String opt = args[opti]; 10011 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10012 break; 10013 } 10014 opti++; 10015 if ("-a".equals(opt)) { 10016 dumpAll = true; 10017 } else if ("--oom".equals(opt)) { 10018 oomOnly = true; 10019 } else if ("-h".equals(opt)) { 10020 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10021 pw.println(" -a: include all available information for each process."); 10022 pw.println(" --oom: only show processes organized by oom adj."); 10023 pw.println("If [process] is specified it can be the name or "); 10024 pw.println("pid of a specific process to dump."); 10025 return; 10026 } else { 10027 pw.println("Unknown argument: " + opt + "; use -h for help"); 10028 } 10029 } 10030 10031 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10032 if (procs == null) { 10033 return; 10034 } 10035 10036 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10037 long uptime = SystemClock.uptimeMillis(); 10038 long realtime = SystemClock.elapsedRealtime(); 10039 10040 if (procs.size() == 1 || isCheckinRequest) { 10041 dumpAll = true; 10042 } 10043 10044 if (isCheckinRequest) { 10045 // short checkin version 10046 pw.println(uptime + "," + realtime); 10047 pw.flush(); 10048 } else { 10049 pw.println("Applications Memory Usage (kB):"); 10050 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10051 } 10052 10053 String[] innerArgs = new String[args.length-opti]; 10054 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10055 10056 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10057 long nativePss=0, dalvikPss=0, otherPss=0; 10058 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10059 10060 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10061 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10062 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10063 10064 long totalPss = 0; 10065 10066 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10067 ProcessRecord r = procs.get(i); 10068 if (r.thread != null) { 10069 if (!isCheckinRequest && dumpAll) { 10070 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10071 pw.flush(); 10072 } 10073 Debug.MemoryInfo mi = null; 10074 if (dumpAll) { 10075 try { 10076 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10077 } catch (RemoteException e) { 10078 if (!isCheckinRequest) { 10079 pw.println("Got RemoteException!"); 10080 pw.flush(); 10081 } 10082 } 10083 } else { 10084 mi = new Debug.MemoryInfo(); 10085 Debug.getMemoryInfo(r.pid, mi); 10086 } 10087 10088 if (!isCheckinRequest && mi != null) { 10089 long myTotalPss = mi.getTotalPss(); 10090 totalPss += myTotalPss; 10091 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10092 r.processName, myTotalPss, 0); 10093 procMems.add(pssItem); 10094 10095 nativePss += mi.nativePss; 10096 dalvikPss += mi.dalvikPss; 10097 otherPss += mi.otherPss; 10098 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10099 long mem = mi.getOtherPss(j); 10100 miscPss[j] += mem; 10101 otherPss -= mem; 10102 } 10103 10104 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10105 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10106 || oomIndex == (oomPss.length-1)) { 10107 oomPss[oomIndex] += myTotalPss; 10108 if (oomProcs[oomIndex] == null) { 10109 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10110 } 10111 oomProcs[oomIndex].add(pssItem); 10112 break; 10113 } 10114 } 10115 } 10116 } 10117 } 10118 10119 if (!isCheckinRequest && procs.size() > 1) { 10120 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10121 10122 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10123 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10124 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10125 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10126 String label = Debug.MemoryInfo.getOtherLabel(j); 10127 catMems.add(new MemItem(label, label, miscPss[j], j)); 10128 } 10129 10130 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10131 for (int j=0; j<oomPss.length; j++) { 10132 if (oomPss[j] != 0) { 10133 String label = DUMP_MEM_OOM_LABEL[j]; 10134 MemItem item = new MemItem(label, label, oomPss[j], 10135 DUMP_MEM_OOM_ADJ[j]); 10136 item.subitems = oomProcs[j]; 10137 oomMems.add(item); 10138 } 10139 } 10140 10141 if (outTag != null || outStack != null) { 10142 if (outTag != null) { 10143 appendMemBucket(outTag, totalPss, "total", false); 10144 } 10145 if (outStack != null) { 10146 appendMemBucket(outStack, totalPss, "total", true); 10147 } 10148 boolean firstLine = true; 10149 for (int i=0; i<oomMems.size(); i++) { 10150 MemItem miCat = oomMems.get(i); 10151 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10152 continue; 10153 } 10154 if (miCat.id < ProcessList.SERVICE_ADJ 10155 || miCat.id == ProcessList.HOME_APP_ADJ 10156 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10157 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10158 outTag.append(" / "); 10159 } 10160 if (outStack != null) { 10161 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10162 if (firstLine) { 10163 outStack.append(":"); 10164 firstLine = false; 10165 } 10166 outStack.append("\n\t at "); 10167 } else { 10168 outStack.append("$"); 10169 } 10170 } 10171 for (int j=0; j<miCat.subitems.size(); j++) { 10172 MemItem mi = miCat.subitems.get(j); 10173 if (j > 0) { 10174 if (outTag != null) { 10175 outTag.append(" "); 10176 } 10177 if (outStack != null) { 10178 outStack.append("$"); 10179 } 10180 } 10181 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10182 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10183 } 10184 if (outStack != null) { 10185 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10186 } 10187 } 10188 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10189 outStack.append("("); 10190 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10191 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10192 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10193 outStack.append(":"); 10194 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10195 } 10196 } 10197 outStack.append(")"); 10198 } 10199 } 10200 } 10201 } 10202 10203 if (!brief && !oomOnly) { 10204 pw.println(); 10205 pw.println("Total PSS by process:"); 10206 dumpMemItems(pw, " ", procMems, true); 10207 pw.println(); 10208 } 10209 pw.println("Total PSS by OOM adjustment:"); 10210 dumpMemItems(pw, " ", oomMems, false); 10211 if (!oomOnly) { 10212 PrintWriter out = categoryPw != null ? categoryPw : pw; 10213 out.println(); 10214 out.println("Total PSS by category:"); 10215 dumpMemItems(out, " ", catMems, true); 10216 } 10217 pw.println(); 10218 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10219 final int[] SINGLE_LONG_FORMAT = new int[] { 10220 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10221 }; 10222 long[] longOut = new long[1]; 10223 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10224 SINGLE_LONG_FORMAT, null, longOut, null); 10225 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10226 longOut[0] = 0; 10227 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10228 SINGLE_LONG_FORMAT, null, longOut, null); 10229 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10230 longOut[0] = 0; 10231 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10232 SINGLE_LONG_FORMAT, null, longOut, null); 10233 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10234 longOut[0] = 0; 10235 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10236 SINGLE_LONG_FORMAT, null, longOut, null); 10237 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10238 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10239 pw.print(shared); pw.println(" kB"); 10240 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10241 pw.print(voltile); pw.println(" kB volatile"); 10242 } 10243 } 10244 10245 /** 10246 * Searches array of arguments for the specified string 10247 * @param args array of argument strings 10248 * @param value value to search for 10249 * @return true if the value is contained in the array 10250 */ 10251 private static boolean scanArgs(String[] args, String value) { 10252 if (args != null) { 10253 for (String arg : args) { 10254 if (value.equals(arg)) { 10255 return true; 10256 } 10257 } 10258 } 10259 return false; 10260 } 10261 10262 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10263 ContentProviderRecord cpr, boolean always) { 10264 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10265 10266 if (!inLaunching || always) { 10267 synchronized (cpr) { 10268 cpr.launchingApp = null; 10269 cpr.notifyAll(); 10270 } 10271 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10272 String names[] = cpr.info.authority.split(";"); 10273 for (int j = 0; j < names.length; j++) { 10274 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10275 } 10276 } 10277 10278 for (int i=0; i<cpr.connections.size(); i++) { 10279 ContentProviderConnection conn = cpr.connections.get(i); 10280 if (conn.waiting) { 10281 // If this connection is waiting for the provider, then we don't 10282 // need to mess with its process unless we are always removing 10283 // or for some reason the provider is not currently launching. 10284 if (inLaunching && !always) { 10285 continue; 10286 } 10287 } 10288 ProcessRecord capp = conn.client; 10289 conn.dead = true; 10290 if (conn.stableCount > 0) { 10291 if (!capp.persistent && capp.thread != null 10292 && capp.pid != 0 10293 && capp.pid != MY_PID) { 10294 Slog.i(TAG, "Kill " + capp.processName 10295 + " (pid " + capp.pid + "): provider " + cpr.info.name 10296 + " in dying process " + (proc != null ? proc.processName : "??")); 10297 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10298 capp.processName, capp.setAdj, "dying provider " 10299 + cpr.name.toShortString()); 10300 Process.killProcessQuiet(capp.pid); 10301 } 10302 } else if (capp.thread != null && conn.provider.provider != null) { 10303 try { 10304 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10305 } catch (RemoteException e) { 10306 } 10307 // In the protocol here, we don't expect the client to correctly 10308 // clean up this connection, we'll just remove it. 10309 cpr.connections.remove(i); 10310 conn.client.conProviders.remove(conn); 10311 } 10312 } 10313 10314 if (inLaunching && always) { 10315 mLaunchingProviders.remove(cpr); 10316 } 10317 return inLaunching; 10318 } 10319 10320 /** 10321 * Main code for cleaning up a process when it has gone away. This is 10322 * called both as a result of the process dying, or directly when stopping 10323 * a process when running in single process mode. 10324 */ 10325 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10326 boolean restarting, boolean allowRestart, int index) { 10327 if (index >= 0) { 10328 mLruProcesses.remove(index); 10329 } 10330 10331 mProcessesToGc.remove(app); 10332 10333 // Dismiss any open dialogs. 10334 if (app.crashDialog != null) { 10335 app.crashDialog.dismiss(); 10336 app.crashDialog = null; 10337 } 10338 if (app.anrDialog != null) { 10339 app.anrDialog.dismiss(); 10340 app.anrDialog = null; 10341 } 10342 if (app.waitDialog != null) { 10343 app.waitDialog.dismiss(); 10344 app.waitDialog = null; 10345 } 10346 10347 app.crashing = false; 10348 app.notResponding = false; 10349 10350 app.resetPackageList(); 10351 app.unlinkDeathRecipient(); 10352 app.thread = null; 10353 app.forcingToForeground = null; 10354 app.foregroundServices = false; 10355 app.foregroundActivities = false; 10356 app.hasShownUi = false; 10357 app.hasAboveClient = false; 10358 10359 mServices.killServicesLocked(app, allowRestart); 10360 10361 boolean restart = false; 10362 10363 // Remove published content providers. 10364 if (!app.pubProviders.isEmpty()) { 10365 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10366 while (it.hasNext()) { 10367 ContentProviderRecord cpr = it.next(); 10368 10369 final boolean always = app.bad || !allowRestart; 10370 if (removeDyingProviderLocked(app, cpr, always) || always) { 10371 // We left the provider in the launching list, need to 10372 // restart it. 10373 restart = true; 10374 } 10375 10376 cpr.provider = null; 10377 cpr.proc = null; 10378 } 10379 app.pubProviders.clear(); 10380 } 10381 10382 // Take care of any launching providers waiting for this process. 10383 if (checkAppInLaunchingProvidersLocked(app, false)) { 10384 restart = true; 10385 } 10386 10387 // Unregister from connected content providers. 10388 if (!app.conProviders.isEmpty()) { 10389 for (int i=0; i<app.conProviders.size(); i++) { 10390 ContentProviderConnection conn = app.conProviders.get(i); 10391 conn.provider.connections.remove(conn); 10392 } 10393 app.conProviders.clear(); 10394 } 10395 10396 // At this point there may be remaining entries in mLaunchingProviders 10397 // where we were the only one waiting, so they are no longer of use. 10398 // Look for these and clean up if found. 10399 // XXX Commented out for now. Trying to figure out a way to reproduce 10400 // the actual situation to identify what is actually going on. 10401 if (false) { 10402 for (int i=0; i<mLaunchingProviders.size(); i++) { 10403 ContentProviderRecord cpr = (ContentProviderRecord) 10404 mLaunchingProviders.get(i); 10405 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10406 synchronized (cpr) { 10407 cpr.launchingApp = null; 10408 cpr.notifyAll(); 10409 } 10410 } 10411 } 10412 } 10413 10414 skipCurrentReceiverLocked(app); 10415 10416 // Unregister any receivers. 10417 if (app.receivers.size() > 0) { 10418 Iterator<ReceiverList> it = app.receivers.iterator(); 10419 while (it.hasNext()) { 10420 removeReceiverLocked(it.next()); 10421 } 10422 app.receivers.clear(); 10423 } 10424 10425 // If the app is undergoing backup, tell the backup manager about it 10426 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10427 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10428 try { 10429 IBackupManager bm = IBackupManager.Stub.asInterface( 10430 ServiceManager.getService(Context.BACKUP_SERVICE)); 10431 bm.agentDisconnected(app.info.packageName); 10432 } catch (RemoteException e) { 10433 // can't happen; backup manager is local 10434 } 10435 } 10436 10437 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10438 ProcessChangeItem item = mPendingProcessChanges.get(i); 10439 if (item.pid == app.pid) { 10440 mPendingProcessChanges.remove(i); 10441 mAvailProcessChanges.add(item); 10442 } 10443 } 10444 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10445 10446 // If the caller is restarting this app, then leave it in its 10447 // current lists and let the caller take care of it. 10448 if (restarting) { 10449 return; 10450 } 10451 10452 if (!app.persistent || app.isolated) { 10453 if (DEBUG_PROCESSES) Slog.v(TAG, 10454 "Removing non-persistent process during cleanup: " + app); 10455 mProcessNames.remove(app.processName, app.uid); 10456 mIsolatedProcesses.remove(app.uid); 10457 if (mHeavyWeightProcess == app) { 10458 mHeavyWeightProcess = null; 10459 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10460 } 10461 } else if (!app.removed) { 10462 // This app is persistent, so we need to keep its record around. 10463 // If it is not already on the pending app list, add it there 10464 // and start a new process for it. 10465 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10466 mPersistentStartingProcesses.add(app); 10467 restart = true; 10468 } 10469 } 10470 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10471 "Clean-up removing on hold: " + app); 10472 mProcessesOnHold.remove(app); 10473 10474 if (app == mHomeProcess) { 10475 mHomeProcess = null; 10476 } 10477 if (app == mPreviousProcess) { 10478 mPreviousProcess = null; 10479 } 10480 10481 if (restart && !app.isolated) { 10482 // We have components that still need to be running in the 10483 // process, so re-launch it. 10484 mProcessNames.put(app.processName, app.uid, app); 10485 startProcessLocked(app, "restart", app.processName); 10486 } else if (app.pid > 0 && app.pid != MY_PID) { 10487 // Goodbye! 10488 synchronized (mPidsSelfLocked) { 10489 mPidsSelfLocked.remove(app.pid); 10490 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10491 } 10492 app.setPid(0); 10493 } 10494 } 10495 10496 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10497 // Look through the content providers we are waiting to have launched, 10498 // and if any run in this process then either schedule a restart of 10499 // the process or kill the client waiting for it if this process has 10500 // gone bad. 10501 int NL = mLaunchingProviders.size(); 10502 boolean restart = false; 10503 for (int i=0; i<NL; i++) { 10504 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10505 if (cpr.launchingApp == app) { 10506 if (!alwaysBad && !app.bad) { 10507 restart = true; 10508 } else { 10509 removeDyingProviderLocked(app, cpr, true); 10510 NL = mLaunchingProviders.size(); 10511 } 10512 } 10513 } 10514 return restart; 10515 } 10516 10517 // ========================================================= 10518 // SERVICES 10519 // ========================================================= 10520 10521 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10522 int flags) { 10523 enforceNotIsolatedCaller("getServices"); 10524 synchronized (this) { 10525 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10526 } 10527 } 10528 10529 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10530 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10531 synchronized (this) { 10532 return mServices.getRunningServiceControlPanelLocked(name); 10533 } 10534 } 10535 10536 public ComponentName startService(IApplicationThread caller, Intent service, 10537 String resolvedType) { 10538 enforceNotIsolatedCaller("startService"); 10539 // Refuse possible leaked file descriptors 10540 if (service != null && service.hasFileDescriptors() == true) { 10541 throw new IllegalArgumentException("File descriptors passed in Intent"); 10542 } 10543 10544 if (DEBUG_SERVICE) 10545 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10546 synchronized(this) { 10547 final int callingPid = Binder.getCallingPid(); 10548 final int callingUid = Binder.getCallingUid(); 10549 final long origId = Binder.clearCallingIdentity(); 10550 ComponentName res = mServices.startServiceLocked(caller, service, 10551 resolvedType, callingPid, callingUid); 10552 Binder.restoreCallingIdentity(origId); 10553 return res; 10554 } 10555 } 10556 10557 ComponentName startServiceInPackage(int uid, 10558 Intent service, String resolvedType) { 10559 synchronized(this) { 10560 if (DEBUG_SERVICE) 10561 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10562 final long origId = Binder.clearCallingIdentity(); 10563 ComponentName res = mServices.startServiceLocked(null, service, 10564 resolvedType, -1, uid); 10565 Binder.restoreCallingIdentity(origId); 10566 return res; 10567 } 10568 } 10569 10570 public int stopService(IApplicationThread caller, Intent service, 10571 String resolvedType) { 10572 enforceNotIsolatedCaller("stopService"); 10573 // Refuse possible leaked file descriptors 10574 if (service != null && service.hasFileDescriptors() == true) { 10575 throw new IllegalArgumentException("File descriptors passed in Intent"); 10576 } 10577 10578 synchronized(this) { 10579 return mServices.stopServiceLocked(caller, service, resolvedType); 10580 } 10581 } 10582 10583 public IBinder peekService(Intent service, String resolvedType) { 10584 enforceNotIsolatedCaller("peekService"); 10585 // Refuse possible leaked file descriptors 10586 if (service != null && service.hasFileDescriptors() == true) { 10587 throw new IllegalArgumentException("File descriptors passed in Intent"); 10588 } 10589 synchronized(this) { 10590 return mServices.peekServiceLocked(service, resolvedType); 10591 } 10592 } 10593 10594 public boolean stopServiceToken(ComponentName className, IBinder token, 10595 int startId) { 10596 synchronized(this) { 10597 return mServices.stopServiceTokenLocked(className, token, startId); 10598 } 10599 } 10600 10601 public void setServiceForeground(ComponentName className, IBinder token, 10602 int id, Notification notification, boolean removeNotification) { 10603 synchronized(this) { 10604 mServices.setServiceForegroundLocked(className, token, id, notification, 10605 removeNotification); 10606 } 10607 } 10608 10609 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10610 String className, int flags) { 10611 boolean result = false; 10612 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10613 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10614 if (ActivityManager.checkUidPermission( 10615 android.Manifest.permission.INTERACT_ACROSS_USERS, 10616 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10617 ComponentName comp = new ComponentName(aInfo.packageName, className); 10618 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10619 + " requests FLAG_SINGLE_USER, but app does not hold " 10620 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10621 Slog.w(TAG, msg); 10622 throw new SecurityException(msg); 10623 } 10624 result = true; 10625 } 10626 } else if (componentProcessName == aInfo.packageName) { 10627 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10628 } else if ("system".equals(componentProcessName)) { 10629 result = true; 10630 } 10631 if (DEBUG_MU) { 10632 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10633 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10634 } 10635 return result; 10636 } 10637 10638 public int bindService(IApplicationThread caller, IBinder token, 10639 Intent service, String resolvedType, 10640 IServiceConnection connection, int flags, int userId) { 10641 enforceNotIsolatedCaller("bindService"); 10642 // Refuse possible leaked file descriptors 10643 if (service != null && service.hasFileDescriptors() == true) { 10644 throw new IllegalArgumentException("File descriptors passed in Intent"); 10645 } 10646 10647 checkValidCaller(Binder.getCallingUid(), userId); 10648 10649 synchronized(this) { 10650 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10651 connection, flags, userId); 10652 } 10653 } 10654 10655 public boolean unbindService(IServiceConnection connection) { 10656 synchronized (this) { 10657 return mServices.unbindServiceLocked(connection); 10658 } 10659 } 10660 10661 public void publishService(IBinder token, Intent intent, IBinder service) { 10662 // Refuse possible leaked file descriptors 10663 if (intent != null && intent.hasFileDescriptors() == true) { 10664 throw new IllegalArgumentException("File descriptors passed in Intent"); 10665 } 10666 10667 synchronized(this) { 10668 if (!(token instanceof ServiceRecord)) { 10669 throw new IllegalArgumentException("Invalid service token"); 10670 } 10671 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10672 } 10673 } 10674 10675 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10676 // Refuse possible leaked file descriptors 10677 if (intent != null && intent.hasFileDescriptors() == true) { 10678 throw new IllegalArgumentException("File descriptors passed in Intent"); 10679 } 10680 10681 synchronized(this) { 10682 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10683 } 10684 } 10685 10686 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10687 synchronized(this) { 10688 if (!(token instanceof ServiceRecord)) { 10689 throw new IllegalArgumentException("Invalid service token"); 10690 } 10691 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10692 } 10693 } 10694 10695 // ========================================================= 10696 // BACKUP AND RESTORE 10697 // ========================================================= 10698 10699 // Cause the target app to be launched if necessary and its backup agent 10700 // instantiated. The backup agent will invoke backupAgentCreated() on the 10701 // activity manager to announce its creation. 10702 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10703 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10704 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10705 10706 synchronized(this) { 10707 // !!! TODO: currently no check here that we're already bound 10708 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10709 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10710 synchronized (stats) { 10711 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10712 } 10713 10714 // Backup agent is now in use, its package can't be stopped. 10715 try { 10716 AppGlobals.getPackageManager().setPackageStoppedState( 10717 app.packageName, false, UserHandle.getUserId(app.uid)); 10718 } catch (RemoteException e) { 10719 } catch (IllegalArgumentException e) { 10720 Slog.w(TAG, "Failed trying to unstop package " 10721 + app.packageName + ": " + e); 10722 } 10723 10724 BackupRecord r = new BackupRecord(ss, app, backupMode); 10725 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10726 ? new ComponentName(app.packageName, app.backupAgentName) 10727 : new ComponentName("android", "FullBackupAgent"); 10728 // startProcessLocked() returns existing proc's record if it's already running 10729 ProcessRecord proc = startProcessLocked(app.processName, app, 10730 false, 0, "backup", hostingName, false, false); 10731 if (proc == null) { 10732 Slog.e(TAG, "Unable to start backup agent process " + r); 10733 return false; 10734 } 10735 10736 r.app = proc; 10737 mBackupTarget = r; 10738 mBackupAppName = app.packageName; 10739 10740 // Try not to kill the process during backup 10741 updateOomAdjLocked(proc); 10742 10743 // If the process is already attached, schedule the creation of the backup agent now. 10744 // If it is not yet live, this will be done when it attaches to the framework. 10745 if (proc.thread != null) { 10746 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10747 try { 10748 proc.thread.scheduleCreateBackupAgent(app, 10749 compatibilityInfoForPackageLocked(app), backupMode); 10750 } catch (RemoteException e) { 10751 // Will time out on the backup manager side 10752 } 10753 } else { 10754 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10755 } 10756 // Invariants: at this point, the target app process exists and the application 10757 // is either already running or in the process of coming up. mBackupTarget and 10758 // mBackupAppName describe the app, so that when it binds back to the AM we 10759 // know that it's scheduled for a backup-agent operation. 10760 } 10761 10762 return true; 10763 } 10764 10765 // A backup agent has just come up 10766 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10767 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10768 + " = " + agent); 10769 10770 synchronized(this) { 10771 if (!agentPackageName.equals(mBackupAppName)) { 10772 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10773 return; 10774 } 10775 } 10776 10777 long oldIdent = Binder.clearCallingIdentity(); 10778 try { 10779 IBackupManager bm = IBackupManager.Stub.asInterface( 10780 ServiceManager.getService(Context.BACKUP_SERVICE)); 10781 bm.agentConnected(agentPackageName, agent); 10782 } catch (RemoteException e) { 10783 // can't happen; the backup manager service is local 10784 } catch (Exception e) { 10785 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10786 e.printStackTrace(); 10787 } finally { 10788 Binder.restoreCallingIdentity(oldIdent); 10789 } 10790 } 10791 10792 // done with this agent 10793 public void unbindBackupAgent(ApplicationInfo appInfo) { 10794 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10795 if (appInfo == null) { 10796 Slog.w(TAG, "unbind backup agent for null app"); 10797 return; 10798 } 10799 10800 synchronized(this) { 10801 if (mBackupAppName == null) { 10802 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10803 return; 10804 } 10805 10806 if (!mBackupAppName.equals(appInfo.packageName)) { 10807 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10808 return; 10809 } 10810 10811 ProcessRecord proc = mBackupTarget.app; 10812 mBackupTarget = null; 10813 mBackupAppName = null; 10814 10815 // Not backing this app up any more; reset its OOM adjustment 10816 updateOomAdjLocked(proc); 10817 10818 // If the app crashed during backup, 'thread' will be null here 10819 if (proc.thread != null) { 10820 try { 10821 proc.thread.scheduleDestroyBackupAgent(appInfo, 10822 compatibilityInfoForPackageLocked(appInfo)); 10823 } catch (Exception e) { 10824 Slog.e(TAG, "Exception when unbinding backup agent:"); 10825 e.printStackTrace(); 10826 } 10827 } 10828 } 10829 } 10830 // ========================================================= 10831 // BROADCASTS 10832 // ========================================================= 10833 10834 private final List getStickiesLocked(String action, IntentFilter filter, 10835 List cur) { 10836 final ContentResolver resolver = mContext.getContentResolver(); 10837 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10838 if (list == null) { 10839 return cur; 10840 } 10841 int N = list.size(); 10842 for (int i=0; i<N; i++) { 10843 Intent intent = list.get(i); 10844 if (filter.match(resolver, intent, true, TAG) >= 0) { 10845 if (cur == null) { 10846 cur = new ArrayList<Intent>(); 10847 } 10848 cur.add(intent); 10849 } 10850 } 10851 return cur; 10852 } 10853 10854 boolean isPendingBroadcastProcessLocked(int pid) { 10855 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10856 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10857 } 10858 10859 void skipPendingBroadcastLocked(int pid) { 10860 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10861 for (BroadcastQueue queue : mBroadcastQueues) { 10862 queue.skipPendingBroadcastLocked(pid); 10863 } 10864 } 10865 10866 // The app just attached; send any pending broadcasts that it should receive 10867 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10868 boolean didSomething = false; 10869 for (BroadcastQueue queue : mBroadcastQueues) { 10870 didSomething |= queue.sendPendingBroadcastsLocked(app); 10871 } 10872 return didSomething; 10873 } 10874 10875 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10876 IIntentReceiver receiver, IntentFilter filter, String permission) { 10877 enforceNotIsolatedCaller("registerReceiver"); 10878 int callingUid; 10879 synchronized(this) { 10880 ProcessRecord callerApp = null; 10881 if (caller != null) { 10882 callerApp = getRecordForAppLocked(caller); 10883 if (callerApp == null) { 10884 throw new SecurityException( 10885 "Unable to find app for caller " + caller 10886 + " (pid=" + Binder.getCallingPid() 10887 + ") when registering receiver " + receiver); 10888 } 10889 if (callerApp.info.uid != Process.SYSTEM_UID && 10890 !callerApp.pkgList.contains(callerPackage)) { 10891 throw new SecurityException("Given caller package " + callerPackage 10892 + " is not running in process " + callerApp); 10893 } 10894 callingUid = callerApp.info.uid; 10895 } else { 10896 callerPackage = null; 10897 callingUid = Binder.getCallingUid(); 10898 } 10899 10900 List allSticky = null; 10901 10902 // Look for any matching sticky broadcasts... 10903 Iterator actions = filter.actionsIterator(); 10904 if (actions != null) { 10905 while (actions.hasNext()) { 10906 String action = (String)actions.next(); 10907 allSticky = getStickiesLocked(action, filter, allSticky); 10908 } 10909 } else { 10910 allSticky = getStickiesLocked(null, filter, allSticky); 10911 } 10912 10913 // The first sticky in the list is returned directly back to 10914 // the client. 10915 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10916 10917 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10918 + ": " + sticky); 10919 10920 if (receiver == null) { 10921 return sticky; 10922 } 10923 10924 ReceiverList rl 10925 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10926 if (rl == null) { 10927 rl = new ReceiverList(this, callerApp, 10928 Binder.getCallingPid(), 10929 Binder.getCallingUid(), receiver); 10930 if (rl.app != null) { 10931 rl.app.receivers.add(rl); 10932 } else { 10933 try { 10934 receiver.asBinder().linkToDeath(rl, 0); 10935 } catch (RemoteException e) { 10936 return sticky; 10937 } 10938 rl.linkedToDeath = true; 10939 } 10940 mRegisteredReceivers.put(receiver.asBinder(), rl); 10941 } 10942 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10943 permission, callingUid); 10944 rl.add(bf); 10945 if (!bf.debugCheck()) { 10946 Slog.w(TAG, "==> For Dynamic broadast"); 10947 } 10948 mReceiverResolver.addFilter(bf); 10949 10950 // Enqueue broadcasts for all existing stickies that match 10951 // this filter. 10952 if (allSticky != null) { 10953 ArrayList receivers = new ArrayList(); 10954 receivers.add(bf); 10955 10956 int N = allSticky.size(); 10957 for (int i=0; i<N; i++) { 10958 Intent intent = (Intent)allSticky.get(i); 10959 BroadcastQueue queue = broadcastQueueForIntent(intent); 10960 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10961 null, -1, -1, null, receivers, null, 0, null, null, 10962 false, true, true, false); 10963 queue.enqueueParallelBroadcastLocked(r); 10964 queue.scheduleBroadcastsLocked(); 10965 } 10966 } 10967 10968 return sticky; 10969 } 10970 } 10971 10972 public void unregisterReceiver(IIntentReceiver receiver) { 10973 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10974 10975 final long origId = Binder.clearCallingIdentity(); 10976 try { 10977 boolean doTrim = false; 10978 10979 synchronized(this) { 10980 ReceiverList rl 10981 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10982 if (rl != null) { 10983 if (rl.curBroadcast != null) { 10984 BroadcastRecord r = rl.curBroadcast; 10985 final boolean doNext = finishReceiverLocked( 10986 receiver.asBinder(), r.resultCode, r.resultData, 10987 r.resultExtras, r.resultAbort, true); 10988 if (doNext) { 10989 doTrim = true; 10990 r.queue.processNextBroadcast(false); 10991 } 10992 } 10993 10994 if (rl.app != null) { 10995 rl.app.receivers.remove(rl); 10996 } 10997 removeReceiverLocked(rl); 10998 if (rl.linkedToDeath) { 10999 rl.linkedToDeath = false; 11000 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11001 } 11002 } 11003 } 11004 11005 // If we actually concluded any broadcasts, we might now be able 11006 // to trim the recipients' apps from our working set 11007 if (doTrim) { 11008 trimApplications(); 11009 return; 11010 } 11011 11012 } finally { 11013 Binder.restoreCallingIdentity(origId); 11014 } 11015 } 11016 11017 void removeReceiverLocked(ReceiverList rl) { 11018 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11019 int N = rl.size(); 11020 for (int i=0; i<N; i++) { 11021 mReceiverResolver.removeFilter(rl.get(i)); 11022 } 11023 } 11024 11025 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11027 ProcessRecord r = mLruProcesses.get(i); 11028 if (r.thread != null) { 11029 try { 11030 r.thread.dispatchPackageBroadcast(cmd, packages); 11031 } catch (RemoteException ex) { 11032 } 11033 } 11034 } 11035 } 11036 11037 private final int broadcastIntentLocked(ProcessRecord callerApp, 11038 String callerPackage, Intent intent, String resolvedType, 11039 IIntentReceiver resultTo, int resultCode, String resultData, 11040 Bundle map, String requiredPermission, 11041 boolean ordered, boolean sticky, int callingPid, int callingUid, 11042 int userId) { 11043 intent = new Intent(intent); 11044 11045 // By default broadcasts do not go to stopped apps. 11046 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11047 11048 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11049 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11050 + " ordered=" + ordered + " userid=" + userId); 11051 if ((resultTo != null) && !ordered) { 11052 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11053 } 11054 11055 boolean onlySendToCaller = false; 11056 11057 // If the caller is trying to send this broadcast to a different 11058 // user, verify that is allowed. 11059 if (UserHandle.getUserId(callingUid) != userId) { 11060 if (checkComponentPermission( 11061 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11062 callingPid, callingUid, -1, true) 11063 != PackageManager.PERMISSION_GRANTED) { 11064 if (checkComponentPermission( 11065 android.Manifest.permission.INTERACT_ACROSS_USERS, 11066 callingPid, callingUid, -1, true) 11067 == PackageManager.PERMISSION_GRANTED) { 11068 onlySendToCaller = true; 11069 } else { 11070 String msg = "Permission Denial: " + intent.getAction() 11071 + " broadcast from " + callerPackage 11072 + " asks to send as user " + userId 11073 + " but is calling from user " + UserHandle.getUserId(callingUid) 11074 + "; this requires " 11075 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11076 Slog.w(TAG, msg); 11077 throw new SecurityException(msg); 11078 } 11079 } 11080 } 11081 11082 // Handle special intents: if this broadcast is from the package 11083 // manager about a package being removed, we need to remove all of 11084 // its activities from the history stack. 11085 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11086 intent.getAction()); 11087 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11088 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11089 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11090 || uidRemoved) { 11091 if (checkComponentPermission( 11092 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11093 callingPid, callingUid, -1, true) 11094 == PackageManager.PERMISSION_GRANTED) { 11095 if (uidRemoved) { 11096 final Bundle intentExtras = intent.getExtras(); 11097 final int uid = intentExtras != null 11098 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11099 if (uid >= 0) { 11100 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11101 synchronized (bs) { 11102 bs.removeUidStatsLocked(uid); 11103 } 11104 } 11105 } else { 11106 // If resources are unvailble just force stop all 11107 // those packages and flush the attribute cache as well. 11108 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11109 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11110 if (list != null && (list.length > 0)) { 11111 for (String pkg : list) { 11112 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11113 } 11114 sendPackageBroadcastLocked( 11115 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11116 } 11117 } else { 11118 Uri data = intent.getData(); 11119 String ssp; 11120 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11121 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11122 forceStopPackageLocked(ssp, 11123 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11124 false, userId); 11125 } 11126 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11127 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11128 new String[] {ssp}); 11129 } 11130 } 11131 } 11132 } 11133 } else { 11134 String msg = "Permission Denial: " + intent.getAction() 11135 + " broadcast from " + callerPackage + " (pid=" + callingPid 11136 + ", uid=" + callingUid + ")" 11137 + " requires " 11138 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11139 Slog.w(TAG, msg); 11140 throw new SecurityException(msg); 11141 } 11142 11143 // Special case for adding a package: by default turn on compatibility 11144 // mode. 11145 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11146 Uri data = intent.getData(); 11147 String ssp; 11148 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11149 mCompatModePackages.handlePackageAddedLocked(ssp, 11150 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11151 } 11152 } 11153 11154 /* 11155 * If this is the time zone changed action, queue up a message that will reset the timezone 11156 * of all currently running processes. This message will get queued up before the broadcast 11157 * happens. 11158 */ 11159 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11160 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11161 } 11162 11163 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11164 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11165 } 11166 11167 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11168 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11169 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11170 } 11171 11172 /* 11173 * Prevent non-system code (defined here to be non-persistent 11174 * processes) from sending protected broadcasts. 11175 */ 11176 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11177 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11178 callingUid == 0) { 11179 // Always okay. 11180 } else if (callerApp == null || !callerApp.persistent) { 11181 try { 11182 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11183 intent.getAction())) { 11184 String msg = "Permission Denial: not allowed to send broadcast " 11185 + intent.getAction() + " from pid=" 11186 + callingPid + ", uid=" + callingUid; 11187 Slog.w(TAG, msg); 11188 throw new SecurityException(msg); 11189 } 11190 } catch (RemoteException e) { 11191 Slog.w(TAG, "Remote exception", e); 11192 return ActivityManager.BROADCAST_SUCCESS; 11193 } 11194 } 11195 11196 // Add to the sticky list if requested. 11197 if (sticky) { 11198 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11199 callingPid, callingUid) 11200 != PackageManager.PERMISSION_GRANTED) { 11201 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11202 + callingPid + ", uid=" + callingUid 11203 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11204 Slog.w(TAG, msg); 11205 throw new SecurityException(msg); 11206 } 11207 if (requiredPermission != null) { 11208 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11209 + " and enforce permission " + requiredPermission); 11210 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11211 } 11212 if (intent.getComponent() != null) { 11213 throw new SecurityException( 11214 "Sticky broadcasts can't target a specific component"); 11215 } 11216 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11217 if (list == null) { 11218 list = new ArrayList<Intent>(); 11219 mStickyBroadcasts.put(intent.getAction(), list); 11220 } 11221 int N = list.size(); 11222 int i; 11223 for (i=0; i<N; i++) { 11224 if (intent.filterEquals(list.get(i))) { 11225 // This sticky already exists, replace it. 11226 list.set(i, new Intent(intent)); 11227 break; 11228 } 11229 } 11230 if (i >= N) { 11231 list.add(new Intent(intent)); 11232 } 11233 } 11234 11235 // Figure out who all will receive this broadcast. 11236 List receivers = null; 11237 List<BroadcastFilter> registeredReceivers = null; 11238 try { 11239 // Need to resolve the intent to interested receivers... 11240 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11241 == 0) { 11242 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11243 intent, resolvedType, STOCK_PM_FLAGS, userId); 11244 } 11245 if (intent.getComponent() == null) { 11246 registeredReceivers = mReceiverResolver.queryIntent(intent, 11247 resolvedType, false, userId); 11248 } 11249 } catch (RemoteException ex) { 11250 // pm is in same process, this will never happen. 11251 } 11252 11253 final boolean replacePending = 11254 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11255 11256 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11257 + " replacePending=" + replacePending); 11258 11259 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11260 if (!ordered && NR > 0) { 11261 // If we are not serializing this broadcast, then send the 11262 // registered receivers separately so they don't wait for the 11263 // components to be launched. 11264 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11265 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11266 callerPackage, callingPid, callingUid, requiredPermission, 11267 registeredReceivers, resultTo, resultCode, resultData, map, 11268 ordered, sticky, false, onlySendToCaller); 11269 if (DEBUG_BROADCAST) Slog.v( 11270 TAG, "Enqueueing parallel broadcast " + r); 11271 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11272 if (!replaced) { 11273 queue.enqueueParallelBroadcastLocked(r); 11274 queue.scheduleBroadcastsLocked(); 11275 } 11276 registeredReceivers = null; 11277 NR = 0; 11278 } 11279 11280 // Merge into one list. 11281 int ir = 0; 11282 if (receivers != null) { 11283 // A special case for PACKAGE_ADDED: do not allow the package 11284 // being added to see this broadcast. This prevents them from 11285 // using this as a back door to get run as soon as they are 11286 // installed. Maybe in the future we want to have a special install 11287 // broadcast or such for apps, but we'd like to deliberately make 11288 // this decision. 11289 String skipPackages[] = null; 11290 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11291 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11292 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11293 Uri data = intent.getData(); 11294 if (data != null) { 11295 String pkgName = data.getSchemeSpecificPart(); 11296 if (pkgName != null) { 11297 skipPackages = new String[] { pkgName }; 11298 } 11299 } 11300 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11301 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11302 } 11303 if (skipPackages != null && (skipPackages.length > 0)) { 11304 for (String skipPackage : skipPackages) { 11305 if (skipPackage != null) { 11306 int NT = receivers.size(); 11307 for (int it=0; it<NT; it++) { 11308 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11309 if (curt.activityInfo.packageName.equals(skipPackage)) { 11310 receivers.remove(it); 11311 it--; 11312 NT--; 11313 } 11314 } 11315 } 11316 } 11317 } 11318 11319 int NT = receivers != null ? receivers.size() : 0; 11320 int it = 0; 11321 ResolveInfo curt = null; 11322 BroadcastFilter curr = null; 11323 while (it < NT && ir < NR) { 11324 if (curt == null) { 11325 curt = (ResolveInfo)receivers.get(it); 11326 } 11327 if (curr == null) { 11328 curr = registeredReceivers.get(ir); 11329 } 11330 if (curr.getPriority() >= curt.priority) { 11331 // Insert this broadcast record into the final list. 11332 receivers.add(it, curr); 11333 ir++; 11334 curr = null; 11335 it++; 11336 NT++; 11337 } else { 11338 // Skip to the next ResolveInfo in the final list. 11339 it++; 11340 curt = null; 11341 } 11342 } 11343 } 11344 while (ir < NR) { 11345 if (receivers == null) { 11346 receivers = new ArrayList(); 11347 } 11348 receivers.add(registeredReceivers.get(ir)); 11349 ir++; 11350 } 11351 11352 if ((receivers != null && receivers.size() > 0) 11353 || resultTo != null) { 11354 BroadcastQueue queue = broadcastQueueForIntent(intent); 11355 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11356 callerPackage, callingPid, callingUid, requiredPermission, 11357 receivers, resultTo, resultCode, resultData, map, ordered, 11358 sticky, false, onlySendToCaller); 11359 if (DEBUG_BROADCAST) Slog.v( 11360 TAG, "Enqueueing ordered broadcast " + r 11361 + ": prev had " + queue.mOrderedBroadcasts.size()); 11362 if (DEBUG_BROADCAST) { 11363 int seq = r.intent.getIntExtra("seq", -1); 11364 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11365 } 11366 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11367 if (!replaced) { 11368 queue.enqueueOrderedBroadcastLocked(r); 11369 queue.scheduleBroadcastsLocked(); 11370 } 11371 } 11372 11373 return ActivityManager.BROADCAST_SUCCESS; 11374 } 11375 11376 final Intent verifyBroadcastLocked(Intent intent) { 11377 // Refuse possible leaked file descriptors 11378 if (intent != null && intent.hasFileDescriptors() == true) { 11379 throw new IllegalArgumentException("File descriptors passed in Intent"); 11380 } 11381 11382 int flags = intent.getFlags(); 11383 11384 if (!mProcessesReady) { 11385 // if the caller really truly claims to know what they're doing, go 11386 // ahead and allow the broadcast without launching any receivers 11387 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11388 intent = new Intent(intent); 11389 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11390 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11391 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11392 + " before boot completion"); 11393 throw new IllegalStateException("Cannot broadcast before boot completed"); 11394 } 11395 } 11396 11397 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11398 throw new IllegalArgumentException( 11399 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11400 } 11401 11402 return intent; 11403 } 11404 11405 public final int broadcastIntent(IApplicationThread caller, 11406 Intent intent, String resolvedType, IIntentReceiver resultTo, 11407 int resultCode, String resultData, Bundle map, 11408 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11409 enforceNotIsolatedCaller("broadcastIntent"); 11410 synchronized(this) { 11411 intent = verifyBroadcastLocked(intent); 11412 11413 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11414 final int callingPid = Binder.getCallingPid(); 11415 final int callingUid = Binder.getCallingUid(); 11416 final long origId = Binder.clearCallingIdentity(); 11417 int res = broadcastIntentLocked(callerApp, 11418 callerApp != null ? callerApp.info.packageName : null, 11419 intent, resolvedType, resultTo, 11420 resultCode, resultData, map, requiredPermission, serialized, sticky, 11421 callingPid, callingUid, userId); 11422 Binder.restoreCallingIdentity(origId); 11423 return res; 11424 } 11425 } 11426 11427 int broadcastIntentInPackage(String packageName, int uid, 11428 Intent intent, String resolvedType, IIntentReceiver resultTo, 11429 int resultCode, String resultData, Bundle map, 11430 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11431 synchronized(this) { 11432 intent = verifyBroadcastLocked(intent); 11433 11434 final long origId = Binder.clearCallingIdentity(); 11435 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11436 resultTo, resultCode, resultData, map, requiredPermission, 11437 serialized, sticky, -1, uid, userId); 11438 Binder.restoreCallingIdentity(origId); 11439 return res; 11440 } 11441 } 11442 11443 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11444 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11445 // Refuse possible leaked file descriptors 11446 if (intent != null && intent.hasFileDescriptors() == true) { 11447 throw new IllegalArgumentException("File descriptors passed in Intent"); 11448 } 11449 11450 synchronized(this) { 11451 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11452 != PackageManager.PERMISSION_GRANTED) { 11453 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11454 + Binder.getCallingPid() 11455 + ", uid=" + Binder.getCallingUid() 11456 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11457 Slog.w(TAG, msg); 11458 throw new SecurityException(msg); 11459 } 11460 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11461 if (list != null) { 11462 int N = list.size(); 11463 int i; 11464 for (i=0; i<N; i++) { 11465 if (intent.filterEquals(list.get(i))) { 11466 list.remove(i); 11467 break; 11468 } 11469 } 11470 } 11471 } 11472 } 11473 11474 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11475 String resultData, Bundle resultExtras, boolean resultAbort, 11476 boolean explicit) { 11477 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11478 if (r == null) { 11479 Slog.w(TAG, "finishReceiver called but not found on queue"); 11480 return false; 11481 } 11482 11483 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11484 explicit); 11485 } 11486 11487 public void finishReceiver(IBinder who, int resultCode, String resultData, 11488 Bundle resultExtras, boolean resultAbort) { 11489 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11490 11491 // Refuse possible leaked file descriptors 11492 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11493 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11494 } 11495 11496 final long origId = Binder.clearCallingIdentity(); 11497 try { 11498 boolean doNext = false; 11499 BroadcastRecord r = null; 11500 11501 synchronized(this) { 11502 r = broadcastRecordForReceiverLocked(who); 11503 if (r != null) { 11504 doNext = r.queue.finishReceiverLocked(r, resultCode, 11505 resultData, resultExtras, resultAbort, true); 11506 } 11507 } 11508 11509 if (doNext) { 11510 r.queue.processNextBroadcast(false); 11511 } 11512 trimApplications(); 11513 } finally { 11514 Binder.restoreCallingIdentity(origId); 11515 } 11516 } 11517 11518 // ========================================================= 11519 // INSTRUMENTATION 11520 // ========================================================= 11521 11522 public boolean startInstrumentation(ComponentName className, 11523 String profileFile, int flags, Bundle arguments, 11524 IInstrumentationWatcher watcher) { 11525 enforceNotIsolatedCaller("startInstrumentation"); 11526 // Refuse possible leaked file descriptors 11527 if (arguments != null && arguments.hasFileDescriptors()) { 11528 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11529 } 11530 11531 synchronized(this) { 11532 InstrumentationInfo ii = null; 11533 ApplicationInfo ai = null; 11534 try { 11535 ii = mContext.getPackageManager().getInstrumentationInfo( 11536 className, STOCK_PM_FLAGS); 11537 ai = mContext.getPackageManager().getApplicationInfo( 11538 ii.targetPackage, STOCK_PM_FLAGS); 11539 } catch (PackageManager.NameNotFoundException e) { 11540 } 11541 if (ii == null) { 11542 reportStartInstrumentationFailure(watcher, className, 11543 "Unable to find instrumentation info for: " + className); 11544 return false; 11545 } 11546 if (ai == null) { 11547 reportStartInstrumentationFailure(watcher, className, 11548 "Unable to find instrumentation target package: " + ii.targetPackage); 11549 return false; 11550 } 11551 11552 int match = mContext.getPackageManager().checkSignatures( 11553 ii.targetPackage, ii.packageName); 11554 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11555 String msg = "Permission Denial: starting instrumentation " 11556 + className + " from pid=" 11557 + Binder.getCallingPid() 11558 + ", uid=" + Binder.getCallingPid() 11559 + " not allowed because package " + ii.packageName 11560 + " does not have a signature matching the target " 11561 + ii.targetPackage; 11562 reportStartInstrumentationFailure(watcher, className, msg); 11563 throw new SecurityException(msg); 11564 } 11565 11566 int userId = UserHandle.getCallingUserId(); 11567 final long origId = Binder.clearCallingIdentity(); 11568 // Instrumentation can kill and relaunch even persistent processes 11569 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11570 ProcessRecord app = addAppLocked(ai, false); 11571 app.instrumentationClass = className; 11572 app.instrumentationInfo = ai; 11573 app.instrumentationProfileFile = profileFile; 11574 app.instrumentationArguments = arguments; 11575 app.instrumentationWatcher = watcher; 11576 app.instrumentationResultClass = className; 11577 Binder.restoreCallingIdentity(origId); 11578 } 11579 11580 return true; 11581 } 11582 11583 /** 11584 * Report errors that occur while attempting to start Instrumentation. Always writes the 11585 * error to the logs, but if somebody is watching, send the report there too. This enables 11586 * the "am" command to report errors with more information. 11587 * 11588 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11589 * @param cn The component name of the instrumentation. 11590 * @param report The error report. 11591 */ 11592 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11593 ComponentName cn, String report) { 11594 Slog.w(TAG, report); 11595 try { 11596 if (watcher != null) { 11597 Bundle results = new Bundle(); 11598 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11599 results.putString("Error", report); 11600 watcher.instrumentationStatus(cn, -1, results); 11601 } 11602 } catch (RemoteException e) { 11603 Slog.w(TAG, e); 11604 } 11605 } 11606 11607 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11608 if (app.instrumentationWatcher != null) { 11609 try { 11610 // NOTE: IInstrumentationWatcher *must* be oneway here 11611 app.instrumentationWatcher.instrumentationFinished( 11612 app.instrumentationClass, 11613 resultCode, 11614 results); 11615 } catch (RemoteException e) { 11616 } 11617 } 11618 app.instrumentationWatcher = null; 11619 app.instrumentationClass = null; 11620 app.instrumentationInfo = null; 11621 app.instrumentationProfileFile = null; 11622 app.instrumentationArguments = null; 11623 11624 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11625 } 11626 11627 public void finishInstrumentation(IApplicationThread target, 11628 int resultCode, Bundle results) { 11629 int userId = UserHandle.getCallingUserId(); 11630 // Refuse possible leaked file descriptors 11631 if (results != null && results.hasFileDescriptors()) { 11632 throw new IllegalArgumentException("File descriptors passed in Intent"); 11633 } 11634 11635 synchronized(this) { 11636 ProcessRecord app = getRecordForAppLocked(target); 11637 if (app == null) { 11638 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11639 return; 11640 } 11641 final long origId = Binder.clearCallingIdentity(); 11642 finishInstrumentationLocked(app, resultCode, results); 11643 Binder.restoreCallingIdentity(origId); 11644 } 11645 } 11646 11647 // ========================================================= 11648 // CONFIGURATION 11649 // ========================================================= 11650 11651 public ConfigurationInfo getDeviceConfigurationInfo() { 11652 ConfigurationInfo config = new ConfigurationInfo(); 11653 synchronized (this) { 11654 config.reqTouchScreen = mConfiguration.touchscreen; 11655 config.reqKeyboardType = mConfiguration.keyboard; 11656 config.reqNavigation = mConfiguration.navigation; 11657 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11658 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11659 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11660 } 11661 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11662 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11663 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11664 } 11665 config.reqGlEsVersion = GL_ES_VERSION; 11666 } 11667 return config; 11668 } 11669 11670 public Configuration getConfiguration() { 11671 Configuration ci; 11672 synchronized(this) { 11673 ci = new Configuration(mConfiguration); 11674 } 11675 return ci; 11676 } 11677 11678 public void updatePersistentConfiguration(Configuration values) { 11679 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11680 "updateConfiguration()"); 11681 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11682 "updateConfiguration()"); 11683 if (values == null) { 11684 throw new NullPointerException("Configuration must not be null"); 11685 } 11686 11687 synchronized(this) { 11688 final long origId = Binder.clearCallingIdentity(); 11689 updateConfigurationLocked(values, null, true, false); 11690 Binder.restoreCallingIdentity(origId); 11691 } 11692 } 11693 11694 public void updateConfiguration(Configuration values) { 11695 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11696 "updateConfiguration()"); 11697 11698 synchronized(this) { 11699 if (values == null && mWindowManager != null) { 11700 // sentinel: fetch the current configuration from the window manager 11701 values = mWindowManager.computeNewConfiguration(); 11702 } 11703 11704 if (mWindowManager != null) { 11705 mProcessList.applyDisplaySize(mWindowManager); 11706 } 11707 11708 final long origId = Binder.clearCallingIdentity(); 11709 if (values != null) { 11710 Settings.System.clearConfiguration(values); 11711 } 11712 updateConfigurationLocked(values, null, false, false); 11713 Binder.restoreCallingIdentity(origId); 11714 } 11715 } 11716 11717 /** 11718 * Do either or both things: (1) change the current configuration, and (2) 11719 * make sure the given activity is running with the (now) current 11720 * configuration. Returns true if the activity has been left running, or 11721 * false if <var>starting</var> is being destroyed to match the new 11722 * configuration. 11723 * @param persistent TODO 11724 */ 11725 boolean updateConfigurationLocked(Configuration values, 11726 ActivityRecord starting, boolean persistent, boolean initLocale) { 11727 // do nothing if we are headless 11728 if (mHeadless) return true; 11729 11730 int changes = 0; 11731 11732 boolean kept = true; 11733 11734 if (values != null) { 11735 Configuration newConfig = new Configuration(mConfiguration); 11736 changes = newConfig.updateFrom(values); 11737 if (changes != 0) { 11738 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11739 Slog.i(TAG, "Updating configuration to: " + values); 11740 } 11741 11742 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11743 11744 if (values.locale != null && !initLocale) { 11745 saveLocaleLocked(values.locale, 11746 !values.locale.equals(mConfiguration.locale), 11747 values.userSetLocale); 11748 } 11749 11750 mConfigurationSeq++; 11751 if (mConfigurationSeq <= 0) { 11752 mConfigurationSeq = 1; 11753 } 11754 newConfig.seq = mConfigurationSeq; 11755 mConfiguration = newConfig; 11756 Slog.i(TAG, "Config changed: " + newConfig); 11757 11758 final Configuration configCopy = new Configuration(mConfiguration); 11759 11760 // TODO: If our config changes, should we auto dismiss any currently 11761 // showing dialogs? 11762 mShowDialogs = shouldShowDialogs(newConfig); 11763 11764 AttributeCache ac = AttributeCache.instance(); 11765 if (ac != null) { 11766 ac.updateConfiguration(configCopy); 11767 } 11768 11769 // Make sure all resources in our process are updated 11770 // right now, so that anyone who is going to retrieve 11771 // resource values after we return will be sure to get 11772 // the new ones. This is especially important during 11773 // boot, where the first config change needs to guarantee 11774 // all resources have that config before following boot 11775 // code is executed. 11776 mSystemThread.applyConfigurationToResources(configCopy); 11777 11778 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11779 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11780 msg.obj = new Configuration(configCopy); 11781 mHandler.sendMessage(msg); 11782 } 11783 11784 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11785 ProcessRecord app = mLruProcesses.get(i); 11786 try { 11787 if (app.thread != null) { 11788 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11789 + app.processName + " new config " + mConfiguration); 11790 app.thread.scheduleConfigurationChanged(configCopy); 11791 } 11792 } catch (Exception e) { 11793 } 11794 } 11795 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11796 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11797 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11798 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11799 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11800 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11801 broadcastIntentLocked(null, null, 11802 new Intent(Intent.ACTION_LOCALE_CHANGED), 11803 null, null, 0, null, null, 11804 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11805 } 11806 } 11807 } 11808 11809 if (changes != 0 && starting == null) { 11810 // If the configuration changed, and the caller is not already 11811 // in the process of starting an activity, then find the top 11812 // activity to check if its configuration needs to change. 11813 starting = mMainStack.topRunningActivityLocked(null); 11814 } 11815 11816 if (starting != null) { 11817 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11818 // And we need to make sure at this point that all other activities 11819 // are made visible with the correct configuration. 11820 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11821 } 11822 11823 if (values != null && mWindowManager != null) { 11824 mWindowManager.setNewConfiguration(mConfiguration); 11825 } 11826 11827 return kept; 11828 } 11829 11830 /** 11831 * Decide based on the configuration whether we should shouw the ANR, 11832 * crash, etc dialogs. The idea is that if there is no affordnace to 11833 * press the on-screen buttons, we shouldn't show the dialog. 11834 * 11835 * A thought: SystemUI might also want to get told about this, the Power 11836 * dialog / global actions also might want different behaviors. 11837 */ 11838 private static final boolean shouldShowDialogs(Configuration config) { 11839 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11840 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11841 } 11842 11843 /** 11844 * Save the locale. You must be inside a synchronized (this) block. 11845 */ 11846 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11847 if(isDiff) { 11848 SystemProperties.set("user.language", l.getLanguage()); 11849 SystemProperties.set("user.region", l.getCountry()); 11850 } 11851 11852 if(isPersist) { 11853 SystemProperties.set("persist.sys.language", l.getLanguage()); 11854 SystemProperties.set("persist.sys.country", l.getCountry()); 11855 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11856 } 11857 } 11858 11859 @Override 11860 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11861 ActivityRecord srec = ActivityRecord.forToken(token); 11862 return srec != null && srec.task.affinity != null && 11863 srec.task.affinity.equals(destAffinity); 11864 } 11865 11866 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11867 Intent resultData) { 11868 ComponentName dest = destIntent.getComponent(); 11869 11870 synchronized (this) { 11871 ActivityRecord srec = ActivityRecord.forToken(token); 11872 if (srec == null) { 11873 return false; 11874 } 11875 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11876 final int start = history.indexOf(srec); 11877 if (start < 0) { 11878 // Current activity is not in history stack; do nothing. 11879 return false; 11880 } 11881 int finishTo = start - 1; 11882 ActivityRecord parent = null; 11883 boolean foundParentInTask = false; 11884 if (dest != null) { 11885 TaskRecord tr = srec.task; 11886 for (int i = start - 1; i >= 0; i--) { 11887 ActivityRecord r = history.get(i); 11888 if (tr != r.task) { 11889 // Couldn't find parent in the same task; stop at the one above this. 11890 // (Root of current task; in-app "home" behavior) 11891 // Always at least finish the current activity. 11892 finishTo = Math.min(start - 1, i + 1); 11893 parent = history.get(finishTo); 11894 break; 11895 } else if (r.info.packageName.equals(dest.getPackageName()) && 11896 r.info.name.equals(dest.getClassName())) { 11897 finishTo = i; 11898 parent = r; 11899 foundParentInTask = true; 11900 break; 11901 } 11902 } 11903 } 11904 11905 if (mController != null) { 11906 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11907 if (next != null) { 11908 // ask watcher if this is allowed 11909 boolean resumeOK = true; 11910 try { 11911 resumeOK = mController.activityResuming(next.packageName); 11912 } catch (RemoteException e) { 11913 mController = null; 11914 } 11915 11916 if (!resumeOK) { 11917 return false; 11918 } 11919 } 11920 } 11921 final long origId = Binder.clearCallingIdentity(); 11922 for (int i = start; i > finishTo; i--) { 11923 ActivityRecord r = history.get(i); 11924 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11925 "navigate-up"); 11926 // Only return the supplied result for the first activity finished 11927 resultCode = Activity.RESULT_CANCELED; 11928 resultData = null; 11929 } 11930 11931 if (parent != null && foundParentInTask) { 11932 final int parentLaunchMode = parent.info.launchMode; 11933 final int destIntentFlags = destIntent.getFlags(); 11934 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11935 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11936 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11937 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11938 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11939 } else { 11940 try { 11941 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11942 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 11943 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11944 null, aInfo, parent.appToken, null, 11945 0, -1, parent.launchedFromUid, 0, null, true, null); 11946 foundParentInTask = res == ActivityManager.START_SUCCESS; 11947 } catch (RemoteException e) { 11948 foundParentInTask = false; 11949 } 11950 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11951 resultData, "navigate-up"); 11952 } 11953 } 11954 Binder.restoreCallingIdentity(origId); 11955 return foundParentInTask; 11956 } 11957 } 11958 11959 public int getLaunchedFromUid(IBinder activityToken) { 11960 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11961 if (srec == null) { 11962 return -1; 11963 } 11964 return srec.launchedFromUid; 11965 } 11966 11967 // ========================================================= 11968 // LIFETIME MANAGEMENT 11969 // ========================================================= 11970 11971 // Returns which broadcast queue the app is the current [or imminent] receiver 11972 // on, or 'null' if the app is not an active broadcast recipient. 11973 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11974 BroadcastRecord r = app.curReceiver; 11975 if (r != null) { 11976 return r.queue; 11977 } 11978 11979 // It's not the current receiver, but it might be starting up to become one 11980 synchronized (this) { 11981 for (BroadcastQueue queue : mBroadcastQueues) { 11982 r = queue.mPendingBroadcast; 11983 if (r != null && r.curApp == app) { 11984 // found it; report which queue it's in 11985 return queue; 11986 } 11987 } 11988 } 11989 11990 return null; 11991 } 11992 11993 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 11994 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 11995 if (mAdjSeq == app.adjSeq) { 11996 // This adjustment has already been computed. If we are calling 11997 // from the top, we may have already computed our adjustment with 11998 // an earlier hidden adjustment that isn't really for us... if 11999 // so, use the new hidden adjustment. 12000 if (!recursed && app.hidden) { 12001 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12002 app.hasActivities ? hiddenAdj : emptyAdj; 12003 } 12004 return app.curRawAdj; 12005 } 12006 12007 if (app.thread == null) { 12008 app.adjSeq = mAdjSeq; 12009 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12010 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12011 } 12012 12013 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12014 app.adjSource = null; 12015 app.adjTarget = null; 12016 app.empty = false; 12017 app.hidden = false; 12018 12019 final int activitiesSize = app.activities.size(); 12020 12021 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12022 // The max adjustment doesn't allow this app to be anything 12023 // below foreground, so it is not worth doing work for it. 12024 app.adjType = "fixed"; 12025 app.adjSeq = mAdjSeq; 12026 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12027 app.hasActivities = false; 12028 app.foregroundActivities = false; 12029 app.keeping = true; 12030 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12031 // System process can do UI, and when they do we want to have 12032 // them trim their memory after the user leaves the UI. To 12033 // facilitate this, here we need to determine whether or not it 12034 // is currently showing UI. 12035 app.systemNoUi = true; 12036 if (app == TOP_APP) { 12037 app.systemNoUi = false; 12038 app.hasActivities = true; 12039 } else if (activitiesSize > 0) { 12040 for (int j = 0; j < activitiesSize; j++) { 12041 final ActivityRecord r = app.activities.get(j); 12042 if (r.visible) { 12043 app.systemNoUi = false; 12044 } 12045 if (r.app == app) { 12046 app.hasActivities = true; 12047 } 12048 } 12049 } 12050 return (app.curAdj=app.maxAdj); 12051 } 12052 12053 app.keeping = false; 12054 app.systemNoUi = false; 12055 app.hasActivities = false; 12056 12057 // Determine the importance of the process, starting with most 12058 // important to least, and assign an appropriate OOM adjustment. 12059 int adj; 12060 int schedGroup; 12061 boolean foregroundActivities = false; 12062 boolean interesting = false; 12063 BroadcastQueue queue; 12064 if (app == TOP_APP) { 12065 // The last app on the list is the foreground app. 12066 adj = ProcessList.FOREGROUND_APP_ADJ; 12067 schedGroup = Process.THREAD_GROUP_DEFAULT; 12068 app.adjType = "top-activity"; 12069 foregroundActivities = true; 12070 interesting = true; 12071 app.hasActivities = true; 12072 } else if (app.instrumentationClass != null) { 12073 // Don't want to kill running instrumentation. 12074 adj = ProcessList.FOREGROUND_APP_ADJ; 12075 schedGroup = Process.THREAD_GROUP_DEFAULT; 12076 app.adjType = "instrumentation"; 12077 interesting = true; 12078 } else if ((queue = isReceivingBroadcast(app)) != null) { 12079 // An app that is currently receiving a broadcast also 12080 // counts as being in the foreground for OOM killer purposes. 12081 // It's placed in a sched group based on the nature of the 12082 // broadcast as reflected by which queue it's active in. 12083 adj = ProcessList.FOREGROUND_APP_ADJ; 12084 schedGroup = (queue == mFgBroadcastQueue) 12085 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12086 app.adjType = "broadcast"; 12087 } else if (app.executingServices.size() > 0) { 12088 // An app that is currently executing a service callback also 12089 // counts as being in the foreground. 12090 adj = ProcessList.FOREGROUND_APP_ADJ; 12091 schedGroup = Process.THREAD_GROUP_DEFAULT; 12092 app.adjType = "exec-service"; 12093 } else { 12094 // Assume process is hidden (has activities); we will correct 12095 // later if this is not the case. 12096 adj = hiddenAdj; 12097 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12098 app.hidden = true; 12099 app.adjType = "bg-activities"; 12100 } 12101 12102 boolean hasStoppingActivities = false; 12103 12104 // Examine all activities if not already foreground. 12105 if (!foregroundActivities && activitiesSize > 0) { 12106 for (int j = 0; j < activitiesSize; j++) { 12107 final ActivityRecord r = app.activities.get(j); 12108 if (r.visible) { 12109 // App has a visible activity; only upgrade adjustment. 12110 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12111 adj = ProcessList.VISIBLE_APP_ADJ; 12112 app.adjType = "visible"; 12113 } 12114 schedGroup = Process.THREAD_GROUP_DEFAULT; 12115 app.hidden = false; 12116 app.hasActivities = true; 12117 foregroundActivities = true; 12118 break; 12119 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12120 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12121 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12122 app.adjType = "pausing"; 12123 } 12124 app.hidden = false; 12125 foregroundActivities = true; 12126 } else if (r.state == ActivityState.STOPPING) { 12127 // We will apply the actual adjustment later, because 12128 // we want to allow this process to immediately go through 12129 // any memory trimming that is in effect. 12130 app.hidden = false; 12131 foregroundActivities = true; 12132 hasStoppingActivities = true; 12133 } 12134 if (r.app == app) { 12135 app.hasActivities = true; 12136 } 12137 } 12138 } 12139 12140 if (adj == hiddenAdj && !app.hasActivities) { 12141 // Whoops, this process is completely empty as far as we know 12142 // at this point. 12143 adj = emptyAdj; 12144 app.empty = true; 12145 app.adjType = "bg-empty"; 12146 } 12147 12148 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12149 if (app.foregroundServices) { 12150 // The user is aware of this app, so make it visible. 12151 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12152 app.hidden = false; 12153 app.adjType = "foreground-service"; 12154 schedGroup = Process.THREAD_GROUP_DEFAULT; 12155 } else if (app.forcingToForeground != null) { 12156 // The user is aware of this app, so make it visible. 12157 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12158 app.hidden = false; 12159 app.adjType = "force-foreground"; 12160 app.adjSource = app.forcingToForeground; 12161 schedGroup = Process.THREAD_GROUP_DEFAULT; 12162 } 12163 } 12164 12165 if (app.foregroundServices) { 12166 interesting = true; 12167 } 12168 12169 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12170 // We don't want to kill the current heavy-weight process. 12171 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12172 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12173 app.hidden = false; 12174 app.adjType = "heavy"; 12175 } 12176 12177 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12178 // This process is hosting what we currently consider to be the 12179 // home app, so we don't want to let it go into the background. 12180 adj = ProcessList.HOME_APP_ADJ; 12181 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12182 app.hidden = false; 12183 app.adjType = "home"; 12184 } 12185 12186 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12187 && app.activities.size() > 0) { 12188 // This was the previous process that showed UI to the user. 12189 // We want to try to keep it around more aggressively, to give 12190 // a good experience around switching between two apps. 12191 adj = ProcessList.PREVIOUS_APP_ADJ; 12192 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12193 app.hidden = false; 12194 app.adjType = "previous"; 12195 } 12196 12197 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12198 + " reason=" + app.adjType); 12199 12200 // By default, we use the computed adjustment. It may be changed if 12201 // there are applications dependent on our services or providers, but 12202 // this gives us a baseline and makes sure we don't get into an 12203 // infinite recursion. 12204 app.adjSeq = mAdjSeq; 12205 app.curRawAdj = app.nonStoppingAdj = adj; 12206 12207 if (mBackupTarget != null && app == mBackupTarget.app) { 12208 // If possible we want to avoid killing apps while they're being backed up 12209 if (adj > ProcessList.BACKUP_APP_ADJ) { 12210 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12211 adj = ProcessList.BACKUP_APP_ADJ; 12212 app.adjType = "backup"; 12213 app.hidden = false; 12214 } 12215 } 12216 12217 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12218 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12219 final long now = SystemClock.uptimeMillis(); 12220 // This process is more important if the top activity is 12221 // bound to the service. 12222 Iterator<ServiceRecord> jt = app.services.iterator(); 12223 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12224 ServiceRecord s = jt.next(); 12225 if (s.startRequested) { 12226 if (app.hasShownUi && app != mHomeProcess) { 12227 // If this process has shown some UI, let it immediately 12228 // go to the LRU list because it may be pretty heavy with 12229 // UI stuff. We'll tag it with a label just to help 12230 // debug and understand what is going on. 12231 if (adj > ProcessList.SERVICE_ADJ) { 12232 app.adjType = "started-bg-ui-services"; 12233 } 12234 } else { 12235 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12236 // This service has seen some activity within 12237 // recent memory, so we will keep its process ahead 12238 // of the background processes. 12239 if (adj > ProcessList.SERVICE_ADJ) { 12240 adj = ProcessList.SERVICE_ADJ; 12241 app.adjType = "started-services"; 12242 app.hidden = false; 12243 } 12244 } 12245 // If we have let the service slide into the background 12246 // state, still have some text describing what it is doing 12247 // even though the service no longer has an impact. 12248 if (adj > ProcessList.SERVICE_ADJ) { 12249 app.adjType = "started-bg-services"; 12250 } 12251 } 12252 // Don't kill this process because it is doing work; it 12253 // has said it is doing work. 12254 app.keeping = true; 12255 } 12256 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12257 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12258 Iterator<ArrayList<ConnectionRecord>> kt 12259 = s.connections.values().iterator(); 12260 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12261 ArrayList<ConnectionRecord> clist = kt.next(); 12262 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12263 // XXX should compute this based on the max of 12264 // all connected clients. 12265 ConnectionRecord cr = clist.get(i); 12266 if (cr.binding.client == app) { 12267 // Binding to ourself is not interesting. 12268 continue; 12269 } 12270 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12271 ProcessRecord client = cr.binding.client; 12272 int clientAdj = adj; 12273 int myHiddenAdj = hiddenAdj; 12274 if (myHiddenAdj > client.hiddenAdj) { 12275 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12276 myHiddenAdj = client.hiddenAdj; 12277 } else { 12278 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12279 } 12280 } 12281 int myEmptyAdj = emptyAdj; 12282 if (myEmptyAdj > client.emptyAdj) { 12283 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12284 myEmptyAdj = client.emptyAdj; 12285 } else { 12286 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12287 } 12288 } 12289 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12290 myEmptyAdj, TOP_APP, true, doingAll); 12291 String adjType = null; 12292 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12293 // Not doing bind OOM management, so treat 12294 // this guy more like a started service. 12295 if (app.hasShownUi && app != mHomeProcess) { 12296 // If this process has shown some UI, let it immediately 12297 // go to the LRU list because it may be pretty heavy with 12298 // UI stuff. We'll tag it with a label just to help 12299 // debug and understand what is going on. 12300 if (adj > clientAdj) { 12301 adjType = "bound-bg-ui-services"; 12302 } 12303 app.hidden = false; 12304 clientAdj = adj; 12305 } else { 12306 if (now >= (s.lastActivity 12307 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12308 // This service has not seen activity within 12309 // recent memory, so allow it to drop to the 12310 // LRU list if there is no other reason to keep 12311 // it around. We'll also tag it with a label just 12312 // to help debug and undertand what is going on. 12313 if (adj > clientAdj) { 12314 adjType = "bound-bg-services"; 12315 } 12316 clientAdj = adj; 12317 } 12318 } 12319 } 12320 if (adj > clientAdj) { 12321 // If this process has recently shown UI, and 12322 // the process that is binding to it is less 12323 // important than being visible, then we don't 12324 // care about the binding as much as we care 12325 // about letting this process get into the LRU 12326 // list to be killed and restarted if needed for 12327 // memory. 12328 if (app.hasShownUi && app != mHomeProcess 12329 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12330 adjType = "bound-bg-ui-services"; 12331 } else { 12332 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12333 |Context.BIND_IMPORTANT)) != 0) { 12334 adj = clientAdj; 12335 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12336 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12337 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12338 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12339 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12340 adj = clientAdj; 12341 } else { 12342 app.pendingUiClean = true; 12343 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12344 adj = ProcessList.VISIBLE_APP_ADJ; 12345 } 12346 } 12347 if (!client.hidden) { 12348 app.hidden = false; 12349 } 12350 if (client.keeping) { 12351 app.keeping = true; 12352 } 12353 adjType = "service"; 12354 } 12355 } 12356 if (adjType != null) { 12357 app.adjType = adjType; 12358 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12359 .REASON_SERVICE_IN_USE; 12360 app.adjSource = cr.binding.client; 12361 app.adjSourceOom = clientAdj; 12362 app.adjTarget = s.name; 12363 } 12364 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12365 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12366 schedGroup = Process.THREAD_GROUP_DEFAULT; 12367 } 12368 } 12369 } 12370 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12371 ActivityRecord a = cr.activity; 12372 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12373 (a.visible || a.state == ActivityState.RESUMED 12374 || a.state == ActivityState.PAUSING)) { 12375 adj = ProcessList.FOREGROUND_APP_ADJ; 12376 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12377 schedGroup = Process.THREAD_GROUP_DEFAULT; 12378 } 12379 app.hidden = false; 12380 app.adjType = "service"; 12381 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12382 .REASON_SERVICE_IN_USE; 12383 app.adjSource = a; 12384 app.adjSourceOom = adj; 12385 app.adjTarget = s.name; 12386 } 12387 } 12388 } 12389 } 12390 } 12391 } 12392 12393 // Finally, if this process has active services running in it, we 12394 // would like to avoid killing it unless it would prevent the current 12395 // application from running. By default we put the process in 12396 // with the rest of the background processes; as we scan through 12397 // its services we may bump it up from there. 12398 if (adj > hiddenAdj) { 12399 adj = hiddenAdj; 12400 app.hidden = false; 12401 app.adjType = "bg-services"; 12402 } 12403 } 12404 12405 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12406 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12407 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12408 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12409 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12410 ContentProviderRecord cpr = jt.next(); 12411 for (int i = cpr.connections.size()-1; 12412 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12413 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12414 i--) { 12415 ContentProviderConnection conn = cpr.connections.get(i); 12416 ProcessRecord client = conn.client; 12417 if (client == app) { 12418 // Being our own client is not interesting. 12419 continue; 12420 } 12421 int myHiddenAdj = hiddenAdj; 12422 if (myHiddenAdj > client.hiddenAdj) { 12423 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12424 myHiddenAdj = client.hiddenAdj; 12425 } else { 12426 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12427 } 12428 } 12429 int myEmptyAdj = emptyAdj; 12430 if (myEmptyAdj > client.emptyAdj) { 12431 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12432 myEmptyAdj = client.emptyAdj; 12433 } else { 12434 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12435 } 12436 } 12437 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12438 myEmptyAdj, TOP_APP, true, doingAll); 12439 if (adj > clientAdj) { 12440 if (app.hasShownUi && app != mHomeProcess 12441 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12442 app.adjType = "bg-ui-provider"; 12443 } else { 12444 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12445 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12446 app.adjType = "provider"; 12447 } 12448 if (!client.hidden) { 12449 app.hidden = false; 12450 } 12451 if (client.keeping) { 12452 app.keeping = true; 12453 } 12454 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12455 .REASON_PROVIDER_IN_USE; 12456 app.adjSource = client; 12457 app.adjSourceOom = clientAdj; 12458 app.adjTarget = cpr.name; 12459 } 12460 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12461 schedGroup = Process.THREAD_GROUP_DEFAULT; 12462 } 12463 } 12464 // If the provider has external (non-framework) process 12465 // dependencies, ensure that its adjustment is at least 12466 // FOREGROUND_APP_ADJ. 12467 if (cpr.hasExternalProcessHandles()) { 12468 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12469 adj = ProcessList.FOREGROUND_APP_ADJ; 12470 schedGroup = Process.THREAD_GROUP_DEFAULT; 12471 app.hidden = false; 12472 app.keeping = true; 12473 app.adjType = "provider"; 12474 app.adjTarget = cpr.name; 12475 } 12476 } 12477 } 12478 } 12479 12480 if (adj == ProcessList.SERVICE_ADJ) { 12481 if (doingAll) { 12482 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12483 mNewNumServiceProcs++; 12484 } 12485 if (app.serviceb) { 12486 adj = ProcessList.SERVICE_B_ADJ; 12487 } 12488 } else { 12489 app.serviceb = false; 12490 } 12491 12492 app.nonStoppingAdj = adj; 12493 12494 if (hasStoppingActivities) { 12495 // Only upgrade adjustment. 12496 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12497 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12498 app.adjType = "stopping"; 12499 } 12500 } 12501 12502 app.curRawAdj = adj; 12503 12504 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12505 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12506 if (adj > app.maxAdj) { 12507 adj = app.maxAdj; 12508 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12509 schedGroup = Process.THREAD_GROUP_DEFAULT; 12510 } 12511 } 12512 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12513 app.keeping = true; 12514 } 12515 12516 if (app.hasAboveClient) { 12517 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12518 // then we need to drop its adjustment to be lower than the service's 12519 // in order to honor the request. We want to drop it by one adjustment 12520 // level... but there is special meaning applied to various levels so 12521 // we will skip some of them. 12522 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12523 // System process will not get dropped, ever 12524 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12525 adj = ProcessList.VISIBLE_APP_ADJ; 12526 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12527 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12528 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12529 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12530 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12531 adj++; 12532 } 12533 } 12534 12535 int importance = app.memImportance; 12536 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12537 app.curAdj = adj; 12538 app.curSchedGroup = schedGroup; 12539 if (!interesting) { 12540 // For this reporting, if there is not something explicitly 12541 // interesting in this process then we will push it to the 12542 // background importance. 12543 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12544 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12545 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12546 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12547 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12548 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12549 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12550 } else if (adj >= ProcessList.SERVICE_ADJ) { 12551 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12552 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12553 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12554 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12555 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12556 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12557 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12558 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12559 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12560 } else { 12561 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12562 } 12563 } 12564 12565 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12566 if (foregroundActivities != app.foregroundActivities) { 12567 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12568 } 12569 if (changes != 0) { 12570 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12571 app.memImportance = importance; 12572 app.foregroundActivities = foregroundActivities; 12573 int i = mPendingProcessChanges.size()-1; 12574 ProcessChangeItem item = null; 12575 while (i >= 0) { 12576 item = mPendingProcessChanges.get(i); 12577 if (item.pid == app.pid) { 12578 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12579 break; 12580 } 12581 i--; 12582 } 12583 if (i < 0) { 12584 // No existing item in pending changes; need a new one. 12585 final int NA = mAvailProcessChanges.size(); 12586 if (NA > 0) { 12587 item = mAvailProcessChanges.remove(NA-1); 12588 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12589 } else { 12590 item = new ProcessChangeItem(); 12591 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12592 } 12593 item.changes = 0; 12594 item.pid = app.pid; 12595 item.uid = app.info.uid; 12596 if (mPendingProcessChanges.size() == 0) { 12597 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12598 "*** Enqueueing dispatch processes changed!"); 12599 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12600 } 12601 mPendingProcessChanges.add(item); 12602 } 12603 item.changes |= changes; 12604 item.importance = importance; 12605 item.foregroundActivities = foregroundActivities; 12606 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12607 + Integer.toHexString(System.identityHashCode(item)) 12608 + " " + app.toShortString() + ": changes=" + item.changes 12609 + " importance=" + item.importance 12610 + " foreground=" + item.foregroundActivities 12611 + " type=" + app.adjType + " source=" + app.adjSource 12612 + " target=" + app.adjTarget); 12613 } 12614 12615 return app.curRawAdj; 12616 } 12617 12618 /** 12619 * Ask a given process to GC right now. 12620 */ 12621 final void performAppGcLocked(ProcessRecord app) { 12622 try { 12623 app.lastRequestedGc = SystemClock.uptimeMillis(); 12624 if (app.thread != null) { 12625 if (app.reportLowMemory) { 12626 app.reportLowMemory = false; 12627 app.thread.scheduleLowMemory(); 12628 } else { 12629 app.thread.processInBackground(); 12630 } 12631 } 12632 } catch (Exception e) { 12633 // whatever. 12634 } 12635 } 12636 12637 /** 12638 * Returns true if things are idle enough to perform GCs. 12639 */ 12640 private final boolean canGcNowLocked() { 12641 boolean processingBroadcasts = false; 12642 for (BroadcastQueue q : mBroadcastQueues) { 12643 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12644 processingBroadcasts = true; 12645 } 12646 } 12647 return !processingBroadcasts 12648 && (mSleeping || (mMainStack.mResumedActivity != null && 12649 mMainStack.mResumedActivity.idle)); 12650 } 12651 12652 /** 12653 * Perform GCs on all processes that are waiting for it, but only 12654 * if things are idle. 12655 */ 12656 final void performAppGcsLocked() { 12657 final int N = mProcessesToGc.size(); 12658 if (N <= 0) { 12659 return; 12660 } 12661 if (canGcNowLocked()) { 12662 while (mProcessesToGc.size() > 0) { 12663 ProcessRecord proc = mProcessesToGc.remove(0); 12664 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12665 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12666 <= SystemClock.uptimeMillis()) { 12667 // To avoid spamming the system, we will GC processes one 12668 // at a time, waiting a few seconds between each. 12669 performAppGcLocked(proc); 12670 scheduleAppGcsLocked(); 12671 return; 12672 } else { 12673 // It hasn't been long enough since we last GCed this 12674 // process... put it in the list to wait for its time. 12675 addProcessToGcListLocked(proc); 12676 break; 12677 } 12678 } 12679 } 12680 12681 scheduleAppGcsLocked(); 12682 } 12683 } 12684 12685 /** 12686 * If all looks good, perform GCs on all processes waiting for them. 12687 */ 12688 final void performAppGcsIfAppropriateLocked() { 12689 if (canGcNowLocked()) { 12690 performAppGcsLocked(); 12691 return; 12692 } 12693 // Still not idle, wait some more. 12694 scheduleAppGcsLocked(); 12695 } 12696 12697 /** 12698 * Schedule the execution of all pending app GCs. 12699 */ 12700 final void scheduleAppGcsLocked() { 12701 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12702 12703 if (mProcessesToGc.size() > 0) { 12704 // Schedule a GC for the time to the next process. 12705 ProcessRecord proc = mProcessesToGc.get(0); 12706 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12707 12708 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12709 long now = SystemClock.uptimeMillis(); 12710 if (when < (now+GC_TIMEOUT)) { 12711 when = now + GC_TIMEOUT; 12712 } 12713 mHandler.sendMessageAtTime(msg, when); 12714 } 12715 } 12716 12717 /** 12718 * Add a process to the array of processes waiting to be GCed. Keeps the 12719 * list in sorted order by the last GC time. The process can't already be 12720 * on the list. 12721 */ 12722 final void addProcessToGcListLocked(ProcessRecord proc) { 12723 boolean added = false; 12724 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12725 if (mProcessesToGc.get(i).lastRequestedGc < 12726 proc.lastRequestedGc) { 12727 added = true; 12728 mProcessesToGc.add(i+1, proc); 12729 break; 12730 } 12731 } 12732 if (!added) { 12733 mProcessesToGc.add(0, proc); 12734 } 12735 } 12736 12737 /** 12738 * Set up to ask a process to GC itself. This will either do it 12739 * immediately, or put it on the list of processes to gc the next 12740 * time things are idle. 12741 */ 12742 final void scheduleAppGcLocked(ProcessRecord app) { 12743 long now = SystemClock.uptimeMillis(); 12744 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12745 return; 12746 } 12747 if (!mProcessesToGc.contains(app)) { 12748 addProcessToGcListLocked(app); 12749 scheduleAppGcsLocked(); 12750 } 12751 } 12752 12753 final void checkExcessivePowerUsageLocked(boolean doKills) { 12754 updateCpuStatsNow(); 12755 12756 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12757 boolean doWakeKills = doKills; 12758 boolean doCpuKills = doKills; 12759 if (mLastPowerCheckRealtime == 0) { 12760 doWakeKills = false; 12761 } 12762 if (mLastPowerCheckUptime == 0) { 12763 doCpuKills = false; 12764 } 12765 if (stats.isScreenOn()) { 12766 doWakeKills = false; 12767 } 12768 final long curRealtime = SystemClock.elapsedRealtime(); 12769 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12770 final long curUptime = SystemClock.uptimeMillis(); 12771 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12772 mLastPowerCheckRealtime = curRealtime; 12773 mLastPowerCheckUptime = curUptime; 12774 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12775 doWakeKills = false; 12776 } 12777 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12778 doCpuKills = false; 12779 } 12780 int i = mLruProcesses.size(); 12781 while (i > 0) { 12782 i--; 12783 ProcessRecord app = mLruProcesses.get(i); 12784 if (!app.keeping) { 12785 long wtime; 12786 synchronized (stats) { 12787 wtime = stats.getProcessWakeTime(app.info.uid, 12788 app.pid, curRealtime); 12789 } 12790 long wtimeUsed = wtime - app.lastWakeTime; 12791 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12792 if (DEBUG_POWER) { 12793 StringBuilder sb = new StringBuilder(128); 12794 sb.append("Wake for "); 12795 app.toShortString(sb); 12796 sb.append(": over "); 12797 TimeUtils.formatDuration(realtimeSince, sb); 12798 sb.append(" used "); 12799 TimeUtils.formatDuration(wtimeUsed, sb); 12800 sb.append(" ("); 12801 sb.append((wtimeUsed*100)/realtimeSince); 12802 sb.append("%)"); 12803 Slog.i(TAG, sb.toString()); 12804 sb.setLength(0); 12805 sb.append("CPU for "); 12806 app.toShortString(sb); 12807 sb.append(": over "); 12808 TimeUtils.formatDuration(uptimeSince, sb); 12809 sb.append(" used "); 12810 TimeUtils.formatDuration(cputimeUsed, sb); 12811 sb.append(" ("); 12812 sb.append((cputimeUsed*100)/uptimeSince); 12813 sb.append("%)"); 12814 Slog.i(TAG, sb.toString()); 12815 } 12816 // If a process has held a wake lock for more 12817 // than 50% of the time during this period, 12818 // that sounds bad. Kill! 12819 if (doWakeKills && realtimeSince > 0 12820 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12821 synchronized (stats) { 12822 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12823 realtimeSince, wtimeUsed); 12824 } 12825 Slog.w(TAG, "Excessive wake lock in " + app.processName 12826 + " (pid " + app.pid + "): held " + wtimeUsed 12827 + " during " + realtimeSince); 12828 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12829 app.processName, app.setAdj, "excessive wake lock"); 12830 Process.killProcessQuiet(app.pid); 12831 } else if (doCpuKills && uptimeSince > 0 12832 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12833 synchronized (stats) { 12834 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12835 uptimeSince, cputimeUsed); 12836 } 12837 Slog.w(TAG, "Excessive CPU in " + app.processName 12838 + " (pid " + app.pid + "): used " + cputimeUsed 12839 + " during " + uptimeSince); 12840 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12841 app.processName, app.setAdj, "excessive cpu"); 12842 Process.killProcessQuiet(app.pid); 12843 } else { 12844 app.lastWakeTime = wtime; 12845 app.lastCpuTime = app.curCpuTime; 12846 } 12847 } 12848 } 12849 } 12850 12851 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12852 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12853 app.hiddenAdj = hiddenAdj; 12854 app.emptyAdj = emptyAdj; 12855 12856 if (app.thread == null) { 12857 return false; 12858 } 12859 12860 final boolean wasKeeping = app.keeping; 12861 12862 boolean success = true; 12863 12864 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12865 12866 if (app.curRawAdj != app.setRawAdj) { 12867 if (wasKeeping && !app.keeping) { 12868 // This app is no longer something we want to keep. Note 12869 // its current wake lock time to later know to kill it if 12870 // it is not behaving well. 12871 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12872 synchronized (stats) { 12873 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12874 app.pid, SystemClock.elapsedRealtime()); 12875 } 12876 app.lastCpuTime = app.curCpuTime; 12877 } 12878 12879 app.setRawAdj = app.curRawAdj; 12880 } 12881 12882 if (app.curAdj != app.setAdj) { 12883 if (Process.setOomAdj(app.pid, app.curAdj)) { 12884 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12885 TAG, "Set " + app.pid + " " + app.processName + 12886 " adj " + app.curAdj + ": " + app.adjType); 12887 app.setAdj = app.curAdj; 12888 } else { 12889 success = false; 12890 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12891 } 12892 } 12893 if (app.setSchedGroup != app.curSchedGroup) { 12894 app.setSchedGroup = app.curSchedGroup; 12895 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12896 "Setting process group of " + app.processName 12897 + " to " + app.curSchedGroup); 12898 if (app.waitingToKill != null && 12899 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12900 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12901 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12902 app.processName, app.setAdj, app.waitingToKill); 12903 app.killedBackground = true; 12904 Process.killProcessQuiet(app.pid); 12905 success = false; 12906 } else { 12907 if (true) { 12908 long oldId = Binder.clearCallingIdentity(); 12909 try { 12910 Process.setProcessGroup(app.pid, app.curSchedGroup); 12911 } catch (Exception e) { 12912 Slog.w(TAG, "Failed setting process group of " + app.pid 12913 + " to " + app.curSchedGroup); 12914 e.printStackTrace(); 12915 } finally { 12916 Binder.restoreCallingIdentity(oldId); 12917 } 12918 } else { 12919 if (app.thread != null) { 12920 try { 12921 app.thread.setSchedulingGroup(app.curSchedGroup); 12922 } catch (RemoteException e) { 12923 } 12924 } 12925 } 12926 } 12927 } 12928 return success; 12929 } 12930 12931 private final ActivityRecord resumedAppLocked() { 12932 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12933 if (resumedActivity == null || resumedActivity.app == null) { 12934 resumedActivity = mMainStack.mPausingActivity; 12935 if (resumedActivity == null || resumedActivity.app == null) { 12936 resumedActivity = mMainStack.topRunningActivityLocked(null); 12937 } 12938 } 12939 return resumedActivity; 12940 } 12941 12942 final boolean updateOomAdjLocked(ProcessRecord app) { 12943 final ActivityRecord TOP_ACT = resumedAppLocked(); 12944 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12945 int curAdj = app.curAdj; 12946 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12947 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12948 12949 mAdjSeq++; 12950 12951 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 12952 TOP_APP, false); 12953 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12954 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12955 if (nowHidden != wasHidden) { 12956 // Changed to/from hidden state, so apps after it in the LRU 12957 // list may also be changed. 12958 updateOomAdjLocked(); 12959 } 12960 return success; 12961 } 12962 12963 final void updateOomAdjLocked() { 12964 final ActivityRecord TOP_ACT = resumedAppLocked(); 12965 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12966 12967 if (false) { 12968 RuntimeException e = new RuntimeException(); 12969 e.fillInStackTrace(); 12970 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12971 } 12972 12973 mAdjSeq++; 12974 mNewNumServiceProcs = 0; 12975 12976 // Let's determine how many processes we have running vs. 12977 // how many slots we have for background processes; we may want 12978 // to put multiple processes in a slot of there are enough of 12979 // them. 12980 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 12981 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 12982 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 12983 if (emptyFactor < 1) emptyFactor = 1; 12984 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 12985 if (hiddenFactor < 1) hiddenFactor = 1; 12986 int stepHidden = 0; 12987 int stepEmpty = 0; 12988 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 12989 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 12990 int numHidden = 0; 12991 int numEmpty = 0; 12992 int numTrimming = 0; 12993 12994 mNumNonHiddenProcs = 0; 12995 mNumHiddenProcs = 0; 12996 12997 // First update the OOM adjustment for each of the 12998 // application processes based on their current state. 12999 int i = mLruProcesses.size(); 13000 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13001 int nextHiddenAdj = curHiddenAdj+1; 13002 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13003 int nextEmptyAdj = curEmptyAdj+2; 13004 while (i > 0) { 13005 i--; 13006 ProcessRecord app = mLruProcesses.get(i); 13007 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13008 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13009 if (!app.killedBackground) { 13010 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13011 // This process was assigned as a hidden process... step the 13012 // hidden level. 13013 mNumHiddenProcs++; 13014 if (curHiddenAdj != nextHiddenAdj) { 13015 stepHidden++; 13016 if (stepHidden >= hiddenFactor) { 13017 stepHidden = 0; 13018 curHiddenAdj = nextHiddenAdj; 13019 nextHiddenAdj += 2; 13020 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13021 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13022 } 13023 } 13024 } 13025 numHidden++; 13026 if (numHidden > hiddenProcessLimit) { 13027 Slog.i(TAG, "No longer want " + app.processName 13028 + " (pid " + app.pid + "): hidden #" + numHidden); 13029 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13030 app.processName, app.setAdj, "too many background"); 13031 app.killedBackground = true; 13032 Process.killProcessQuiet(app.pid); 13033 } 13034 } else { 13035 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13036 // This process was assigned as an empty process... step the 13037 // empty level. 13038 if (curEmptyAdj != nextEmptyAdj) { 13039 stepEmpty++; 13040 if (stepEmpty >= emptyFactor) { 13041 stepEmpty = 0; 13042 curEmptyAdj = nextEmptyAdj; 13043 nextEmptyAdj += 2; 13044 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13045 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13046 } 13047 } 13048 } 13049 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13050 mNumNonHiddenProcs++; 13051 } 13052 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13053 numEmpty++; 13054 if (numEmpty > emptyProcessLimit) { 13055 Slog.i(TAG, "No longer want " + app.processName 13056 + " (pid " + app.pid + "): empty #" + numEmpty); 13057 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13058 app.processName, app.setAdj, "too many background"); 13059 app.killedBackground = true; 13060 Process.killProcessQuiet(app.pid); 13061 } 13062 } 13063 } 13064 if (app.isolated && app.services.size() <= 0) { 13065 // If this is an isolated process, and there are no 13066 // services running in it, then the process is no longer 13067 // needed. We agressively kill these because we can by 13068 // definition not re-use the same process again, and it is 13069 // good to avoid having whatever code was running in them 13070 // left sitting around after no longer needed. 13071 Slog.i(TAG, "Isolated process " + app.processName 13072 + " (pid " + app.pid + ") no longer needed"); 13073 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13074 app.processName, app.setAdj, "isolated not needed"); 13075 app.killedBackground = true; 13076 Process.killProcessQuiet(app.pid); 13077 } 13078 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13079 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13080 && !app.killedBackground) { 13081 numTrimming++; 13082 } 13083 } 13084 } 13085 13086 mNumServiceProcs = mNewNumServiceProcs; 13087 13088 // Now determine the memory trimming level of background processes. 13089 // Unfortunately we need to start at the back of the list to do this 13090 // properly. We only do this if the number of background apps we 13091 // are managing to keep around is less than half the maximum we desire; 13092 // if we are keeping a good number around, we'll let them use whatever 13093 // memory they want. 13094 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13095 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13096 final int numHiddenAndEmpty = numHidden + numEmpty; 13097 final int N = mLruProcesses.size(); 13098 int factor = numTrimming/3; 13099 int minFactor = 2; 13100 if (mHomeProcess != null) minFactor++; 13101 if (mPreviousProcess != null) minFactor++; 13102 if (factor < minFactor) factor = minFactor; 13103 int step = 0; 13104 int fgTrimLevel; 13105 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13106 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13107 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13108 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13109 } else { 13110 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13111 } 13112 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13113 for (i=0; i<N; i++) { 13114 ProcessRecord app = mLruProcesses.get(i); 13115 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13116 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13117 && !app.killedBackground) { 13118 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13119 try { 13120 app.thread.scheduleTrimMemory(curLevel); 13121 } catch (RemoteException e) { 13122 } 13123 if (false) { 13124 // For now we won't do this; our memory trimming seems 13125 // to be good enough at this point that destroying 13126 // activities causes more harm than good. 13127 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13128 && app != mHomeProcess && app != mPreviousProcess) { 13129 // Need to do this on its own message because the stack may not 13130 // be in a consistent state at this point. 13131 // For these apps we will also finish their activities 13132 // to help them free memory. 13133 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13134 } 13135 } 13136 } 13137 app.trimMemoryLevel = curLevel; 13138 step++; 13139 if (step >= factor) { 13140 step = 0; 13141 switch (curLevel) { 13142 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13143 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13144 break; 13145 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13146 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13147 break; 13148 } 13149 } 13150 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13151 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13152 && app.thread != null) { 13153 try { 13154 app.thread.scheduleTrimMemory( 13155 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13156 } catch (RemoteException e) { 13157 } 13158 } 13159 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13160 } else { 13161 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13162 && app.pendingUiClean) { 13163 // If this application is now in the background and it 13164 // had done UI, then give it the special trim level to 13165 // have it free UI resources. 13166 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13167 if (app.trimMemoryLevel < level && app.thread != null) { 13168 try { 13169 app.thread.scheduleTrimMemory(level); 13170 } catch (RemoteException e) { 13171 } 13172 } 13173 app.pendingUiClean = false; 13174 } 13175 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13176 try { 13177 app.thread.scheduleTrimMemory(fgTrimLevel); 13178 } catch (RemoteException e) { 13179 } 13180 } 13181 app.trimMemoryLevel = fgTrimLevel; 13182 } 13183 } 13184 } else { 13185 final int N = mLruProcesses.size(); 13186 for (i=0; i<N; i++) { 13187 ProcessRecord app = mLruProcesses.get(i); 13188 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13189 && app.pendingUiClean) { 13190 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13191 && app.thread != null) { 13192 try { 13193 app.thread.scheduleTrimMemory( 13194 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13195 } catch (RemoteException e) { 13196 } 13197 } 13198 app.pendingUiClean = false; 13199 } 13200 app.trimMemoryLevel = 0; 13201 } 13202 } 13203 13204 if (mAlwaysFinishActivities) { 13205 // Need to do this on its own message because the stack may not 13206 // be in a consistent state at this point. 13207 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13208 } 13209 } 13210 13211 final void trimApplications() { 13212 synchronized (this) { 13213 int i; 13214 13215 // First remove any unused application processes whose package 13216 // has been removed. 13217 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13218 final ProcessRecord app = mRemovedProcesses.get(i); 13219 if (app.activities.size() == 0 13220 && app.curReceiver == null && app.services.size() == 0) { 13221 Slog.i( 13222 TAG, "Exiting empty application process " 13223 + app.processName + " (" 13224 + (app.thread != null ? app.thread.asBinder() : null) 13225 + ")\n"); 13226 if (app.pid > 0 && app.pid != MY_PID) { 13227 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13228 app.processName, app.setAdj, "empty"); 13229 Process.killProcessQuiet(app.pid); 13230 } else { 13231 try { 13232 app.thread.scheduleExit(); 13233 } catch (Exception e) { 13234 // Ignore exceptions. 13235 } 13236 } 13237 cleanUpApplicationRecordLocked(app, false, true, -1); 13238 mRemovedProcesses.remove(i); 13239 13240 if (app.persistent) { 13241 if (app.persistent) { 13242 addAppLocked(app.info, false); 13243 } 13244 } 13245 } 13246 } 13247 13248 // Now update the oom adj for all processes. 13249 updateOomAdjLocked(); 13250 } 13251 } 13252 13253 /** This method sends the specified signal to each of the persistent apps */ 13254 public void signalPersistentProcesses(int sig) throws RemoteException { 13255 if (sig != Process.SIGNAL_USR1) { 13256 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13257 } 13258 13259 synchronized (this) { 13260 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13261 != PackageManager.PERMISSION_GRANTED) { 13262 throw new SecurityException("Requires permission " 13263 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13264 } 13265 13266 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13267 ProcessRecord r = mLruProcesses.get(i); 13268 if (r.thread != null && r.persistent) { 13269 Process.sendSignal(r.pid, sig); 13270 } 13271 } 13272 } 13273 } 13274 13275 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13276 if (proc == null || proc == mProfileProc) { 13277 proc = mProfileProc; 13278 path = mProfileFile; 13279 profileType = mProfileType; 13280 clearProfilerLocked(); 13281 } 13282 if (proc == null) { 13283 return; 13284 } 13285 try { 13286 proc.thread.profilerControl(false, path, null, profileType); 13287 } catch (RemoteException e) { 13288 throw new IllegalStateException("Process disappeared"); 13289 } 13290 } 13291 13292 private void clearProfilerLocked() { 13293 if (mProfileFd != null) { 13294 try { 13295 mProfileFd.close(); 13296 } catch (IOException e) { 13297 } 13298 } 13299 mProfileApp = null; 13300 mProfileProc = null; 13301 mProfileFile = null; 13302 mProfileType = 0; 13303 mAutoStopProfiler = false; 13304 } 13305 13306 public boolean profileControl(String process, boolean start, 13307 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13308 13309 try { 13310 synchronized (this) { 13311 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13312 // its own permission. 13313 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13314 != PackageManager.PERMISSION_GRANTED) { 13315 throw new SecurityException("Requires permission " 13316 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13317 } 13318 13319 if (start && fd == null) { 13320 throw new IllegalArgumentException("null fd"); 13321 } 13322 13323 ProcessRecord proc = null; 13324 if (process != null) { 13325 try { 13326 int pid = Integer.parseInt(process); 13327 synchronized (mPidsSelfLocked) { 13328 proc = mPidsSelfLocked.get(pid); 13329 } 13330 } catch (NumberFormatException e) { 13331 } 13332 13333 if (proc == null) { 13334 HashMap<String, SparseArray<ProcessRecord>> all 13335 = mProcessNames.getMap(); 13336 SparseArray<ProcessRecord> procs = all.get(process); 13337 if (procs != null && procs.size() > 0) { 13338 proc = procs.valueAt(0); 13339 } 13340 } 13341 } 13342 13343 if (start && (proc == null || proc.thread == null)) { 13344 throw new IllegalArgumentException("Unknown process: " + process); 13345 } 13346 13347 if (start) { 13348 stopProfilerLocked(null, null, 0); 13349 setProfileApp(proc.info, proc.processName, path, fd, false); 13350 mProfileProc = proc; 13351 mProfileType = profileType; 13352 try { 13353 fd = fd.dup(); 13354 } catch (IOException e) { 13355 fd = null; 13356 } 13357 proc.thread.profilerControl(start, path, fd, profileType); 13358 fd = null; 13359 mProfileFd = null; 13360 } else { 13361 stopProfilerLocked(proc, path, profileType); 13362 if (fd != null) { 13363 try { 13364 fd.close(); 13365 } catch (IOException e) { 13366 } 13367 } 13368 } 13369 13370 return true; 13371 } 13372 } catch (RemoteException e) { 13373 throw new IllegalStateException("Process disappeared"); 13374 } finally { 13375 if (fd != null) { 13376 try { 13377 fd.close(); 13378 } catch (IOException e) { 13379 } 13380 } 13381 } 13382 } 13383 13384 public boolean dumpHeap(String process, boolean managed, 13385 String path, ParcelFileDescriptor fd) throws RemoteException { 13386 13387 try { 13388 synchronized (this) { 13389 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13390 // its own permission (same as profileControl). 13391 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13392 != PackageManager.PERMISSION_GRANTED) { 13393 throw new SecurityException("Requires permission " 13394 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13395 } 13396 13397 if (fd == null) { 13398 throw new IllegalArgumentException("null fd"); 13399 } 13400 13401 ProcessRecord proc = null; 13402 try { 13403 int pid = Integer.parseInt(process); 13404 synchronized (mPidsSelfLocked) { 13405 proc = mPidsSelfLocked.get(pid); 13406 } 13407 } catch (NumberFormatException e) { 13408 } 13409 13410 if (proc == null) { 13411 HashMap<String, SparseArray<ProcessRecord>> all 13412 = mProcessNames.getMap(); 13413 SparseArray<ProcessRecord> procs = all.get(process); 13414 if (procs != null && procs.size() > 0) { 13415 proc = procs.valueAt(0); 13416 } 13417 } 13418 13419 if (proc == null || proc.thread == null) { 13420 throw new IllegalArgumentException("Unknown process: " + process); 13421 } 13422 13423 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13424 if (!isDebuggable) { 13425 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13426 throw new SecurityException("Process not debuggable: " + proc); 13427 } 13428 } 13429 13430 proc.thread.dumpHeap(managed, path, fd); 13431 fd = null; 13432 return true; 13433 } 13434 } catch (RemoteException e) { 13435 throw new IllegalStateException("Process disappeared"); 13436 } finally { 13437 if (fd != null) { 13438 try { 13439 fd.close(); 13440 } catch (IOException e) { 13441 } 13442 } 13443 } 13444 } 13445 13446 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13447 public void monitor() { 13448 synchronized (this) { } 13449 } 13450 13451 void onCoreSettingsChange(Bundle settings) { 13452 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13453 ProcessRecord processRecord = mLruProcesses.get(i); 13454 try { 13455 if (processRecord.thread != null) { 13456 processRecord.thread.setCoreSettings(settings); 13457 } 13458 } catch (RemoteException re) { 13459 /* ignore */ 13460 } 13461 } 13462 } 13463 13464 // Multi-user methods 13465 13466 public boolean switchUser(int userId) { 13467 final int callingUid = Binder.getCallingUid(); 13468 if (callingUid != 0 && callingUid != Process.myUid()) { 13469 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13470 return false; 13471 } 13472 if (mCurrentUserId == userId) 13473 return true; 13474 13475 synchronized (this) { 13476 // Check if user is already logged in, otherwise check if user exists first before 13477 // adding to the list of logged in users. 13478 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13479 if (!userExists(userId)) { 13480 return false; 13481 } 13482 mLoggedInUsers.append(userId, userId); 13483 } 13484 13485 mCurrentUserId = userId; 13486 boolean haveActivities = mMainStack.switchUser(userId); 13487 if (!haveActivities) { 13488 startHomeActivityLocked(userId); 13489 } 13490 13491 } 13492 13493 // Inform of user switch 13494 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13495 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13496 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 13497 13498 return true; 13499 } 13500 13501 @Override 13502 public UserInfo getCurrentUser() throws RemoteException { 13503 final int callingUid = Binder.getCallingUid(); 13504 if (callingUid != 0 && callingUid != Process.myUid()) { 13505 Slog.e(TAG, "Trying to get user from unauthorized app"); 13506 return null; 13507 } 13508 return getUserManager().getUserInfo(mCurrentUserId); 13509 } 13510 13511 private void onUserRemoved(Intent intent) { 13512 int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 13513 if (extraUserId < 1) return; 13514 13515 // Kill all the processes for the user 13516 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13517 synchronized (this) { 13518 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13519 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13520 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13521 for (int i = 0; i < uids.size(); i++) { 13522 if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) { 13523 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13524 } 13525 } 13526 } 13527 13528 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13529 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13530 false, false, true, true, extraUserId); 13531 } 13532 } 13533 } 13534 13535 private boolean userExists(int userId) { 13536 UserInfo user = getUserManager().getUserInfo(userId); 13537 return user != null; 13538 } 13539 13540 UserManager getUserManager() { 13541 if (mUserManager == null) { 13542 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13543 } 13544 return mUserManager; 13545 } 13546 13547 private void checkValidCaller(int uid, int userId) { 13548 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13549 13550 throw new SecurityException("Caller uid=" + uid 13551 + " is not privileged to communicate with user=" + userId); 13552 } 13553 13554 private int applyUserId(int uid, int userId) { 13555 return UserHandle.getUid(userId, uid); 13556 } 13557 13558 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13559 if (info == null) return null; 13560 ApplicationInfo newInfo = new ApplicationInfo(info); 13561 newInfo.uid = applyUserId(info.uid, userId); 13562 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13563 + info.packageName; 13564 return newInfo; 13565 } 13566 13567 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13568 if (aInfo == null 13569 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13570 return aInfo; 13571 } 13572 13573 ActivityInfo info = new ActivityInfo(aInfo); 13574 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13575 return info; 13576 } 13577} 13578