ActivityManagerService.java revision 7767eac3232ba2fb9828766813cdb481d6a97584
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.wm.WindowManagerService; 31 32import dalvik.system.Zygote; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityManagerNative; 37import android.app.ActivityOptions; 38import android.app.ActivityThread; 39import android.app.AlertDialog; 40import android.app.AppGlobals; 41import android.app.ApplicationErrorReport; 42import android.app.Dialog; 43import android.app.IActivityController; 44import android.app.IApplicationThread; 45import android.app.IInstrumentationWatcher; 46import android.app.INotificationManager; 47import android.app.IProcessObserver; 48import android.app.IServiceConnection; 49import android.app.IThumbnailReceiver; 50import android.app.Instrumentation; 51import android.app.Notification; 52import android.app.NotificationManager; 53import android.app.PendingIntent; 54import android.app.backup.IBackupManager; 55import android.content.ActivityNotFoundException; 56import android.content.BroadcastReceiver; 57import android.content.ClipData; 58import android.content.ComponentCallbacks2; 59import android.content.ComponentName; 60import android.content.ContentProvider; 61import android.content.ContentResolver; 62import android.content.Context; 63import android.content.DialogInterface; 64import android.content.IContentProvider; 65import android.content.IIntentReceiver; 66import android.content.IIntentSender; 67import android.content.Intent; 68import android.content.IntentFilter; 69import android.content.IntentSender; 70import android.content.pm.ActivityInfo; 71import android.content.pm.ApplicationInfo; 72import android.content.pm.ConfigurationInfo; 73import android.content.pm.IPackageDataObserver; 74import android.content.pm.IPackageManager; 75import android.content.pm.InstrumentationInfo; 76import android.content.pm.PackageInfo; 77import android.content.pm.PackageManager; 78import android.content.pm.UserInfo; 79import android.content.pm.PackageManager.NameNotFoundException; 80import android.content.pm.PathPermission; 81import android.content.pm.ProviderInfo; 82import android.content.pm.ResolveInfo; 83import android.content.pm.ServiceInfo; 84import android.content.res.CompatibilityInfo; 85import android.content.res.Configuration; 86import android.graphics.Bitmap; 87import android.net.Proxy; 88import android.net.ProxyProperties; 89import android.net.Uri; 90import android.os.Binder; 91import android.os.Build; 92import android.os.Bundle; 93import android.os.Debug; 94import android.os.DropBoxManager; 95import android.os.Environment; 96import android.os.FileObserver; 97import android.os.FileUtils; 98import android.os.Handler; 99import android.os.IBinder; 100import android.os.IPermissionController; 101import android.os.Looper; 102import android.os.Message; 103import android.os.Parcel; 104import android.os.ParcelFileDescriptor; 105import android.os.Process; 106import android.os.RemoteCallbackList; 107import android.os.RemoteException; 108import android.os.SELinux; 109import android.os.ServiceManager; 110import android.os.StrictMode; 111import android.os.SystemClock; 112import android.os.SystemProperties; 113import android.os.UserHandle; 114import android.os.UserManager; 115import android.provider.Settings; 116import android.text.format.Time; 117import android.util.EventLog; 118import android.util.Log; 119import android.util.Pair; 120import android.util.PrintWriterPrinter; 121import android.util.Slog; 122import android.util.SparseArray; 123import android.util.SparseIntArray; 124import android.util.TimeUtils; 125import android.view.Gravity; 126import android.view.LayoutInflater; 127import android.view.View; 128import android.view.WindowManager; 129import android.view.WindowManagerPolicy; 130 131import java.io.BufferedInputStream; 132import java.io.BufferedOutputStream; 133import java.io.BufferedReader; 134import java.io.DataInputStream; 135import java.io.DataOutputStream; 136import java.io.File; 137import java.io.FileDescriptor; 138import java.io.FileInputStream; 139import java.io.FileNotFoundException; 140import java.io.FileOutputStream; 141import java.io.IOException; 142import java.io.InputStreamReader; 143import java.io.PrintWriter; 144import java.io.StringWriter; 145import java.lang.ref.WeakReference; 146import java.util.ArrayList; 147import java.util.Collections; 148import java.util.Comparator; 149import java.util.HashMap; 150import java.util.HashSet; 151import java.util.Iterator; 152import java.util.List; 153import java.util.Locale; 154import java.util.Map; 155import java.util.Map.Entry; 156import java.util.Set; 157import java.util.concurrent.atomic.AtomicBoolean; 158import java.util.concurrent.atomic.AtomicLong; 159 160public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 162 private static final String USER_DATA_DIR = "/data/user/"; 163 static final String TAG = "ActivityManager"; 164 static final String TAG_MU = "ActivityManagerServiceMU"; 165 static final boolean DEBUG = false; 166 static final boolean localLOGV = DEBUG; 167 static final boolean DEBUG_SWITCH = localLOGV || false; 168 static final boolean DEBUG_TASKS = localLOGV || false; 169 static final boolean DEBUG_PAUSE = localLOGV || false; 170 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 171 static final boolean DEBUG_TRANSITION = localLOGV || false; 172 static final boolean DEBUG_BROADCAST = localLOGV || false; 173 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_SERVICE = localLOGV || false; 176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 177 static final boolean DEBUG_VISBILITY = localLOGV || false; 178 static final boolean DEBUG_PROCESSES = localLOGV || false; 179 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 180 static final boolean DEBUG_PROVIDER = localLOGV || false; 181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 182 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 183 static final boolean DEBUG_RESULTS = localLOGV || false; 184 static final boolean DEBUG_BACKUP = localLOGV || false; 185 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 186 static final boolean DEBUG_POWER = localLOGV || false; 187 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 188 static final boolean DEBUG_MU = localLOGV || false; 189 static final boolean VALIDATE_TOKENS = false; 190 static final boolean SHOW_ACTIVITY_START_TIME = true; 191 192 // Control over CPU and battery monitoring. 193 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 194 static final boolean MONITOR_CPU_USAGE = true; 195 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 196 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 197 static final boolean MONITOR_THREAD_CPU_USAGE = false; 198 199 // The flags that are set for all calls we make to the package manager. 200 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 201 202 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 203 204 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 205 206 // Maximum number of recent tasks that we can remember. 207 static final int MAX_RECENT_TASKS = 20; 208 209 // Amount of time after a call to stopAppSwitches() during which we will 210 // prevent further untrusted switches from happening. 211 static final long APP_SWITCH_DELAY_TIME = 5*1000; 212 213 // How long we wait for a launched process to attach to the activity manager 214 // before we decide it's never going to come up for real. 215 static final int PROC_START_TIMEOUT = 10*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real, when the process was 219 // started with a wrapper for instrumentation (such as Valgrind) because it 220 // could take much longer than usual. 221 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 222 223 // How long to wait after going idle before forcing apps to GC. 224 static final int GC_TIMEOUT = 5*1000; 225 226 // The minimum amount of time between successive GC requests for a process. 227 static final int GC_MIN_INTERVAL = 60*1000; 228 229 // The rate at which we check for apps using excessive power -- 15 mins. 230 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 231 232 // The minimum sample duration we will allow before deciding we have 233 // enough data on wake locks to start killing things. 234 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on CPU usage to start killing things. 238 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // How long we allow a receiver to run before giving up on it. 241 static final int BROADCAST_FG_TIMEOUT = 10*1000; 242 static final int BROADCAST_BG_TIMEOUT = 60*1000; 243 244 // How long we wait until we timeout on key dispatching. 245 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 246 247 // How long we wait until we timeout on key dispatching during instrumentation. 248 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 249 250 static final int MY_PID = Process.myPid(); 251 252 static final String[] EMPTY_STRING_ARRAY = new String[0]; 253 254 public ActivityStack mMainStack; 255 256 private final boolean mHeadless; 257 258 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 259 // default actuion automatically. Important for devices without direct input 260 // devices. 261 private boolean mShowDialogs = true; 262 263 /** 264 * Description of a request to start a new activity, which has been held 265 * due to app switches being disabled. 266 */ 267 static class PendingActivityLaunch { 268 ActivityRecord r; 269 ActivityRecord sourceRecord; 270 int startFlags; 271 } 272 273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 274 = new ArrayList<PendingActivityLaunch>(); 275 276 277 BroadcastQueue mFgBroadcastQueue; 278 BroadcastQueue mBgBroadcastQueue; 279 // Convenient for easy iteration over the queues. Foreground is first 280 // so that dispatch of foreground broadcasts gets precedence. 281 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 282 283 BroadcastQueue broadcastQueueForIntent(Intent intent) { 284 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 285 if (DEBUG_BACKGROUND_BROADCAST) { 286 Slog.i(TAG, "Broadcast intent " + intent + " on " 287 + (isFg ? "foreground" : "background") 288 + " queue"); 289 } 290 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 291 } 292 293 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 294 for (BroadcastQueue queue : mBroadcastQueues) { 295 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 296 if (r != null) { 297 return r; 298 } 299 } 300 return null; 301 } 302 303 /** 304 * Activity we have told the window manager to have key focus. 305 */ 306 ActivityRecord mFocusedActivity = null; 307 /** 308 * List of intents that were used to start the most recent tasks. 309 */ 310 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 311 312 /** 313 * Process management. 314 */ 315 final ProcessList mProcessList = new ProcessList(); 316 317 /** 318 * All of the applications we currently have running organized by name. 319 * The keys are strings of the application package name (as 320 * returned by the package manager), and the keys are ApplicationRecord 321 * objects. 322 */ 323 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 324 325 /** 326 * The currently running isolated processes. 327 */ 328 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 329 330 /** 331 * Counter for assigning isolated process uids, to avoid frequently reusing the 332 * same ones. 333 */ 334 int mNextIsolatedProcessUid = 0; 335 336 /** 337 * The currently running heavy-weight process, if any. 338 */ 339 ProcessRecord mHeavyWeightProcess = null; 340 341 /** 342 * The last time that various processes have crashed. 343 */ 344 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 345 346 /** 347 * Set of applications that we consider to be bad, and will reject 348 * incoming broadcasts from (which the user has no control over). 349 * Processes are added to this set when they have crashed twice within 350 * a minimum amount of time; they are removed from it when they are 351 * later restarted (hopefully due to some user action). The value is the 352 * time it was added to the list. 353 */ 354 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 355 356 /** 357 * All of the processes we currently have running organized by pid. 358 * The keys are the pid running the application. 359 * 360 * <p>NOTE: This object is protected by its own lock, NOT the global 361 * activity manager lock! 362 */ 363 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 364 365 /** 366 * All of the processes that have been forced to be foreground. The key 367 * is the pid of the caller who requested it (we hold a death 368 * link on it). 369 */ 370 abstract class ForegroundToken implements IBinder.DeathRecipient { 371 int pid; 372 IBinder token; 373 } 374 final SparseArray<ForegroundToken> mForegroundProcesses 375 = new SparseArray<ForegroundToken>(); 376 377 /** 378 * List of records for processes that someone had tried to start before the 379 * system was ready. We don't start them at that point, but ensure they 380 * are started by the time booting is complete. 381 */ 382 final ArrayList<ProcessRecord> mProcessesOnHold 383 = new ArrayList<ProcessRecord>(); 384 385 /** 386 * List of persistent applications that are in the process 387 * of being started. 388 */ 389 final ArrayList<ProcessRecord> mPersistentStartingProcesses 390 = new ArrayList<ProcessRecord>(); 391 392 /** 393 * Processes that are being forcibly torn down. 394 */ 395 final ArrayList<ProcessRecord> mRemovedProcesses 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of running applications, sorted by recent usage. 400 * The first entry in the list is the least recently used. 401 * It contains ApplicationRecord objects. This list does NOT include 402 * any persistent application records (since we never want to exit them). 403 */ 404 final ArrayList<ProcessRecord> mLruProcesses 405 = new ArrayList<ProcessRecord>(); 406 407 /** 408 * List of processes that should gc as soon as things are idle. 409 */ 410 final ArrayList<ProcessRecord> mProcessesToGc 411 = new ArrayList<ProcessRecord>(); 412 413 /** 414 * This is the process holding what we currently consider to be 415 * the "home" activity. 416 */ 417 ProcessRecord mHomeProcess; 418 419 /** 420 * This is the process holding the activity the user last visited that 421 * is in a different process from the one they are currently in. 422 */ 423 ProcessRecord mPreviousProcess; 424 425 /** 426 * The time at which the previous process was last visible. 427 */ 428 long mPreviousProcessVisibleTime; 429 430 /** 431 * Packages that the user has asked to have run in screen size 432 * compatibility mode instead of filling the screen. 433 */ 434 final CompatModePackages mCompatModePackages; 435 436 /** 437 * Set of PendingResultRecord objects that are currently active. 438 */ 439 final HashSet mPendingResultRecords = new HashSet(); 440 441 /** 442 * Set of IntentSenderRecord objects that are currently active. 443 */ 444 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 445 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 446 447 /** 448 * Fingerprints (hashCode()) of stack traces that we've 449 * already logged DropBox entries for. Guarded by itself. If 450 * something (rogue user app) forces this over 451 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 452 */ 453 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 454 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 455 456 /** 457 * Strict Mode background batched logging state. 458 * 459 * The string buffer is guarded by itself, and its lock is also 460 * used to determine if another batched write is already 461 * in-flight. 462 */ 463 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 464 465 /** 466 * Keeps track of all IIntentReceivers that have been registered for 467 * broadcasts. Hash keys are the receiver IBinder, hash value is 468 * a ReceiverList. 469 */ 470 final HashMap mRegisteredReceivers = new HashMap(); 471 472 /** 473 * Resolver for broadcast intents to registered receivers. 474 * Holds BroadcastFilter (subclass of IntentFilter). 475 */ 476 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 477 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 478 @Override 479 protected boolean allowFilterResult( 480 BroadcastFilter filter, List<BroadcastFilter> dest) { 481 IBinder target = filter.receiverList.receiver.asBinder(); 482 for (int i=dest.size()-1; i>=0; i--) { 483 if (dest.get(i).receiverList.receiver.asBinder() == target) { 484 return false; 485 } 486 } 487 return true; 488 } 489 490 @Override 491 protected BroadcastFilter[] newArray(int size) { 492 return new BroadcastFilter[size]; 493 } 494 495 @Override 496 protected String packageForFilter(BroadcastFilter filter) { 497 return filter.packageName; 498 } 499 }; 500 501 /** 502 * State of all active sticky broadcasts. Keys are the action of the 503 * sticky Intent, values are an ArrayList of all broadcasted intents with 504 * that action (which should usually be one). 505 */ 506 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 507 new HashMap<String, ArrayList<Intent>>(); 508 509 final ActiveServices mServices; 510 511 /** 512 * Backup/restore process management 513 */ 514 String mBackupAppName = null; 515 BackupRecord mBackupTarget = null; 516 517 /** 518 * List of PendingThumbnailsRecord objects of clients who are still 519 * waiting to receive all of the thumbnails for a task. 520 */ 521 final ArrayList mPendingThumbnails = new ArrayList(); 522 523 /** 524 * List of HistoryRecord objects that have been finished and must 525 * still report back to a pending thumbnail receiver. 526 */ 527 final ArrayList mCancelledThumbnails = new ArrayList(); 528 529 final ProviderMap mProviderMap = new ProviderMap(); 530 531 /** 532 * List of content providers who have clients waiting for them. The 533 * application is currently being launched and the provider will be 534 * removed from this list once it is published. 535 */ 536 final ArrayList<ContentProviderRecord> mLaunchingProviders 537 = new ArrayList<ContentProviderRecord>(); 538 539 /** 540 * Global set of specific Uri permissions that have been granted. 541 */ 542 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 543 = new SparseArray<HashMap<Uri, UriPermission>>(); 544 545 CoreSettingsObserver mCoreSettingsObserver; 546 547 /** 548 * Thread-local storage used to carry caller permissions over through 549 * indirect content-provider access. 550 * @see #ActivityManagerService.openContentUri() 551 */ 552 private class Identity { 553 public int pid; 554 public int uid; 555 556 Identity(int _pid, int _uid) { 557 pid = _pid; 558 uid = _uid; 559 } 560 } 561 562 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 563 564 /** 565 * All information we have collected about the runtime performance of 566 * any user id that can impact battery performance. 567 */ 568 final BatteryStatsService mBatteryStatsService; 569 570 /** 571 * information about component usage 572 */ 573 final UsageStatsService mUsageStatsService; 574 575 /** 576 * Current configuration information. HistoryRecord objects are given 577 * a reference to this object to indicate which configuration they are 578 * currently running in, so this object must be kept immutable. 579 */ 580 Configuration mConfiguration = new Configuration(); 581 582 /** 583 * Current sequencing integer of the configuration, for skipping old 584 * configurations. 585 */ 586 int mConfigurationSeq = 0; 587 588 /** 589 * Hardware-reported OpenGLES version. 590 */ 591 final int GL_ES_VERSION; 592 593 /** 594 * List of initialization arguments to pass to all processes when binding applications to them. 595 * For example, references to the commonly used services. 596 */ 597 HashMap<String, IBinder> mAppBindArgs; 598 599 /** 600 * Temporary to avoid allocations. Protected by main lock. 601 */ 602 final StringBuilder mStringBuilder = new StringBuilder(256); 603 604 /** 605 * Used to control how we initialize the service. 606 */ 607 boolean mStartRunning = false; 608 ComponentName mTopComponent; 609 String mTopAction; 610 String mTopData; 611 boolean mProcessesReady = false; 612 boolean mSystemReady = false; 613 boolean mBooting = false; 614 boolean mWaitingUpdate = false; 615 boolean mDidUpdate = false; 616 boolean mOnBattery = false; 617 boolean mLaunchWarningShown = false; 618 619 Context mContext; 620 621 int mFactoryTest; 622 623 boolean mCheckedForSetup; 624 625 /** 626 * The time at which we will allow normal application switches again, 627 * after a call to {@link #stopAppSwitches()}. 628 */ 629 long mAppSwitchesAllowedTime; 630 631 /** 632 * This is set to true after the first switch after mAppSwitchesAllowedTime 633 * is set; any switches after that will clear the time. 634 */ 635 boolean mDidAppSwitch; 636 637 /** 638 * Last time (in realtime) at which we checked for power usage. 639 */ 640 long mLastPowerCheckRealtime; 641 642 /** 643 * Last time (in uptime) at which we checked for power usage. 644 */ 645 long mLastPowerCheckUptime; 646 647 /** 648 * Set while we are wanting to sleep, to prevent any 649 * activities from being started/resumed. 650 */ 651 boolean mSleeping = false; 652 653 /** 654 * State of external calls telling us if the device is asleep. 655 */ 656 boolean mWentToSleep = false; 657 658 /** 659 * State of external call telling us if the lock screen is shown. 660 */ 661 boolean mLockScreenShown = false; 662 663 /** 664 * Set if we are shutting down the system, similar to sleeping. 665 */ 666 boolean mShuttingDown = false; 667 668 /** 669 * Task identifier that activities are currently being started 670 * in. Incremented each time a new task is created. 671 * todo: Replace this with a TokenSpace class that generates non-repeating 672 * integers that won't wrap. 673 */ 674 int mCurTask = 1; 675 676 /** 677 * Current sequence id for oom_adj computation traversal. 678 */ 679 int mAdjSeq = 0; 680 681 /** 682 * Current sequence id for process LRU updating. 683 */ 684 int mLruSeq = 0; 685 686 /** 687 * Keep track of the non-hidden/empty process we last found, to help 688 * determine how to distribute hidden/empty processes next time. 689 */ 690 int mNumNonHiddenProcs = 0; 691 692 /** 693 * Keep track of the number of hidden procs, to balance oom adj 694 * distribution between those and empty procs. 695 */ 696 int mNumHiddenProcs = 0; 697 698 /** 699 * Keep track of the number of service processes we last found, to 700 * determine on the next iteration which should be B services. 701 */ 702 int mNumServiceProcs = 0; 703 int mNewNumServiceProcs = 0; 704 705 /** 706 * System monitoring: number of processes that died since the last 707 * N procs were started. 708 */ 709 int[] mProcDeaths = new int[20]; 710 711 /** 712 * This is set if we had to do a delayed dexopt of an app before launching 713 * it, to increasing the ANR timeouts in that case. 714 */ 715 boolean mDidDexOpt; 716 717 String mDebugApp = null; 718 boolean mWaitForDebugger = false; 719 boolean mDebugTransient = false; 720 String mOrigDebugApp = null; 721 boolean mOrigWaitForDebugger = false; 722 boolean mAlwaysFinishActivities = false; 723 IActivityController mController = null; 724 String mProfileApp = null; 725 ProcessRecord mProfileProc = null; 726 String mProfileFile; 727 ParcelFileDescriptor mProfileFd; 728 int mProfileType = 0; 729 boolean mAutoStopProfiler = false; 730 String mOpenGlTraceApp = null; 731 732 static class ProcessChangeItem { 733 static final int CHANGE_ACTIVITIES = 1<<0; 734 static final int CHANGE_IMPORTANCE= 1<<1; 735 int changes; 736 int uid; 737 int pid; 738 int importance; 739 boolean foregroundActivities; 740 } 741 742 final RemoteCallbackList<IProcessObserver> mProcessObservers 743 = new RemoteCallbackList<IProcessObserver>(); 744 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 745 746 final ArrayList<ProcessChangeItem> mPendingProcessChanges 747 = new ArrayList<ProcessChangeItem>(); 748 final ArrayList<ProcessChangeItem> mAvailProcessChanges 749 = new ArrayList<ProcessChangeItem>(); 750 751 /** 752 * Callback of last caller to {@link #requestPss}. 753 */ 754 Runnable mRequestPssCallback; 755 756 /** 757 * Remaining processes for which we are waiting results from the last 758 * call to {@link #requestPss}. 759 */ 760 final ArrayList<ProcessRecord> mRequestPssList 761 = new ArrayList<ProcessRecord>(); 762 763 /** 764 * Runtime statistics collection thread. This object's lock is used to 765 * protect all related state. 766 */ 767 final Thread mProcessStatsThread; 768 769 /** 770 * Used to collect process stats when showing not responding dialog. 771 * Protected by mProcessStatsThread. 772 */ 773 final ProcessStats mProcessStats = new ProcessStats( 774 MONITOR_THREAD_CPU_USAGE); 775 final AtomicLong mLastCpuTime = new AtomicLong(0); 776 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 777 778 long mLastWriteTime = 0; 779 780 /** 781 * Set to true after the system has finished booting. 782 */ 783 boolean mBooted = false; 784 785 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 786 int mProcessLimitOverride = -1; 787 788 WindowManagerService mWindowManager; 789 790 static ActivityManagerService mSelf; 791 static ActivityThread mSystemThread; 792 793 private int mCurrentUserId; 794 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 795 private UserManager mUserManager; 796 797 private final class AppDeathRecipient implements IBinder.DeathRecipient { 798 final ProcessRecord mApp; 799 final int mPid; 800 final IApplicationThread mAppThread; 801 802 AppDeathRecipient(ProcessRecord app, int pid, 803 IApplicationThread thread) { 804 if (localLOGV) Slog.v( 805 TAG, "New death recipient " + this 806 + " for thread " + thread.asBinder()); 807 mApp = app; 808 mPid = pid; 809 mAppThread = thread; 810 } 811 812 public void binderDied() { 813 if (localLOGV) Slog.v( 814 TAG, "Death received in " + this 815 + " for thread " + mAppThread.asBinder()); 816 synchronized(ActivityManagerService.this) { 817 appDiedLocked(mApp, mPid, mAppThread); 818 } 819 } 820 } 821 822 static final int SHOW_ERROR_MSG = 1; 823 static final int SHOW_NOT_RESPONDING_MSG = 2; 824 static final int SHOW_FACTORY_ERROR_MSG = 3; 825 static final int UPDATE_CONFIGURATION_MSG = 4; 826 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 827 static final int WAIT_FOR_DEBUGGER_MSG = 6; 828 static final int SERVICE_TIMEOUT_MSG = 12; 829 static final int UPDATE_TIME_ZONE = 13; 830 static final int SHOW_UID_ERROR_MSG = 14; 831 static final int IM_FEELING_LUCKY_MSG = 15; 832 static final int PROC_START_TIMEOUT_MSG = 20; 833 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 834 static final int KILL_APPLICATION_MSG = 22; 835 static final int FINALIZE_PENDING_INTENT_MSG = 23; 836 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 837 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 838 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 839 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 840 static final int CLEAR_DNS_CACHE = 28; 841 static final int UPDATE_HTTP_PROXY = 29; 842 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 843 static final int DISPATCH_PROCESSES_CHANGED = 31; 844 static final int DISPATCH_PROCESS_DIED = 32; 845 static final int REPORT_MEM_USAGE = 33; 846 847 static final int FIRST_ACTIVITY_STACK_MSG = 100; 848 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 849 static final int FIRST_COMPAT_MODE_MSG = 300; 850 851 AlertDialog mUidAlert; 852 CompatModeDialog mCompatModeDialog; 853 long mLastMemUsageReportTime = 0; 854 855 final Handler mHandler = new Handler() { 856 //public Handler() { 857 // if (localLOGV) Slog.v(TAG, "Handler started!"); 858 //} 859 860 public void handleMessage(Message msg) { 861 switch (msg.what) { 862 case SHOW_ERROR_MSG: { 863 HashMap data = (HashMap) msg.obj; 864 synchronized (ActivityManagerService.this) { 865 ProcessRecord proc = (ProcessRecord)data.get("app"); 866 if (proc != null && proc.crashDialog != null) { 867 Slog.e(TAG, "App already has crash dialog: " + proc); 868 return; 869 } 870 AppErrorResult res = (AppErrorResult) data.get("result"); 871 if (mShowDialogs && !mSleeping && !mShuttingDown) { 872 Dialog d = new AppErrorDialog(mContext, res, proc); 873 d.show(); 874 proc.crashDialog = d; 875 } else { 876 // The device is asleep, so just pretend that the user 877 // saw a crash dialog and hit "force quit". 878 res.set(0); 879 } 880 } 881 882 ensureBootCompleted(); 883 } break; 884 case SHOW_NOT_RESPONDING_MSG: { 885 synchronized (ActivityManagerService.this) { 886 HashMap data = (HashMap) msg.obj; 887 ProcessRecord proc = (ProcessRecord)data.get("app"); 888 if (proc != null && proc.anrDialog != null) { 889 Slog.e(TAG, "App already has anr dialog: " + proc); 890 return; 891 } 892 893 Intent intent = new Intent("android.intent.action.ANR"); 894 if (!mProcessesReady) { 895 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 896 | Intent.FLAG_RECEIVER_FOREGROUND); 897 } 898 broadcastIntentLocked(null, null, intent, 899 null, null, 0, null, null, null, 900 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 901 902 if (mShowDialogs) { 903 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 904 mContext, proc, (ActivityRecord)data.get("activity")); 905 d.show(); 906 proc.anrDialog = d; 907 } else { 908 // Just kill the app if there is no dialog to be shown. 909 killAppAtUsersRequest(proc, null); 910 } 911 } 912 913 ensureBootCompleted(); 914 } break; 915 case SHOW_STRICT_MODE_VIOLATION_MSG: { 916 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 917 synchronized (ActivityManagerService.this) { 918 ProcessRecord proc = (ProcessRecord) data.get("app"); 919 if (proc == null) { 920 Slog.e(TAG, "App not found when showing strict mode dialog."); 921 break; 922 } 923 if (proc.crashDialog != null) { 924 Slog.e(TAG, "App already has strict mode dialog: " + proc); 925 return; 926 } 927 AppErrorResult res = (AppErrorResult) data.get("result"); 928 if (mShowDialogs && !mSleeping && !mShuttingDown) { 929 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 930 d.show(); 931 proc.crashDialog = d; 932 } else { 933 // The device is asleep, so just pretend that the user 934 // saw a crash dialog and hit "force quit". 935 res.set(0); 936 } 937 } 938 ensureBootCompleted(); 939 } break; 940 case SHOW_FACTORY_ERROR_MSG: { 941 Dialog d = new FactoryErrorDialog( 942 mContext, msg.getData().getCharSequence("msg")); 943 d.show(); 944 ensureBootCompleted(); 945 } break; 946 case UPDATE_CONFIGURATION_MSG: { 947 final ContentResolver resolver = mContext.getContentResolver(); 948 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 949 } break; 950 case GC_BACKGROUND_PROCESSES_MSG: { 951 synchronized (ActivityManagerService.this) { 952 performAppGcsIfAppropriateLocked(); 953 } 954 } break; 955 case WAIT_FOR_DEBUGGER_MSG: { 956 synchronized (ActivityManagerService.this) { 957 ProcessRecord app = (ProcessRecord)msg.obj; 958 if (msg.arg1 != 0) { 959 if (!app.waitedForDebugger) { 960 Dialog d = new AppWaitingForDebuggerDialog( 961 ActivityManagerService.this, 962 mContext, app); 963 app.waitDialog = d; 964 app.waitedForDebugger = true; 965 d.show(); 966 } 967 } else { 968 if (app.waitDialog != null) { 969 app.waitDialog.dismiss(); 970 app.waitDialog = null; 971 } 972 } 973 } 974 } break; 975 case SERVICE_TIMEOUT_MSG: { 976 if (mDidDexOpt) { 977 mDidDexOpt = false; 978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 979 nmsg.obj = msg.obj; 980 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 981 return; 982 } 983 mServices.serviceTimeout((ProcessRecord)msg.obj); 984 } break; 985 case UPDATE_TIME_ZONE: { 986 synchronized (ActivityManagerService.this) { 987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 988 ProcessRecord r = mLruProcesses.get(i); 989 if (r.thread != null) { 990 try { 991 r.thread.updateTimeZone(); 992 } catch (RemoteException ex) { 993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 994 } 995 } 996 } 997 } 998 } break; 999 case CLEAR_DNS_CACHE: { 1000 synchronized (ActivityManagerService.this) { 1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1002 ProcessRecord r = mLruProcesses.get(i); 1003 if (r.thread != null) { 1004 try { 1005 r.thread.clearDnsCache(); 1006 } catch (RemoteException ex) { 1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1008 } 1009 } 1010 } 1011 } 1012 } break; 1013 case UPDATE_HTTP_PROXY: { 1014 ProxyProperties proxy = (ProxyProperties)msg.obj; 1015 String host = ""; 1016 String port = ""; 1017 String exclList = ""; 1018 if (proxy != null) { 1019 host = proxy.getHost(); 1020 port = Integer.toString(proxy.getPort()); 1021 exclList = proxy.getExclusionList(); 1022 } 1023 synchronized (ActivityManagerService.this) { 1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1025 ProcessRecord r = mLruProcesses.get(i); 1026 if (r.thread != null) { 1027 try { 1028 r.thread.setHttpProxy(host, port, exclList); 1029 } catch (RemoteException ex) { 1030 Slog.w(TAG, "Failed to update http proxy for: " + 1031 r.info.processName); 1032 } 1033 } 1034 } 1035 } 1036 } break; 1037 case SHOW_UID_ERROR_MSG: { 1038 String title = "System UIDs Inconsistent"; 1039 String text = "UIDs on the system are inconsistent, you need to wipe your" 1040 + " data partition or your device will be unstable."; 1041 Log.e(TAG, title + ": " + text); 1042 if (mShowDialogs) { 1043 // XXX This is a temporary dialog, no need to localize. 1044 AlertDialog d = new BaseErrorDialog(mContext); 1045 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1046 d.setCancelable(false); 1047 d.setTitle(title); 1048 d.setMessage(text); 1049 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1050 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1051 mUidAlert = d; 1052 d.show(); 1053 } 1054 } break; 1055 case IM_FEELING_LUCKY_MSG: { 1056 if (mUidAlert != null) { 1057 mUidAlert.dismiss(); 1058 mUidAlert = null; 1059 } 1060 } break; 1061 case PROC_START_TIMEOUT_MSG: { 1062 if (mDidDexOpt) { 1063 mDidDexOpt = false; 1064 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1065 nmsg.obj = msg.obj; 1066 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1067 return; 1068 } 1069 ProcessRecord app = (ProcessRecord)msg.obj; 1070 synchronized (ActivityManagerService.this) { 1071 processStartTimedOutLocked(app); 1072 } 1073 } break; 1074 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1075 synchronized (ActivityManagerService.this) { 1076 doPendingActivityLaunchesLocked(true); 1077 } 1078 } break; 1079 case KILL_APPLICATION_MSG: { 1080 synchronized (ActivityManagerService.this) { 1081 int uid = msg.arg1; 1082 boolean restart = (msg.arg2 == 1); 1083 String pkg = (String) msg.obj; 1084 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1085 UserHandle.getUserId(uid)); 1086 } 1087 } break; 1088 case FINALIZE_PENDING_INTENT_MSG: { 1089 ((PendingIntentRecord)msg.obj).completeFinalize(); 1090 } break; 1091 case POST_HEAVY_NOTIFICATION_MSG: { 1092 INotificationManager inm = NotificationManager.getService(); 1093 if (inm == null) { 1094 return; 1095 } 1096 1097 ActivityRecord root = (ActivityRecord)msg.obj; 1098 ProcessRecord process = root.app; 1099 if (process == null) { 1100 return; 1101 } 1102 1103 try { 1104 Context context = mContext.createPackageContext(process.info.packageName, 0); 1105 String text = mContext.getString(R.string.heavy_weight_notification, 1106 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1107 Notification notification = new Notification(); 1108 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1109 notification.when = 0; 1110 notification.flags = Notification.FLAG_ONGOING_EVENT; 1111 notification.tickerText = text; 1112 notification.defaults = 0; // please be quiet 1113 notification.sound = null; 1114 notification.vibrate = null; 1115 notification.setLatestEventInfo(context, text, 1116 mContext.getText(R.string.heavy_weight_notification_detail), 1117 PendingIntent.getActivity(mContext, 0, root.intent, 1118 PendingIntent.FLAG_CANCEL_CURRENT)); 1119 1120 try { 1121 int[] outId = new int[1]; 1122 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1123 notification, outId); 1124 } catch (RuntimeException e) { 1125 Slog.w(ActivityManagerService.TAG, 1126 "Error showing notification for heavy-weight app", e); 1127 } catch (RemoteException e) { 1128 } 1129 } catch (NameNotFoundException e) { 1130 Slog.w(TAG, "Unable to create context for heavy notification", e); 1131 } 1132 } break; 1133 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1134 INotificationManager inm = NotificationManager.getService(); 1135 if (inm == null) { 1136 return; 1137 } 1138 try { 1139 inm.cancelNotification("android", 1140 R.string.heavy_weight_notification); 1141 } catch (RuntimeException e) { 1142 Slog.w(ActivityManagerService.TAG, 1143 "Error canceling notification for service", e); 1144 } catch (RemoteException e) { 1145 } 1146 } break; 1147 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1148 synchronized (ActivityManagerService.this) { 1149 checkExcessivePowerUsageLocked(true); 1150 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1151 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1152 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1153 } 1154 } break; 1155 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1156 synchronized (ActivityManagerService.this) { 1157 ActivityRecord ar = (ActivityRecord)msg.obj; 1158 if (mCompatModeDialog != null) { 1159 if (mCompatModeDialog.mAppInfo.packageName.equals( 1160 ar.info.applicationInfo.packageName)) { 1161 return; 1162 } 1163 mCompatModeDialog.dismiss(); 1164 mCompatModeDialog = null; 1165 } 1166 if (ar != null && false) { 1167 if (mCompatModePackages.getPackageAskCompatModeLocked( 1168 ar.packageName)) { 1169 int mode = mCompatModePackages.computeCompatModeLocked( 1170 ar.info.applicationInfo); 1171 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1172 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1173 mCompatModeDialog = new CompatModeDialog( 1174 ActivityManagerService.this, mContext, 1175 ar.info.applicationInfo); 1176 mCompatModeDialog.show(); 1177 } 1178 } 1179 } 1180 } 1181 break; 1182 } 1183 case DISPATCH_PROCESSES_CHANGED: { 1184 dispatchProcessesChanged(); 1185 break; 1186 } 1187 case DISPATCH_PROCESS_DIED: { 1188 final int pid = msg.arg1; 1189 final int uid = msg.arg2; 1190 dispatchProcessDied(pid, uid); 1191 break; 1192 } 1193 case REPORT_MEM_USAGE: { 1194 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1195 if (!isDebuggable) { 1196 return; 1197 } 1198 synchronized (ActivityManagerService.this) { 1199 long now = SystemClock.uptimeMillis(); 1200 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1201 // Don't report more than every 5 minutes to somewhat 1202 // avoid spamming. 1203 return; 1204 } 1205 mLastMemUsageReportTime = now; 1206 } 1207 Thread thread = new Thread() { 1208 @Override public void run() { 1209 StringBuilder dropBuilder = new StringBuilder(1024); 1210 StringBuilder logBuilder = new StringBuilder(1024); 1211 StringWriter oomSw = new StringWriter(); 1212 PrintWriter oomPw = new PrintWriter(oomSw); 1213 StringWriter catSw = new StringWriter(); 1214 PrintWriter catPw = new PrintWriter(catSw); 1215 String[] emptyArgs = new String[] { }; 1216 StringBuilder tag = new StringBuilder(128); 1217 StringBuilder stack = new StringBuilder(128); 1218 tag.append("Low on memory -- "); 1219 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1220 tag, stack); 1221 dropBuilder.append(stack); 1222 dropBuilder.append('\n'); 1223 dropBuilder.append('\n'); 1224 String oomString = oomSw.toString(); 1225 dropBuilder.append(oomString); 1226 dropBuilder.append('\n'); 1227 logBuilder.append(oomString); 1228 try { 1229 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1230 "procrank", }); 1231 final InputStreamReader converter = new InputStreamReader( 1232 proc.getInputStream()); 1233 BufferedReader in = new BufferedReader(converter); 1234 String line; 1235 while (true) { 1236 line = in.readLine(); 1237 if (line == null) { 1238 break; 1239 } 1240 if (line.length() > 0) { 1241 logBuilder.append(line); 1242 logBuilder.append('\n'); 1243 } 1244 dropBuilder.append(line); 1245 dropBuilder.append('\n'); 1246 } 1247 converter.close(); 1248 } catch (IOException e) { 1249 } 1250 synchronized (ActivityManagerService.this) { 1251 catPw.println(); 1252 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1253 catPw.println(); 1254 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1255 false, false, null); 1256 catPw.println(); 1257 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1258 } 1259 dropBuilder.append(catSw.toString()); 1260 addErrorToDropBox("lowmem", null, "system_server", null, 1261 null, tag.toString(), dropBuilder.toString(), null, null); 1262 Slog.i(TAG, logBuilder.toString()); 1263 synchronized (ActivityManagerService.this) { 1264 long now = SystemClock.uptimeMillis(); 1265 if (mLastMemUsageReportTime < now) { 1266 mLastMemUsageReportTime = now; 1267 } 1268 } 1269 } 1270 }; 1271 thread.start(); 1272 break; 1273 } 1274 } 1275 } 1276 }; 1277 1278 public static void setSystemProcess() { 1279 try { 1280 ActivityManagerService m = mSelf; 1281 1282 ServiceManager.addService("activity", m, true); 1283 ServiceManager.addService("meminfo", new MemBinder(m)); 1284 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1285 ServiceManager.addService("dbinfo", new DbBinder(m)); 1286 if (MONITOR_CPU_USAGE) { 1287 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1288 } 1289 ServiceManager.addService("permission", new PermissionController(m)); 1290 1291 ApplicationInfo info = 1292 mSelf.mContext.getPackageManager().getApplicationInfo( 1293 "android", STOCK_PM_FLAGS); 1294 mSystemThread.installSystemApplicationInfo(info); 1295 1296 synchronized (mSelf) { 1297 ProcessRecord app = mSelf.newProcessRecordLocked( 1298 mSystemThread.getApplicationThread(), info, 1299 info.processName, false); 1300 app.persistent = true; 1301 app.pid = MY_PID; 1302 app.maxAdj = ProcessList.SYSTEM_ADJ; 1303 mSelf.mProcessNames.put(app.processName, app.uid, app); 1304 synchronized (mSelf.mPidsSelfLocked) { 1305 mSelf.mPidsSelfLocked.put(app.pid, app); 1306 } 1307 mSelf.updateLruProcessLocked(app, true, true); 1308 } 1309 } catch (PackageManager.NameNotFoundException e) { 1310 throw new RuntimeException( 1311 "Unable to find android system package", e); 1312 } 1313 } 1314 1315 public void setWindowManager(WindowManagerService wm) { 1316 mWindowManager = wm; 1317 } 1318 1319 public static final Context main(int factoryTest) { 1320 AThread thr = new AThread(); 1321 thr.start(); 1322 1323 synchronized (thr) { 1324 while (thr.mService == null) { 1325 try { 1326 thr.wait(); 1327 } catch (InterruptedException e) { 1328 } 1329 } 1330 } 1331 1332 ActivityManagerService m = thr.mService; 1333 mSelf = m; 1334 ActivityThread at = ActivityThread.systemMain(); 1335 mSystemThread = at; 1336 Context context = at.getSystemContext(); 1337 context.setTheme(android.R.style.Theme_Holo); 1338 m.mContext = context; 1339 m.mFactoryTest = factoryTest; 1340 m.mMainStack = new ActivityStack(m, context, true); 1341 1342 m.mBatteryStatsService.publish(context); 1343 m.mUsageStatsService.publish(context); 1344 1345 synchronized (thr) { 1346 thr.mReady = true; 1347 thr.notifyAll(); 1348 } 1349 1350 m.startRunning(null, null, null, null); 1351 1352 return context; 1353 } 1354 1355 public static ActivityManagerService self() { 1356 return mSelf; 1357 } 1358 1359 static class AThread extends Thread { 1360 ActivityManagerService mService; 1361 boolean mReady = false; 1362 1363 public AThread() { 1364 super("ActivityManager"); 1365 } 1366 1367 public void run() { 1368 Looper.prepare(); 1369 1370 android.os.Process.setThreadPriority( 1371 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1372 android.os.Process.setCanSelfBackground(false); 1373 1374 ActivityManagerService m = new ActivityManagerService(); 1375 1376 synchronized (this) { 1377 mService = m; 1378 notifyAll(); 1379 } 1380 1381 synchronized (this) { 1382 while (!mReady) { 1383 try { 1384 wait(); 1385 } catch (InterruptedException e) { 1386 } 1387 } 1388 } 1389 1390 // For debug builds, log event loop stalls to dropbox for analysis. 1391 if (StrictMode.conditionallyEnableDebugLogging()) { 1392 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1393 } 1394 1395 Looper.loop(); 1396 } 1397 } 1398 1399 static class MemBinder extends Binder { 1400 ActivityManagerService mActivityManagerService; 1401 MemBinder(ActivityManagerService activityManagerService) { 1402 mActivityManagerService = activityManagerService; 1403 } 1404 1405 @Override 1406 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1407 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1408 != PackageManager.PERMISSION_GRANTED) { 1409 pw.println("Permission Denial: can't dump meminfo from from pid=" 1410 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1411 + " without permission " + android.Manifest.permission.DUMP); 1412 return; 1413 } 1414 1415 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1416 false, null, null, null); 1417 } 1418 } 1419 1420 static class GraphicsBinder extends Binder { 1421 ActivityManagerService mActivityManagerService; 1422 GraphicsBinder(ActivityManagerService activityManagerService) { 1423 mActivityManagerService = activityManagerService; 1424 } 1425 1426 @Override 1427 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1428 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1429 != PackageManager.PERMISSION_GRANTED) { 1430 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1431 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1432 + " without permission " + android.Manifest.permission.DUMP); 1433 return; 1434 } 1435 1436 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1437 } 1438 } 1439 1440 static class DbBinder extends Binder { 1441 ActivityManagerService mActivityManagerService; 1442 DbBinder(ActivityManagerService activityManagerService) { 1443 mActivityManagerService = activityManagerService; 1444 } 1445 1446 @Override 1447 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1448 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1449 != PackageManager.PERMISSION_GRANTED) { 1450 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1451 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1452 + " without permission " + android.Manifest.permission.DUMP); 1453 return; 1454 } 1455 1456 mActivityManagerService.dumpDbInfo(fd, pw, args); 1457 } 1458 } 1459 1460 static class CpuBinder extends Binder { 1461 ActivityManagerService mActivityManagerService; 1462 CpuBinder(ActivityManagerService activityManagerService) { 1463 mActivityManagerService = activityManagerService; 1464 } 1465 1466 @Override 1467 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1468 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1469 != PackageManager.PERMISSION_GRANTED) { 1470 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1471 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1472 + " without permission " + android.Manifest.permission.DUMP); 1473 return; 1474 } 1475 1476 synchronized (mActivityManagerService.mProcessStatsThread) { 1477 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1478 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1479 SystemClock.uptimeMillis())); 1480 } 1481 } 1482 } 1483 1484 private ActivityManagerService() { 1485 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1486 1487 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1488 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1489 mBroadcastQueues[0] = mFgBroadcastQueue; 1490 mBroadcastQueues[1] = mBgBroadcastQueue; 1491 1492 mServices = new ActiveServices(this); 1493 1494 File dataDir = Environment.getDataDirectory(); 1495 File systemDir = new File(dataDir, "system"); 1496 systemDir.mkdirs(); 1497 mBatteryStatsService = new BatteryStatsService(new File( 1498 systemDir, "batterystats.bin").toString()); 1499 mBatteryStatsService.getActiveStatistics().readLocked(); 1500 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1501 mOnBattery = DEBUG_POWER ? true 1502 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1503 mBatteryStatsService.getActiveStatistics().setCallback(this); 1504 1505 mUsageStatsService = new UsageStatsService(new File( 1506 systemDir, "usagestats").toString()); 1507 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1508 1509 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1510 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1511 1512 mConfiguration.setToDefaults(); 1513 mConfiguration.locale = Locale.getDefault(); 1514 mConfigurationSeq = mConfiguration.seq = 1; 1515 mProcessStats.init(); 1516 1517 mCompatModePackages = new CompatModePackages(this, systemDir); 1518 1519 // Add ourself to the Watchdog monitors. 1520 Watchdog.getInstance().addMonitor(this); 1521 1522 mProcessStatsThread = new Thread("ProcessStats") { 1523 public void run() { 1524 while (true) { 1525 try { 1526 try { 1527 synchronized(this) { 1528 final long now = SystemClock.uptimeMillis(); 1529 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1530 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1531 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1532 // + ", write delay=" + nextWriteDelay); 1533 if (nextWriteDelay < nextCpuDelay) { 1534 nextCpuDelay = nextWriteDelay; 1535 } 1536 if (nextCpuDelay > 0) { 1537 mProcessStatsMutexFree.set(true); 1538 this.wait(nextCpuDelay); 1539 } 1540 } 1541 } catch (InterruptedException e) { 1542 } 1543 updateCpuStatsNow(); 1544 } catch (Exception e) { 1545 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1546 } 1547 } 1548 } 1549 }; 1550 mProcessStatsThread.start(); 1551 } 1552 1553 @Override 1554 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1555 throws RemoteException { 1556 if (code == SYSPROPS_TRANSACTION) { 1557 // We need to tell all apps about the system property change. 1558 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1559 synchronized(this) { 1560 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1561 final int NA = apps.size(); 1562 for (int ia=0; ia<NA; ia++) { 1563 ProcessRecord app = apps.valueAt(ia); 1564 if (app.thread != null) { 1565 procs.add(app.thread.asBinder()); 1566 } 1567 } 1568 } 1569 } 1570 1571 int N = procs.size(); 1572 for (int i=0; i<N; i++) { 1573 Parcel data2 = Parcel.obtain(); 1574 try { 1575 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1576 } catch (RemoteException e) { 1577 } 1578 data2.recycle(); 1579 } 1580 } 1581 try { 1582 return super.onTransact(code, data, reply, flags); 1583 } catch (RuntimeException e) { 1584 // The activity manager only throws security exceptions, so let's 1585 // log all others. 1586 if (!(e instanceof SecurityException)) { 1587 Slog.e(TAG, "Activity Manager Crash", e); 1588 } 1589 throw e; 1590 } 1591 } 1592 1593 void updateCpuStats() { 1594 final long now = SystemClock.uptimeMillis(); 1595 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1596 return; 1597 } 1598 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1599 synchronized (mProcessStatsThread) { 1600 mProcessStatsThread.notify(); 1601 } 1602 } 1603 } 1604 1605 void updateCpuStatsNow() { 1606 synchronized (mProcessStatsThread) { 1607 mProcessStatsMutexFree.set(false); 1608 final long now = SystemClock.uptimeMillis(); 1609 boolean haveNewCpuStats = false; 1610 1611 if (MONITOR_CPU_USAGE && 1612 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1613 mLastCpuTime.set(now); 1614 haveNewCpuStats = true; 1615 mProcessStats.update(); 1616 //Slog.i(TAG, mProcessStats.printCurrentState()); 1617 //Slog.i(TAG, "Total CPU usage: " 1618 // + mProcessStats.getTotalCpuPercent() + "%"); 1619 1620 // Slog the cpu usage if the property is set. 1621 if ("true".equals(SystemProperties.get("events.cpu"))) { 1622 int user = mProcessStats.getLastUserTime(); 1623 int system = mProcessStats.getLastSystemTime(); 1624 int iowait = mProcessStats.getLastIoWaitTime(); 1625 int irq = mProcessStats.getLastIrqTime(); 1626 int softIrq = mProcessStats.getLastSoftIrqTime(); 1627 int idle = mProcessStats.getLastIdleTime(); 1628 1629 int total = user + system + iowait + irq + softIrq + idle; 1630 if (total == 0) total = 1; 1631 1632 EventLog.writeEvent(EventLogTags.CPU, 1633 ((user+system+iowait+irq+softIrq) * 100) / total, 1634 (user * 100) / total, 1635 (system * 100) / total, 1636 (iowait * 100) / total, 1637 (irq * 100) / total, 1638 (softIrq * 100) / total); 1639 } 1640 } 1641 1642 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1643 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1644 synchronized(bstats) { 1645 synchronized(mPidsSelfLocked) { 1646 if (haveNewCpuStats) { 1647 if (mOnBattery) { 1648 int perc = bstats.startAddingCpuLocked(); 1649 int totalUTime = 0; 1650 int totalSTime = 0; 1651 final int N = mProcessStats.countStats(); 1652 for (int i=0; i<N; i++) { 1653 ProcessStats.Stats st = mProcessStats.getStats(i); 1654 if (!st.working) { 1655 continue; 1656 } 1657 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1658 int otherUTime = (st.rel_utime*perc)/100; 1659 int otherSTime = (st.rel_stime*perc)/100; 1660 totalUTime += otherUTime; 1661 totalSTime += otherSTime; 1662 if (pr != null) { 1663 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1664 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1665 st.rel_stime-otherSTime); 1666 ps.addSpeedStepTimes(cpuSpeedTimes); 1667 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1668 } else { 1669 BatteryStatsImpl.Uid.Proc ps = 1670 bstats.getProcessStatsLocked(st.name, st.pid); 1671 if (ps != null) { 1672 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1673 st.rel_stime-otherSTime); 1674 ps.addSpeedStepTimes(cpuSpeedTimes); 1675 } 1676 } 1677 } 1678 bstats.finishAddingCpuLocked(perc, totalUTime, 1679 totalSTime, cpuSpeedTimes); 1680 } 1681 } 1682 } 1683 1684 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1685 mLastWriteTime = now; 1686 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1687 } 1688 } 1689 } 1690 } 1691 1692 @Override 1693 public void batteryNeedsCpuUpdate() { 1694 updateCpuStatsNow(); 1695 } 1696 1697 @Override 1698 public void batteryPowerChanged(boolean onBattery) { 1699 // When plugging in, update the CPU stats first before changing 1700 // the plug state. 1701 updateCpuStatsNow(); 1702 synchronized (this) { 1703 synchronized(mPidsSelfLocked) { 1704 mOnBattery = DEBUG_POWER ? true : onBattery; 1705 } 1706 } 1707 } 1708 1709 /** 1710 * Initialize the application bind args. These are passed to each 1711 * process when the bindApplication() IPC is sent to the process. They're 1712 * lazily setup to make sure the services are running when they're asked for. 1713 */ 1714 private HashMap<String, IBinder> getCommonServicesLocked() { 1715 if (mAppBindArgs == null) { 1716 mAppBindArgs = new HashMap<String, IBinder>(); 1717 1718 // Setup the application init args 1719 mAppBindArgs.put("package", ServiceManager.getService("package")); 1720 mAppBindArgs.put("window", ServiceManager.getService("window")); 1721 mAppBindArgs.put(Context.ALARM_SERVICE, 1722 ServiceManager.getService(Context.ALARM_SERVICE)); 1723 } 1724 return mAppBindArgs; 1725 } 1726 1727 final void setFocusedActivityLocked(ActivityRecord r) { 1728 if (mFocusedActivity != r) { 1729 mFocusedActivity = r; 1730 if (r != null) { 1731 mWindowManager.setFocusedApp(r.appToken, true); 1732 } 1733 } 1734 } 1735 1736 private final void updateLruProcessInternalLocked(ProcessRecord app, 1737 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1738 // put it on the LRU to keep track of when it should be exited. 1739 int lrui = mLruProcesses.indexOf(app); 1740 if (lrui >= 0) mLruProcesses.remove(lrui); 1741 1742 int i = mLruProcesses.size()-1; 1743 int skipTop = 0; 1744 1745 app.lruSeq = mLruSeq; 1746 1747 // compute the new weight for this process. 1748 if (updateActivityTime) { 1749 app.lastActivityTime = SystemClock.uptimeMillis(); 1750 } 1751 if (app.activities.size() > 0) { 1752 // If this process has activities, we more strongly want to keep 1753 // it around. 1754 app.lruWeight = app.lastActivityTime; 1755 } else if (app.pubProviders.size() > 0) { 1756 // If this process contains content providers, we want to keep 1757 // it a little more strongly. 1758 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1759 // Also don't let it kick out the first few "real" hidden processes. 1760 skipTop = ProcessList.MIN_HIDDEN_APPS; 1761 } else { 1762 // If this process doesn't have activities, we less strongly 1763 // want to keep it around, and generally want to avoid getting 1764 // in front of any very recently used activities. 1765 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1766 // Also don't let it kick out the first few "real" hidden processes. 1767 skipTop = ProcessList.MIN_HIDDEN_APPS; 1768 } 1769 1770 while (i >= 0) { 1771 ProcessRecord p = mLruProcesses.get(i); 1772 // If this app shouldn't be in front of the first N background 1773 // apps, then skip over that many that are currently hidden. 1774 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1775 skipTop--; 1776 } 1777 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1778 mLruProcesses.add(i+1, app); 1779 break; 1780 } 1781 i--; 1782 } 1783 if (i < 0) { 1784 mLruProcesses.add(0, app); 1785 } 1786 1787 // If the app is currently using a content provider or service, 1788 // bump those processes as well. 1789 if (app.connections.size() > 0) { 1790 for (ConnectionRecord cr : app.connections) { 1791 if (cr.binding != null && cr.binding.service != null 1792 && cr.binding.service.app != null 1793 && cr.binding.service.app.lruSeq != mLruSeq) { 1794 updateLruProcessInternalLocked(cr.binding.service.app, false, 1795 updateActivityTime, i+1); 1796 } 1797 } 1798 } 1799 for (int j=app.conProviders.size()-1; j>=0; j--) { 1800 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1801 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1802 updateLruProcessInternalLocked(cpr.proc, false, 1803 updateActivityTime, i+1); 1804 } 1805 } 1806 1807 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1808 if (oomAdj) { 1809 updateOomAdjLocked(); 1810 } 1811 } 1812 1813 final void updateLruProcessLocked(ProcessRecord app, 1814 boolean oomAdj, boolean updateActivityTime) { 1815 mLruSeq++; 1816 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1817 } 1818 1819 final ProcessRecord getProcessRecordLocked( 1820 String processName, int uid) { 1821 if (uid == Process.SYSTEM_UID) { 1822 // The system gets to run in any process. If there are multiple 1823 // processes with the same uid, just pick the first (this 1824 // should never happen). 1825 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1826 processName); 1827 if (procs == null) return null; 1828 final int N = procs.size(); 1829 for (int i = 0; i < N; i++) { 1830 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1831 } 1832 } 1833 ProcessRecord proc = mProcessNames.get(processName, uid); 1834 return proc; 1835 } 1836 1837 void ensurePackageDexOpt(String packageName) { 1838 IPackageManager pm = AppGlobals.getPackageManager(); 1839 try { 1840 if (pm.performDexOpt(packageName)) { 1841 mDidDexOpt = true; 1842 } 1843 } catch (RemoteException e) { 1844 } 1845 } 1846 1847 boolean isNextTransitionForward() { 1848 int transit = mWindowManager.getPendingAppTransition(); 1849 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1850 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1851 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1852 } 1853 1854 final ProcessRecord startProcessLocked(String processName, 1855 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1856 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1857 boolean isolated) { 1858 ProcessRecord app; 1859 if (!isolated) { 1860 app = getProcessRecordLocked(processName, info.uid); 1861 } else { 1862 // If this is an isolated process, it can't re-use an existing process. 1863 app = null; 1864 } 1865 // We don't have to do anything more if: 1866 // (1) There is an existing application record; and 1867 // (2) The caller doesn't think it is dead, OR there is no thread 1868 // object attached to it so we know it couldn't have crashed; and 1869 // (3) There is a pid assigned to it, so it is either starting or 1870 // already running. 1871 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1872 + " app=" + app + " knownToBeDead=" + knownToBeDead 1873 + " thread=" + (app != null ? app.thread : null) 1874 + " pid=" + (app != null ? app.pid : -1)); 1875 if (app != null && app.pid > 0) { 1876 if (!knownToBeDead || app.thread == null) { 1877 // We already have the app running, or are waiting for it to 1878 // come up (we have a pid but not yet its thread), so keep it. 1879 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1880 // If this is a new package in the process, add the package to the list 1881 app.addPackage(info.packageName); 1882 return app; 1883 } else { 1884 // An application record is attached to a previous process, 1885 // clean it up now. 1886 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1887 handleAppDiedLocked(app, true, true); 1888 } 1889 } 1890 1891 String hostingNameStr = hostingName != null 1892 ? hostingName.flattenToShortString() : null; 1893 1894 if (!isolated) { 1895 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1896 // If we are in the background, then check to see if this process 1897 // is bad. If so, we will just silently fail. 1898 if (mBadProcesses.get(info.processName, info.uid) != null) { 1899 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1900 + "/" + info.processName); 1901 return null; 1902 } 1903 } else { 1904 // When the user is explicitly starting a process, then clear its 1905 // crash count so that we won't make it bad until they see at 1906 // least one crash dialog again, and make the process good again 1907 // if it had been bad. 1908 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1909 + "/" + info.processName); 1910 mProcessCrashTimes.remove(info.processName, info.uid); 1911 if (mBadProcesses.get(info.processName, info.uid) != null) { 1912 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1913 info.processName); 1914 mBadProcesses.remove(info.processName, info.uid); 1915 if (app != null) { 1916 app.bad = false; 1917 } 1918 } 1919 } 1920 } 1921 1922 if (app == null) { 1923 app = newProcessRecordLocked(null, info, processName, isolated); 1924 if (app == null) { 1925 Slog.w(TAG, "Failed making new process record for " 1926 + processName + "/" + info.uid + " isolated=" + isolated); 1927 return null; 1928 } 1929 mProcessNames.put(processName, app.uid, app); 1930 if (isolated) { 1931 mIsolatedProcesses.put(app.uid, app); 1932 } 1933 } else { 1934 // If this is a new package in the process, add the package to the list 1935 app.addPackage(info.packageName); 1936 } 1937 1938 // If the system is not ready yet, then hold off on starting this 1939 // process until it is. 1940 if (!mProcessesReady 1941 && !isAllowedWhileBooting(info) 1942 && !allowWhileBooting) { 1943 if (!mProcessesOnHold.contains(app)) { 1944 mProcessesOnHold.add(app); 1945 } 1946 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1947 return app; 1948 } 1949 1950 startProcessLocked(app, hostingType, hostingNameStr); 1951 return (app.pid != 0) ? app : null; 1952 } 1953 1954 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1955 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1956 } 1957 1958 private final void startProcessLocked(ProcessRecord app, 1959 String hostingType, String hostingNameStr) { 1960 if (app.pid > 0 && app.pid != MY_PID) { 1961 synchronized (mPidsSelfLocked) { 1962 mPidsSelfLocked.remove(app.pid); 1963 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1964 } 1965 app.setPid(0); 1966 } 1967 1968 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1969 "startProcessLocked removing on hold: " + app); 1970 mProcessesOnHold.remove(app); 1971 1972 updateCpuStats(); 1973 1974 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1975 mProcDeaths[0] = 0; 1976 1977 try { 1978 int uid = app.uid; 1979 1980 int[] gids = null; 1981 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1982 if (!app.isolated) { 1983 try { 1984 final PackageManager pm = mContext.getPackageManager(); 1985 gids = pm.getPackageGids(app.info.packageName); 1986 } catch (PackageManager.NameNotFoundException e) { 1987 Slog.w(TAG, "Unable to retrieve gids", e); 1988 } 1989 1990 if (Environment.isExternalStorageEmulated()) { 1991 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 1992 } 1993 } 1994 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1995 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1996 && mTopComponent != null 1997 && app.processName.equals(mTopComponent.getPackageName())) { 1998 uid = 0; 1999 } 2000 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2001 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2002 uid = 0; 2003 } 2004 } 2005 int debugFlags = 0; 2006 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2007 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2008 // Also turn on CheckJNI for debuggable apps. It's quite 2009 // awkward to turn on otherwise. 2010 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2011 } 2012 // Run the app in safe mode if its manifest requests so or the 2013 // system is booted in safe mode. 2014 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2015 Zygote.systemInSafeMode == true) { 2016 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2017 } 2018 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2019 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2020 } 2021 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2022 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2023 } 2024 if ("1".equals(SystemProperties.get("debug.assert"))) { 2025 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2026 } 2027 2028 // Start the process. It will either succeed and return a result containing 2029 // the PID of the new process, or else throw a RuntimeException. 2030 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2031 app.processName, uid, uid, gids, debugFlags, mountExternal, 2032 app.info.targetSdkVersion, null, null); 2033 2034 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2035 synchronized (bs) { 2036 if (bs.isOnBattery()) { 2037 app.batteryStats.incStartsLocked(); 2038 } 2039 } 2040 2041 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2042 app.processName, hostingType, 2043 hostingNameStr != null ? hostingNameStr : ""); 2044 2045 if (app.persistent) { 2046 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2047 } 2048 2049 StringBuilder buf = mStringBuilder; 2050 buf.setLength(0); 2051 buf.append("Start proc "); 2052 buf.append(app.processName); 2053 buf.append(" for "); 2054 buf.append(hostingType); 2055 if (hostingNameStr != null) { 2056 buf.append(" "); 2057 buf.append(hostingNameStr); 2058 } 2059 buf.append(": pid="); 2060 buf.append(startResult.pid); 2061 buf.append(" uid="); 2062 buf.append(uid); 2063 buf.append(" gids={"); 2064 if (gids != null) { 2065 for (int gi=0; gi<gids.length; gi++) { 2066 if (gi != 0) buf.append(", "); 2067 buf.append(gids[gi]); 2068 2069 } 2070 } 2071 buf.append("}"); 2072 Slog.i(TAG, buf.toString()); 2073 app.setPid(startResult.pid); 2074 app.usingWrapper = startResult.usingWrapper; 2075 app.removed = false; 2076 synchronized (mPidsSelfLocked) { 2077 this.mPidsSelfLocked.put(startResult.pid, app); 2078 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2079 msg.obj = app; 2080 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2081 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2082 } 2083 } catch (RuntimeException e) { 2084 // XXX do better error recovery. 2085 app.setPid(0); 2086 Slog.e(TAG, "Failure starting process " + app.processName, e); 2087 } 2088 } 2089 2090 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2091 if (resumed) { 2092 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2093 } else { 2094 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2095 } 2096 } 2097 2098 boolean startHomeActivityLocked(int userId) { 2099 if (mHeadless) { 2100 // Added because none of the other calls to ensureBootCompleted seem to fire 2101 // when running headless. 2102 ensureBootCompleted(); 2103 return false; 2104 } 2105 2106 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2107 && mTopAction == null) { 2108 // We are running in factory test mode, but unable to find 2109 // the factory test app, so just sit around displaying the 2110 // error message and don't try to start anything. 2111 return false; 2112 } 2113 Intent intent = new Intent( 2114 mTopAction, 2115 mTopData != null ? Uri.parse(mTopData) : null); 2116 intent.setComponent(mTopComponent); 2117 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2118 intent.addCategory(Intent.CATEGORY_HOME); 2119 } 2120 ActivityInfo aInfo = 2121 intent.resolveActivityInfo(mContext.getPackageManager(), 2122 STOCK_PM_FLAGS); 2123 if (aInfo != null) { 2124 intent.setComponent(new ComponentName( 2125 aInfo.applicationInfo.packageName, aInfo.name)); 2126 // Don't do this if the home app is currently being 2127 // instrumented. 2128 aInfo = new ActivityInfo(aInfo); 2129 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2130 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2131 aInfo.applicationInfo.uid); 2132 if (app == null || app.instrumentationClass == null) { 2133 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2134 mMainStack.startActivityLocked(null, intent, null, aInfo, 2135 null, null, 0, 0, 0, 0, null, false, null); 2136 } 2137 } 2138 2139 return true; 2140 } 2141 2142 /** 2143 * Starts the "new version setup screen" if appropriate. 2144 */ 2145 void startSetupActivityLocked() { 2146 // Only do this once per boot. 2147 if (mCheckedForSetup) { 2148 return; 2149 } 2150 2151 // We will show this screen if the current one is a different 2152 // version than the last one shown, and we are not running in 2153 // low-level factory test mode. 2154 final ContentResolver resolver = mContext.getContentResolver(); 2155 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2156 Settings.Secure.getInt(resolver, 2157 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2158 mCheckedForSetup = true; 2159 2160 // See if we should be showing the platform update setup UI. 2161 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2162 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2163 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2164 2165 // We don't allow third party apps to replace this. 2166 ResolveInfo ri = null; 2167 for (int i=0; ris != null && i<ris.size(); i++) { 2168 if ((ris.get(i).activityInfo.applicationInfo.flags 2169 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2170 ri = ris.get(i); 2171 break; 2172 } 2173 } 2174 2175 if (ri != null) { 2176 String vers = ri.activityInfo.metaData != null 2177 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2178 : null; 2179 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2180 vers = ri.activityInfo.applicationInfo.metaData.getString( 2181 Intent.METADATA_SETUP_VERSION); 2182 } 2183 String lastVers = Settings.Secure.getString( 2184 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2185 if (vers != null && !vers.equals(lastVers)) { 2186 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2187 intent.setComponent(new ComponentName( 2188 ri.activityInfo.packageName, ri.activityInfo.name)); 2189 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2190 null, null, 0, 0, 0, 0, null, false, null); 2191 } 2192 } 2193 } 2194 } 2195 2196 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2197 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2198 } 2199 2200 void enforceNotIsolatedCaller(String caller) { 2201 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2202 throw new SecurityException("Isolated process not allowed to call " + caller); 2203 } 2204 } 2205 2206 public int getFrontActivityScreenCompatMode() { 2207 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2208 synchronized (this) { 2209 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2210 } 2211 } 2212 2213 public void setFrontActivityScreenCompatMode(int mode) { 2214 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2215 "setFrontActivityScreenCompatMode"); 2216 synchronized (this) { 2217 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2218 } 2219 } 2220 2221 public int getPackageScreenCompatMode(String packageName) { 2222 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2223 synchronized (this) { 2224 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2225 } 2226 } 2227 2228 public void setPackageScreenCompatMode(String packageName, int mode) { 2229 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2230 "setPackageScreenCompatMode"); 2231 synchronized (this) { 2232 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2233 } 2234 } 2235 2236 public boolean getPackageAskScreenCompat(String packageName) { 2237 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2238 synchronized (this) { 2239 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2240 } 2241 } 2242 2243 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2244 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2245 "setPackageAskScreenCompat"); 2246 synchronized (this) { 2247 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2248 } 2249 } 2250 2251 void reportResumedActivityLocked(ActivityRecord r) { 2252 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2253 updateUsageStats(r, true); 2254 } 2255 2256 private void dispatchProcessesChanged() { 2257 int N; 2258 synchronized (this) { 2259 N = mPendingProcessChanges.size(); 2260 if (mActiveProcessChanges.length < N) { 2261 mActiveProcessChanges = new ProcessChangeItem[N]; 2262 } 2263 mPendingProcessChanges.toArray(mActiveProcessChanges); 2264 mAvailProcessChanges.addAll(mPendingProcessChanges); 2265 mPendingProcessChanges.clear(); 2266 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2267 } 2268 int i = mProcessObservers.beginBroadcast(); 2269 while (i > 0) { 2270 i--; 2271 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2272 if (observer != null) { 2273 try { 2274 for (int j=0; j<N; j++) { 2275 ProcessChangeItem item = mActiveProcessChanges[j]; 2276 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2277 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2278 + item.pid + " uid=" + item.uid + ": " 2279 + item.foregroundActivities); 2280 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2281 item.foregroundActivities); 2282 } 2283 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2284 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2285 + item.pid + " uid=" + item.uid + ": " + item.importance); 2286 observer.onImportanceChanged(item.pid, item.uid, 2287 item.importance); 2288 } 2289 } 2290 } catch (RemoteException e) { 2291 } 2292 } 2293 } 2294 mProcessObservers.finishBroadcast(); 2295 } 2296 2297 private void dispatchProcessDied(int pid, int uid) { 2298 int i = mProcessObservers.beginBroadcast(); 2299 while (i > 0) { 2300 i--; 2301 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2302 if (observer != null) { 2303 try { 2304 observer.onProcessDied(pid, uid); 2305 } catch (RemoteException e) { 2306 } 2307 } 2308 } 2309 mProcessObservers.finishBroadcast(); 2310 } 2311 2312 final void doPendingActivityLaunchesLocked(boolean doResume) { 2313 final int N = mPendingActivityLaunches.size(); 2314 if (N <= 0) { 2315 return; 2316 } 2317 for (int i=0; i<N; i++) { 2318 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2319 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2320 pal.startFlags, doResume && i == (N-1), null); 2321 } 2322 mPendingActivityLaunches.clear(); 2323 } 2324 2325 public final int startActivity(IApplicationThread caller, 2326 Intent intent, String resolvedType, IBinder resultTo, 2327 String resultWho, int requestCode, int startFlags, 2328 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2329 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2330 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2331 } 2332 2333 public final int startActivityAsUser(IApplicationThread caller, 2334 Intent intent, String resolvedType, IBinder resultTo, 2335 String resultWho, int requestCode, int startFlags, 2336 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2337 enforceNotIsolatedCaller("startActivity"); 2338 if (userId != UserHandle.getCallingUserId()) { 2339 // Requesting a different user, make sure that they have the permission 2340 if (checkComponentPermission( 2341 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2342 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2343 == PackageManager.PERMISSION_GRANTED) { 2344 // Translate to the current user id, if caller wasn't aware 2345 if (userId == UserHandle.USER_CURRENT) { 2346 userId = mCurrentUserId; 2347 } 2348 } else { 2349 String msg = "Permission Denial: " 2350 + "Request to startActivity as user " + userId 2351 + " but is calling from user " + UserHandle.getCallingUserId() 2352 + "; this requires " 2353 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2354 Slog.w(TAG, msg); 2355 throw new SecurityException(msg); 2356 } 2357 } else { 2358 if (intent.getCategories() != null 2359 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2360 // Requesting home, set the identity to the current user 2361 // HACK! 2362 userId = mCurrentUserId; 2363 } else { 2364 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2365 // the current user's userId 2366 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2367 userId = 0; 2368 } else { 2369 userId = Binder.getOrigCallingUser(); 2370 } 2371 } 2372 } 2373 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2374 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2375 null, null, options, userId); 2376 } 2377 2378 public final WaitResult startActivityAndWait(IApplicationThread caller, 2379 Intent intent, String resolvedType, IBinder resultTo, 2380 String resultWho, int requestCode, int startFlags, String profileFile, 2381 ParcelFileDescriptor profileFd, Bundle options) { 2382 enforceNotIsolatedCaller("startActivityAndWait"); 2383 WaitResult res = new WaitResult(); 2384 int userId = Binder.getOrigCallingUser(); 2385 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2386 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2387 res, null, options, userId); 2388 return res; 2389 } 2390 2391 public final int startActivityWithConfig(IApplicationThread caller, 2392 Intent intent, String resolvedType, IBinder resultTo, 2393 String resultWho, int requestCode, int startFlags, Configuration config, 2394 Bundle options) { 2395 enforceNotIsolatedCaller("startActivityWithConfig"); 2396 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2397 resultTo, resultWho, requestCode, startFlags, 2398 null, null, null, config, options, Binder.getOrigCallingUser()); 2399 return ret; 2400 } 2401 2402 public int startActivityIntentSender(IApplicationThread caller, 2403 IntentSender intent, Intent fillInIntent, String resolvedType, 2404 IBinder resultTo, String resultWho, int requestCode, 2405 int flagsMask, int flagsValues, Bundle options) { 2406 enforceNotIsolatedCaller("startActivityIntentSender"); 2407 // Refuse possible leaked file descriptors 2408 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2409 throw new IllegalArgumentException("File descriptors passed in Intent"); 2410 } 2411 2412 IIntentSender sender = intent.getTarget(); 2413 if (!(sender instanceof PendingIntentRecord)) { 2414 throw new IllegalArgumentException("Bad PendingIntent object"); 2415 } 2416 2417 PendingIntentRecord pir = (PendingIntentRecord)sender; 2418 2419 synchronized (this) { 2420 // If this is coming from the currently resumed activity, it is 2421 // effectively saying that app switches are allowed at this point. 2422 if (mMainStack.mResumedActivity != null 2423 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2424 Binder.getCallingUid()) { 2425 mAppSwitchesAllowedTime = 0; 2426 } 2427 } 2428 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2429 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2430 return ret; 2431 } 2432 2433 public boolean startNextMatchingActivity(IBinder callingActivity, 2434 Intent intent, Bundle options) { 2435 // Refuse possible leaked file descriptors 2436 if (intent != null && intent.hasFileDescriptors() == true) { 2437 throw new IllegalArgumentException("File descriptors passed in Intent"); 2438 } 2439 2440 synchronized (this) { 2441 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2442 if (r == null) { 2443 ActivityOptions.abort(options); 2444 return false; 2445 } 2446 if (r.app == null || r.app.thread == null) { 2447 // The caller is not running... d'oh! 2448 ActivityOptions.abort(options); 2449 return false; 2450 } 2451 intent = new Intent(intent); 2452 // The caller is not allowed to change the data. 2453 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2454 // And we are resetting to find the next component... 2455 intent.setComponent(null); 2456 2457 ActivityInfo aInfo = null; 2458 try { 2459 List<ResolveInfo> resolves = 2460 AppGlobals.getPackageManager().queryIntentActivities( 2461 intent, r.resolvedType, 2462 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2463 UserHandle.getCallingUserId()); 2464 2465 // Look for the original activity in the list... 2466 final int N = resolves != null ? resolves.size() : 0; 2467 for (int i=0; i<N; i++) { 2468 ResolveInfo rInfo = resolves.get(i); 2469 if (rInfo.activityInfo.packageName.equals(r.packageName) 2470 && rInfo.activityInfo.name.equals(r.info.name)) { 2471 // We found the current one... the next matching is 2472 // after it. 2473 i++; 2474 if (i<N) { 2475 aInfo = resolves.get(i).activityInfo; 2476 } 2477 break; 2478 } 2479 } 2480 } catch (RemoteException e) { 2481 } 2482 2483 if (aInfo == null) { 2484 // Nobody who is next! 2485 ActivityOptions.abort(options); 2486 return false; 2487 } 2488 2489 intent.setComponent(new ComponentName( 2490 aInfo.applicationInfo.packageName, aInfo.name)); 2491 intent.setFlags(intent.getFlags()&~( 2492 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2493 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2494 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2495 Intent.FLAG_ACTIVITY_NEW_TASK)); 2496 2497 // Okay now we need to start the new activity, replacing the 2498 // currently running activity. This is a little tricky because 2499 // we want to start the new one as if the current one is finished, 2500 // but not finish the current one first so that there is no flicker. 2501 // And thus... 2502 final boolean wasFinishing = r.finishing; 2503 r.finishing = true; 2504 2505 // Propagate reply information over to the new activity. 2506 final ActivityRecord resultTo = r.resultTo; 2507 final String resultWho = r.resultWho; 2508 final int requestCode = r.requestCode; 2509 r.resultTo = null; 2510 if (resultTo != null) { 2511 resultTo.removeResultsLocked(r, resultWho, requestCode); 2512 } 2513 2514 final long origId = Binder.clearCallingIdentity(); 2515 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2516 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2517 resultWho, requestCode, -1, r.launchedFromUid, 0, 2518 options, false, null); 2519 Binder.restoreCallingIdentity(origId); 2520 2521 r.finishing = wasFinishing; 2522 if (res != ActivityManager.START_SUCCESS) { 2523 return false; 2524 } 2525 return true; 2526 } 2527 } 2528 2529 public final int startActivityInPackage(int uid, 2530 Intent intent, String resolvedType, IBinder resultTo, 2531 String resultWho, int requestCode, int startFlags, Bundle options) { 2532 2533 // This is so super not safe, that only the system (or okay root) 2534 // can do it. 2535 final int callingUid = Binder.getCallingUid(); 2536 if (callingUid != 0 && callingUid != Process.myUid()) { 2537 throw new SecurityException( 2538 "startActivityInPackage only available to the system"); 2539 } 2540 2541 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2542 resultTo, resultWho, requestCode, startFlags, 2543 null, null, null, null, options, UserHandle.getUserId(uid)); 2544 return ret; 2545 } 2546 2547 public final int startActivities(IApplicationThread caller, 2548 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2549 enforceNotIsolatedCaller("startActivities"); 2550 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2551 options, Binder.getOrigCallingUser()); 2552 return ret; 2553 } 2554 2555 public final int startActivitiesInPackage(int uid, 2556 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2557 Bundle options) { 2558 2559 // This is so super not safe, that only the system (or okay root) 2560 // can do it. 2561 final int callingUid = Binder.getCallingUid(); 2562 if (callingUid != 0 && callingUid != Process.myUid()) { 2563 throw new SecurityException( 2564 "startActivityInPackage only available to the system"); 2565 } 2566 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2567 options, UserHandle.getUserId(uid)); 2568 return ret; 2569 } 2570 2571 final void addRecentTaskLocked(TaskRecord task) { 2572 int N = mRecentTasks.size(); 2573 // Quick case: check if the top-most recent task is the same. 2574 if (N > 0 && mRecentTasks.get(0) == task) { 2575 return; 2576 } 2577 // Remove any existing entries that are the same kind of task. 2578 for (int i=0; i<N; i++) { 2579 TaskRecord tr = mRecentTasks.get(i); 2580 if (task.userId == tr.userId 2581 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2582 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2583 mRecentTasks.remove(i); 2584 i--; 2585 N--; 2586 if (task.intent == null) { 2587 // If the new recent task we are adding is not fully 2588 // specified, then replace it with the existing recent task. 2589 task = tr; 2590 } 2591 } 2592 } 2593 if (N >= MAX_RECENT_TASKS) { 2594 mRecentTasks.remove(N-1); 2595 } 2596 mRecentTasks.add(0, task); 2597 } 2598 2599 public void setRequestedOrientation(IBinder token, 2600 int requestedOrientation) { 2601 synchronized (this) { 2602 ActivityRecord r = mMainStack.isInStackLocked(token); 2603 if (r == null) { 2604 return; 2605 } 2606 final long origId = Binder.clearCallingIdentity(); 2607 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2608 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2609 mConfiguration, 2610 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2611 if (config != null) { 2612 r.frozenBeforeDestroy = true; 2613 if (!updateConfigurationLocked(config, r, false, false)) { 2614 mMainStack.resumeTopActivityLocked(null); 2615 } 2616 } 2617 Binder.restoreCallingIdentity(origId); 2618 } 2619 } 2620 2621 public int getRequestedOrientation(IBinder token) { 2622 synchronized (this) { 2623 ActivityRecord r = mMainStack.isInStackLocked(token); 2624 if (r == null) { 2625 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2626 } 2627 return mWindowManager.getAppOrientation(r.appToken); 2628 } 2629 } 2630 2631 /** 2632 * This is the internal entry point for handling Activity.finish(). 2633 * 2634 * @param token The Binder token referencing the Activity we want to finish. 2635 * @param resultCode Result code, if any, from this Activity. 2636 * @param resultData Result data (Intent), if any, from this Activity. 2637 * 2638 * @return Returns true if the activity successfully finished, or false if it is still running. 2639 */ 2640 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2641 // Refuse possible leaked file descriptors 2642 if (resultData != null && resultData.hasFileDescriptors() == true) { 2643 throw new IllegalArgumentException("File descriptors passed in Intent"); 2644 } 2645 2646 synchronized(this) { 2647 if (mController != null) { 2648 // Find the first activity that is not finishing. 2649 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2650 if (next != null) { 2651 // ask watcher if this is allowed 2652 boolean resumeOK = true; 2653 try { 2654 resumeOK = mController.activityResuming(next.packageName); 2655 } catch (RemoteException e) { 2656 mController = null; 2657 } 2658 2659 if (!resumeOK) { 2660 return false; 2661 } 2662 } 2663 } 2664 final long origId = Binder.clearCallingIdentity(); 2665 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2666 resultData, "app-request"); 2667 Binder.restoreCallingIdentity(origId); 2668 return res; 2669 } 2670 } 2671 2672 public final void finishHeavyWeightApp() { 2673 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2674 != PackageManager.PERMISSION_GRANTED) { 2675 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2676 + Binder.getCallingPid() 2677 + ", uid=" + Binder.getCallingUid() 2678 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2679 Slog.w(TAG, msg); 2680 throw new SecurityException(msg); 2681 } 2682 2683 synchronized(this) { 2684 if (mHeavyWeightProcess == null) { 2685 return; 2686 } 2687 2688 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2689 mHeavyWeightProcess.activities); 2690 for (int i=0; i<activities.size(); i++) { 2691 ActivityRecord r = activities.get(i); 2692 if (!r.finishing) { 2693 int index = mMainStack.indexOfTokenLocked(r.appToken); 2694 if (index >= 0) { 2695 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2696 null, "finish-heavy"); 2697 } 2698 } 2699 } 2700 2701 mHeavyWeightProcess = null; 2702 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2703 } 2704 } 2705 2706 public void crashApplication(int uid, int initialPid, String packageName, 2707 String message) { 2708 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2709 != PackageManager.PERMISSION_GRANTED) { 2710 String msg = "Permission Denial: crashApplication() from pid=" 2711 + Binder.getCallingPid() 2712 + ", uid=" + Binder.getCallingUid() 2713 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2714 Slog.w(TAG, msg); 2715 throw new SecurityException(msg); 2716 } 2717 2718 synchronized(this) { 2719 ProcessRecord proc = null; 2720 2721 // Figure out which process to kill. We don't trust that initialPid 2722 // still has any relation to current pids, so must scan through the 2723 // list. 2724 synchronized (mPidsSelfLocked) { 2725 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2726 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2727 if (p.uid != uid) { 2728 continue; 2729 } 2730 if (p.pid == initialPid) { 2731 proc = p; 2732 break; 2733 } 2734 for (String str : p.pkgList) { 2735 if (str.equals(packageName)) { 2736 proc = p; 2737 } 2738 } 2739 } 2740 } 2741 2742 if (proc == null) { 2743 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2744 + " initialPid=" + initialPid 2745 + " packageName=" + packageName); 2746 return; 2747 } 2748 2749 if (proc.thread != null) { 2750 if (proc.pid == Process.myPid()) { 2751 Log.w(TAG, "crashApplication: trying to crash self!"); 2752 return; 2753 } 2754 long ident = Binder.clearCallingIdentity(); 2755 try { 2756 proc.thread.scheduleCrash(message); 2757 } catch (RemoteException e) { 2758 } 2759 Binder.restoreCallingIdentity(ident); 2760 } 2761 } 2762 } 2763 2764 public final void finishSubActivity(IBinder token, String resultWho, 2765 int requestCode) { 2766 synchronized(this) { 2767 final long origId = Binder.clearCallingIdentity(); 2768 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2769 Binder.restoreCallingIdentity(origId); 2770 } 2771 } 2772 2773 public boolean finishActivityAffinity(IBinder token) { 2774 synchronized(this) { 2775 final long origId = Binder.clearCallingIdentity(); 2776 boolean res = mMainStack.finishActivityAffinityLocked(token); 2777 Binder.restoreCallingIdentity(origId); 2778 return res; 2779 } 2780 } 2781 2782 public boolean willActivityBeVisible(IBinder token) { 2783 synchronized(this) { 2784 int i; 2785 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2786 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2787 if (r.appToken == token) { 2788 return true; 2789 } 2790 if (r.fullscreen && !r.finishing) { 2791 return false; 2792 } 2793 } 2794 return true; 2795 } 2796 } 2797 2798 public void overridePendingTransition(IBinder token, String packageName, 2799 int enterAnim, int exitAnim) { 2800 synchronized(this) { 2801 ActivityRecord self = mMainStack.isInStackLocked(token); 2802 if (self == null) { 2803 return; 2804 } 2805 2806 final long origId = Binder.clearCallingIdentity(); 2807 2808 if (self.state == ActivityState.RESUMED 2809 || self.state == ActivityState.PAUSING) { 2810 mWindowManager.overridePendingAppTransition(packageName, 2811 enterAnim, exitAnim, null); 2812 } 2813 2814 Binder.restoreCallingIdentity(origId); 2815 } 2816 } 2817 2818 /** 2819 * Main function for removing an existing process from the activity manager 2820 * as a result of that process going away. Clears out all connections 2821 * to the process. 2822 */ 2823 private final void handleAppDiedLocked(ProcessRecord app, 2824 boolean restarting, boolean allowRestart) { 2825 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2826 if (!restarting) { 2827 mLruProcesses.remove(app); 2828 } 2829 2830 if (mProfileProc == app) { 2831 clearProfilerLocked(); 2832 } 2833 2834 // Just in case... 2835 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2836 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2837 mMainStack.mPausingActivity = null; 2838 } 2839 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2840 mMainStack.mLastPausedActivity = null; 2841 } 2842 2843 // Remove this application's activities from active lists. 2844 mMainStack.removeHistoryRecordsForAppLocked(app); 2845 2846 boolean atTop = true; 2847 boolean hasVisibleActivities = false; 2848 2849 // Clean out the history list. 2850 int i = mMainStack.mHistory.size(); 2851 if (localLOGV) Slog.v( 2852 TAG, "Removing app " + app + " from history with " + i + " entries"); 2853 while (i > 0) { 2854 i--; 2855 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2856 if (localLOGV) Slog.v( 2857 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2858 if (r.app == app) { 2859 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2860 if (ActivityStack.DEBUG_ADD_REMOVE) { 2861 RuntimeException here = new RuntimeException("here"); 2862 here.fillInStackTrace(); 2863 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2864 + ": haveState=" + r.haveState 2865 + " stateNotNeeded=" + r.stateNotNeeded 2866 + " finishing=" + r.finishing 2867 + " state=" + r.state, here); 2868 } 2869 if (!r.finishing) { 2870 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2871 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2872 System.identityHashCode(r), 2873 r.task.taskId, r.shortComponentName, 2874 "proc died without state saved"); 2875 } 2876 mMainStack.removeActivityFromHistoryLocked(r); 2877 2878 } else { 2879 // We have the current state for this activity, so 2880 // it can be restarted later when needed. 2881 if (localLOGV) Slog.v( 2882 TAG, "Keeping entry, setting app to null"); 2883 if (r.visible) { 2884 hasVisibleActivities = true; 2885 } 2886 r.app = null; 2887 r.nowVisible = false; 2888 if (!r.haveState) { 2889 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2890 "App died, clearing saved state of " + r); 2891 r.icicle = null; 2892 } 2893 } 2894 2895 r.stack.cleanUpActivityLocked(r, true, true); 2896 } 2897 atTop = false; 2898 } 2899 2900 app.activities.clear(); 2901 2902 if (app.instrumentationClass != null) { 2903 Slog.w(TAG, "Crash of app " + app.processName 2904 + " running instrumentation " + app.instrumentationClass); 2905 Bundle info = new Bundle(); 2906 info.putString("shortMsg", "Process crashed."); 2907 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2908 } 2909 2910 if (!restarting) { 2911 if (!mMainStack.resumeTopActivityLocked(null)) { 2912 // If there was nothing to resume, and we are not already 2913 // restarting this process, but there is a visible activity that 2914 // is hosted by the process... then make sure all visible 2915 // activities are running, taking care of restarting this 2916 // process. 2917 if (hasVisibleActivities) { 2918 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2919 } 2920 } 2921 } 2922 } 2923 2924 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2925 IBinder threadBinder = thread.asBinder(); 2926 // Find the application record. 2927 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2928 ProcessRecord rec = mLruProcesses.get(i); 2929 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2930 return i; 2931 } 2932 } 2933 return -1; 2934 } 2935 2936 final ProcessRecord getRecordForAppLocked( 2937 IApplicationThread thread) { 2938 if (thread == null) { 2939 return null; 2940 } 2941 2942 int appIndex = getLRURecordIndexForAppLocked(thread); 2943 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2944 } 2945 2946 final void appDiedLocked(ProcessRecord app, int pid, 2947 IApplicationThread thread) { 2948 2949 mProcDeaths[0]++; 2950 2951 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2952 synchronized (stats) { 2953 stats.noteProcessDiedLocked(app.info.uid, pid); 2954 } 2955 2956 // Clean up already done if the process has been re-started. 2957 if (app.pid == pid && app.thread != null && 2958 app.thread.asBinder() == thread.asBinder()) { 2959 if (!app.killedBackground) { 2960 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2961 + ") has died."); 2962 } 2963 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2964 if (localLOGV) Slog.v( 2965 TAG, "Dying app: " + app + ", pid: " + pid 2966 + ", thread: " + thread.asBinder()); 2967 boolean doLowMem = app.instrumentationClass == null; 2968 handleAppDiedLocked(app, false, true); 2969 2970 if (doLowMem) { 2971 // If there are no longer any background processes running, 2972 // and the app that died was not running instrumentation, 2973 // then tell everyone we are now low on memory. 2974 boolean haveBg = false; 2975 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2976 ProcessRecord rec = mLruProcesses.get(i); 2977 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2978 haveBg = true; 2979 break; 2980 } 2981 } 2982 2983 if (!haveBg) { 2984 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2985 long now = SystemClock.uptimeMillis(); 2986 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2987 ProcessRecord rec = mLruProcesses.get(i); 2988 if (rec != app && rec.thread != null && 2989 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2990 // The low memory report is overriding any current 2991 // state for a GC request. Make sure to do 2992 // heavy/important/visible/foreground processes first. 2993 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2994 rec.lastRequestedGc = 0; 2995 } else { 2996 rec.lastRequestedGc = rec.lastLowMemory; 2997 } 2998 rec.reportLowMemory = true; 2999 rec.lastLowMemory = now; 3000 mProcessesToGc.remove(rec); 3001 addProcessToGcListLocked(rec); 3002 } 3003 } 3004 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3005 scheduleAppGcsLocked(); 3006 } 3007 } 3008 } else if (app.pid != pid) { 3009 // A new process has already been started. 3010 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3011 + ") has died and restarted (pid " + app.pid + ")."); 3012 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3013 } else if (DEBUG_PROCESSES) { 3014 Slog.d(TAG, "Received spurious death notification for thread " 3015 + thread.asBinder()); 3016 } 3017 } 3018 3019 /** 3020 * If a stack trace dump file is configured, dump process stack traces. 3021 * @param clearTraces causes the dump file to be erased prior to the new 3022 * traces being written, if true; when false, the new traces will be 3023 * appended to any existing file content. 3024 * @param firstPids of dalvik VM processes to dump stack traces for first 3025 * @param lastPids of dalvik VM processes to dump stack traces for last 3026 * @param nativeProcs optional list of native process names to dump stack crawls 3027 * @return file containing stack traces, or null if no dump file is configured 3028 */ 3029 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3030 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3031 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3032 if (tracesPath == null || tracesPath.length() == 0) { 3033 return null; 3034 } 3035 3036 File tracesFile = new File(tracesPath); 3037 try { 3038 File tracesDir = tracesFile.getParentFile(); 3039 if (!tracesDir.exists()) { 3040 tracesFile.mkdirs(); 3041 if (!SELinux.restorecon(tracesDir)) { 3042 return null; 3043 } 3044 } 3045 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3046 3047 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3048 tracesFile.createNewFile(); 3049 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3050 } catch (IOException e) { 3051 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3052 return null; 3053 } 3054 3055 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3056 return tracesFile; 3057 } 3058 3059 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3060 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3061 // Use a FileObserver to detect when traces finish writing. 3062 // The order of traces is considered important to maintain for legibility. 3063 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3064 public synchronized void onEvent(int event, String path) { notify(); } 3065 }; 3066 3067 try { 3068 observer.startWatching(); 3069 3070 // First collect all of the stacks of the most important pids. 3071 if (firstPids != null) { 3072 try { 3073 int num = firstPids.size(); 3074 for (int i = 0; i < num; i++) { 3075 synchronized (observer) { 3076 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3077 observer.wait(200); // Wait for write-close, give up after 200msec 3078 } 3079 } 3080 } catch (InterruptedException e) { 3081 Log.wtf(TAG, e); 3082 } 3083 } 3084 3085 // Next measure CPU usage. 3086 if (processStats != null) { 3087 processStats.init(); 3088 System.gc(); 3089 processStats.update(); 3090 try { 3091 synchronized (processStats) { 3092 processStats.wait(500); // measure over 1/2 second. 3093 } 3094 } catch (InterruptedException e) { 3095 } 3096 processStats.update(); 3097 3098 // We'll take the stack crawls of just the top apps using CPU. 3099 final int N = processStats.countWorkingStats(); 3100 int numProcs = 0; 3101 for (int i=0; i<N && numProcs<5; i++) { 3102 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3103 if (lastPids.indexOfKey(stats.pid) >= 0) { 3104 numProcs++; 3105 try { 3106 synchronized (observer) { 3107 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3108 observer.wait(200); // Wait for write-close, give up after 200msec 3109 } 3110 } catch (InterruptedException e) { 3111 Log.wtf(TAG, e); 3112 } 3113 3114 } 3115 } 3116 } 3117 3118 } finally { 3119 observer.stopWatching(); 3120 } 3121 3122 if (nativeProcs != null) { 3123 int[] pids = Process.getPidsForCommands(nativeProcs); 3124 if (pids != null) { 3125 for (int pid : pids) { 3126 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3127 } 3128 } 3129 } 3130 } 3131 3132 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3133 if (true || IS_USER_BUILD) { 3134 return; 3135 } 3136 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3137 if (tracesPath == null || tracesPath.length() == 0) { 3138 return; 3139 } 3140 3141 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3142 StrictMode.allowThreadDiskWrites(); 3143 try { 3144 final File tracesFile = new File(tracesPath); 3145 final File tracesDir = tracesFile.getParentFile(); 3146 final File tracesTmp = new File(tracesDir, "__tmp__"); 3147 try { 3148 if (!tracesDir.exists()) { 3149 tracesFile.mkdirs(); 3150 if (!SELinux.restorecon(tracesDir.getPath())) { 3151 return; 3152 } 3153 } 3154 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3155 3156 if (tracesFile.exists()) { 3157 tracesTmp.delete(); 3158 tracesFile.renameTo(tracesTmp); 3159 } 3160 StringBuilder sb = new StringBuilder(); 3161 Time tobj = new Time(); 3162 tobj.set(System.currentTimeMillis()); 3163 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3164 sb.append(": "); 3165 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3166 sb.append(" since "); 3167 sb.append(msg); 3168 FileOutputStream fos = new FileOutputStream(tracesFile); 3169 fos.write(sb.toString().getBytes()); 3170 if (app == null) { 3171 fos.write("\n*** No application process!".getBytes()); 3172 } 3173 fos.close(); 3174 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3175 } catch (IOException e) { 3176 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3177 return; 3178 } 3179 3180 if (app != null) { 3181 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3182 firstPids.add(app.pid); 3183 dumpStackTraces(tracesPath, firstPids, null, null, null); 3184 } 3185 3186 File lastTracesFile = null; 3187 File curTracesFile = null; 3188 for (int i=9; i>=0; i--) { 3189 String name = String.format("slow%02d.txt", i); 3190 curTracesFile = new File(tracesDir, name); 3191 if (curTracesFile.exists()) { 3192 if (lastTracesFile != null) { 3193 curTracesFile.renameTo(lastTracesFile); 3194 } else { 3195 curTracesFile.delete(); 3196 } 3197 } 3198 lastTracesFile = curTracesFile; 3199 } 3200 tracesFile.renameTo(curTracesFile); 3201 if (tracesTmp.exists()) { 3202 tracesTmp.renameTo(tracesFile); 3203 } 3204 } finally { 3205 StrictMode.setThreadPolicy(oldPolicy); 3206 } 3207 } 3208 3209 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3210 ActivityRecord parent, final String annotation) { 3211 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3212 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3213 3214 if (mController != null) { 3215 try { 3216 // 0 == continue, -1 = kill process immediately 3217 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3218 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3219 } catch (RemoteException e) { 3220 mController = null; 3221 } 3222 } 3223 3224 long anrTime = SystemClock.uptimeMillis(); 3225 if (MONITOR_CPU_USAGE) { 3226 updateCpuStatsNow(); 3227 } 3228 3229 synchronized (this) { 3230 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3231 if (mShuttingDown) { 3232 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3233 return; 3234 } else if (app.notResponding) { 3235 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3236 return; 3237 } else if (app.crashing) { 3238 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3239 return; 3240 } 3241 3242 // In case we come through here for the same app before completing 3243 // this one, mark as anring now so we will bail out. 3244 app.notResponding = true; 3245 3246 // Log the ANR to the event log. 3247 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3248 annotation); 3249 3250 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3251 firstPids.add(app.pid); 3252 3253 int parentPid = app.pid; 3254 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3255 if (parentPid != app.pid) firstPids.add(parentPid); 3256 3257 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3258 3259 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3260 ProcessRecord r = mLruProcesses.get(i); 3261 if (r != null && r.thread != null) { 3262 int pid = r.pid; 3263 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3264 if (r.persistent) { 3265 firstPids.add(pid); 3266 } else { 3267 lastPids.put(pid, Boolean.TRUE); 3268 } 3269 } 3270 } 3271 } 3272 } 3273 3274 // Log the ANR to the main log. 3275 StringBuilder info = new StringBuilder(); 3276 info.setLength(0); 3277 info.append("ANR in ").append(app.processName); 3278 if (activity != null && activity.shortComponentName != null) { 3279 info.append(" (").append(activity.shortComponentName).append(")"); 3280 } 3281 info.append("\n"); 3282 if (annotation != null) { 3283 info.append("Reason: ").append(annotation).append("\n"); 3284 } 3285 if (parent != null && parent != activity) { 3286 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3287 } 3288 3289 final ProcessStats processStats = new ProcessStats(true); 3290 3291 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3292 3293 String cpuInfo = null; 3294 if (MONITOR_CPU_USAGE) { 3295 updateCpuStatsNow(); 3296 synchronized (mProcessStatsThread) { 3297 cpuInfo = mProcessStats.printCurrentState(anrTime); 3298 } 3299 info.append(processStats.printCurrentLoad()); 3300 info.append(cpuInfo); 3301 } 3302 3303 info.append(processStats.printCurrentState(anrTime)); 3304 3305 Slog.e(TAG, info.toString()); 3306 if (tracesFile == null) { 3307 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3308 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3309 } 3310 3311 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3312 cpuInfo, tracesFile, null); 3313 3314 if (mController != null) { 3315 try { 3316 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3317 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3318 if (res != 0) { 3319 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3320 return; 3321 } 3322 } catch (RemoteException e) { 3323 mController = null; 3324 } 3325 } 3326 3327 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3328 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3329 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3330 3331 synchronized (this) { 3332 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3333 Slog.w(TAG, "Killing " + app + ": background ANR"); 3334 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3335 app.processName, app.setAdj, "background ANR"); 3336 Process.killProcessQuiet(app.pid); 3337 return; 3338 } 3339 3340 // Set the app's notResponding state, and look up the errorReportReceiver 3341 makeAppNotRespondingLocked(app, 3342 activity != null ? activity.shortComponentName : null, 3343 annotation != null ? "ANR " + annotation : "ANR", 3344 info.toString()); 3345 3346 // Bring up the infamous App Not Responding dialog 3347 Message msg = Message.obtain(); 3348 HashMap map = new HashMap(); 3349 msg.what = SHOW_NOT_RESPONDING_MSG; 3350 msg.obj = map; 3351 map.put("app", app); 3352 if (activity != null) { 3353 map.put("activity", activity); 3354 } 3355 3356 mHandler.sendMessage(msg); 3357 } 3358 } 3359 3360 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3361 if (!mLaunchWarningShown) { 3362 mLaunchWarningShown = true; 3363 mHandler.post(new Runnable() { 3364 @Override 3365 public void run() { 3366 synchronized (ActivityManagerService.this) { 3367 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3368 d.show(); 3369 mHandler.postDelayed(new Runnable() { 3370 @Override 3371 public void run() { 3372 synchronized (ActivityManagerService.this) { 3373 d.dismiss(); 3374 mLaunchWarningShown = false; 3375 } 3376 } 3377 }, 4000); 3378 } 3379 } 3380 }); 3381 } 3382 } 3383 3384 public boolean clearApplicationUserData(final String packageName, 3385 final IPackageDataObserver observer, final int userId) { 3386 enforceNotIsolatedCaller("clearApplicationUserData"); 3387 int uid = Binder.getCallingUid(); 3388 int pid = Binder.getCallingPid(); 3389 long callingId = Binder.clearCallingIdentity(); 3390 try { 3391 IPackageManager pm = AppGlobals.getPackageManager(); 3392 int pkgUid = -1; 3393 synchronized(this) { 3394 try { 3395 pkgUid = pm.getPackageUid(packageName, userId); 3396 } catch (RemoteException e) { 3397 } 3398 if (pkgUid == -1) { 3399 Slog.w(TAG, "Invalid packageName:" + packageName); 3400 return false; 3401 } 3402 if (uid == pkgUid || checkComponentPermission( 3403 android.Manifest.permission.CLEAR_APP_USER_DATA, 3404 pid, uid, -1, true) 3405 == PackageManager.PERMISSION_GRANTED) { 3406 forceStopPackageLocked(packageName, pkgUid); 3407 } else { 3408 throw new SecurityException(pid+" does not have permission:"+ 3409 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3410 "for process:"+packageName); 3411 } 3412 } 3413 3414 try { 3415 //clear application user data 3416 pm.clearApplicationUserData(packageName, observer, userId); 3417 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3418 Uri.fromParts("package", packageName, null)); 3419 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3420 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3421 null, null, 0, null, null, null, false, false, userId); 3422 } catch (RemoteException e) { 3423 } 3424 } finally { 3425 Binder.restoreCallingIdentity(callingId); 3426 } 3427 return true; 3428 } 3429 3430 public void killBackgroundProcesses(final String packageName) { 3431 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3432 != PackageManager.PERMISSION_GRANTED && 3433 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3434 != PackageManager.PERMISSION_GRANTED) { 3435 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3436 + Binder.getCallingPid() 3437 + ", uid=" + Binder.getCallingUid() 3438 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3439 Slog.w(TAG, msg); 3440 throw new SecurityException(msg); 3441 } 3442 3443 int userId = UserHandle.getCallingUserId(); 3444 long callingId = Binder.clearCallingIdentity(); 3445 try { 3446 IPackageManager pm = AppGlobals.getPackageManager(); 3447 int pkgUid = -1; 3448 synchronized(this) { 3449 try { 3450 pkgUid = pm.getPackageUid(packageName, userId); 3451 } catch (RemoteException e) { 3452 } 3453 if (pkgUid == -1) { 3454 Slog.w(TAG, "Invalid packageName: " + packageName); 3455 return; 3456 } 3457 killPackageProcessesLocked(packageName, pkgUid, 3458 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3459 } 3460 } finally { 3461 Binder.restoreCallingIdentity(callingId); 3462 } 3463 } 3464 3465 public void killAllBackgroundProcesses() { 3466 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3467 != PackageManager.PERMISSION_GRANTED) { 3468 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3469 + Binder.getCallingPid() 3470 + ", uid=" + Binder.getCallingUid() 3471 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3472 Slog.w(TAG, msg); 3473 throw new SecurityException(msg); 3474 } 3475 3476 long callingId = Binder.clearCallingIdentity(); 3477 try { 3478 synchronized(this) { 3479 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3480 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3481 final int NA = apps.size(); 3482 for (int ia=0; ia<NA; ia++) { 3483 ProcessRecord app = apps.valueAt(ia); 3484 if (app.persistent) { 3485 // we don't kill persistent processes 3486 continue; 3487 } 3488 if (app.removed) { 3489 procs.add(app); 3490 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3491 app.removed = true; 3492 procs.add(app); 3493 } 3494 } 3495 } 3496 3497 int N = procs.size(); 3498 for (int i=0; i<N; i++) { 3499 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3500 } 3501 } 3502 } finally { 3503 Binder.restoreCallingIdentity(callingId); 3504 } 3505 } 3506 3507 public void forceStopPackage(final String packageName) { 3508 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3509 != PackageManager.PERMISSION_GRANTED) { 3510 String msg = "Permission Denial: forceStopPackage() from pid=" 3511 + Binder.getCallingPid() 3512 + ", uid=" + Binder.getCallingUid() 3513 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3514 Slog.w(TAG, msg); 3515 throw new SecurityException(msg); 3516 } 3517 final int userId = UserHandle.getCallingUserId(); 3518 long callingId = Binder.clearCallingIdentity(); 3519 try { 3520 IPackageManager pm = AppGlobals.getPackageManager(); 3521 int pkgUid = -1; 3522 synchronized(this) { 3523 try { 3524 pkgUid = pm.getPackageUid(packageName, userId); 3525 } catch (RemoteException e) { 3526 } 3527 if (pkgUid == -1) { 3528 Slog.w(TAG, "Invalid packageName: " + packageName); 3529 return; 3530 } 3531 forceStopPackageLocked(packageName, pkgUid); 3532 try { 3533 pm.setPackageStoppedState(packageName, true, userId); 3534 } catch (RemoteException e) { 3535 } catch (IllegalArgumentException e) { 3536 Slog.w(TAG, "Failed trying to unstop package " 3537 + packageName + ": " + e); 3538 } 3539 } 3540 } finally { 3541 Binder.restoreCallingIdentity(callingId); 3542 } 3543 } 3544 3545 /* 3546 * The pkg name and uid have to be specified. 3547 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3548 */ 3549 public void killApplicationWithUid(String pkg, int uid) { 3550 if (pkg == null) { 3551 return; 3552 } 3553 // Make sure the uid is valid. 3554 if (uid < 0) { 3555 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3556 return; 3557 } 3558 int callerUid = Binder.getCallingUid(); 3559 // Only the system server can kill an application 3560 if (callerUid == Process.SYSTEM_UID) { 3561 // Post an aysnc message to kill the application 3562 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3563 msg.arg1 = uid; 3564 msg.arg2 = 0; 3565 msg.obj = pkg; 3566 mHandler.sendMessage(msg); 3567 } else { 3568 throw new SecurityException(callerUid + " cannot kill pkg: " + 3569 pkg); 3570 } 3571 } 3572 3573 public void closeSystemDialogs(String reason) { 3574 enforceNotIsolatedCaller("closeSystemDialogs"); 3575 3576 final int uid = Binder.getCallingUid(); 3577 final long origId = Binder.clearCallingIdentity(); 3578 synchronized (this) { 3579 closeSystemDialogsLocked(uid, reason); 3580 } 3581 Binder.restoreCallingIdentity(origId); 3582 } 3583 3584 void closeSystemDialogsLocked(int callingUid, String reason) { 3585 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3586 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3587 if (reason != null) { 3588 intent.putExtra("reason", reason); 3589 } 3590 mWindowManager.closeSystemDialogs(reason); 3591 3592 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3593 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3594 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3595 r.stack.finishActivityLocked(r, i, 3596 Activity.RESULT_CANCELED, null, "close-sys"); 3597 } 3598 } 3599 3600 broadcastIntentLocked(null, null, intent, null, 3601 null, 0, null, null, null, false, false, -1, 3602 callingUid, 0 /* TODO: Verify */); 3603 } 3604 3605 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3606 throws RemoteException { 3607 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3608 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3609 for (int i=pids.length-1; i>=0; i--) { 3610 infos[i] = new Debug.MemoryInfo(); 3611 Debug.getMemoryInfo(pids[i], infos[i]); 3612 } 3613 return infos; 3614 } 3615 3616 public long[] getProcessPss(int[] pids) throws RemoteException { 3617 enforceNotIsolatedCaller("getProcessPss"); 3618 long[] pss = new long[pids.length]; 3619 for (int i=pids.length-1; i>=0; i--) { 3620 pss[i] = Debug.getPss(pids[i]); 3621 } 3622 return pss; 3623 } 3624 3625 public void killApplicationProcess(String processName, int uid) { 3626 if (processName == null) { 3627 return; 3628 } 3629 3630 int callerUid = Binder.getCallingUid(); 3631 // Only the system server can kill an application 3632 if (callerUid == Process.SYSTEM_UID) { 3633 synchronized (this) { 3634 ProcessRecord app = getProcessRecordLocked(processName, uid); 3635 if (app != null && app.thread != null) { 3636 try { 3637 app.thread.scheduleSuicide(); 3638 } catch (RemoteException e) { 3639 // If the other end already died, then our work here is done. 3640 } 3641 } else { 3642 Slog.w(TAG, "Process/uid not found attempting kill of " 3643 + processName + " / " + uid); 3644 } 3645 } 3646 } else { 3647 throw new SecurityException(callerUid + " cannot kill app process: " + 3648 processName); 3649 } 3650 } 3651 3652 private void forceStopPackageLocked(final String packageName, int uid) { 3653 forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid)); 3654 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3655 Uri.fromParts("package", packageName, null)); 3656 if (!mProcessesReady) { 3657 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3658 } 3659 intent.putExtra(Intent.EXTRA_UID, uid); 3660 broadcastIntentLocked(null, null, intent, 3661 null, null, 0, null, null, null, 3662 false, false, 3663 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3664 } 3665 3666 private final boolean killPackageProcessesLocked(String packageName, int uid, 3667 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3668 boolean evenPersistent, String reason) { 3669 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3670 3671 // Remove all processes this package may have touched: all with the 3672 // same UID (except for the system or root user), and all whose name 3673 // matches the package name. 3674 final String procNamePrefix = packageName + ":"; 3675 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3676 final int NA = apps.size(); 3677 for (int ia=0; ia<NA; ia++) { 3678 ProcessRecord app = apps.valueAt(ia); 3679 if (app.persistent && !evenPersistent) { 3680 // we don't kill persistent processes 3681 continue; 3682 } 3683 if (app.removed) { 3684 if (doit) { 3685 procs.add(app); 3686 } 3687 // If uid is specified and the uid and process name match 3688 // Or, the uid is not specified and the process name matches 3689 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3690 || ((app.processName.equals(packageName) 3691 || app.processName.startsWith(procNamePrefix)) 3692 && uid < 0))) { 3693 if (app.setAdj >= minOomAdj) { 3694 if (!doit) { 3695 return true; 3696 } 3697 app.removed = true; 3698 procs.add(app); 3699 } 3700 } 3701 } 3702 } 3703 3704 int N = procs.size(); 3705 for (int i=0; i<N; i++) { 3706 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3707 } 3708 return N > 0; 3709 } 3710 3711 private final boolean forceStopPackageLocked(String name, int uid, 3712 boolean callerWillRestart, boolean purgeCache, boolean doit, 3713 boolean evenPersistent, int userId) { 3714 int i; 3715 int N; 3716 3717 if (uid < 0) { 3718 try { 3719 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3720 } catch (RemoteException e) { 3721 } 3722 } 3723 3724 if (doit) { 3725 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3726 3727 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3728 while (badApps.hasNext()) { 3729 SparseArray<Long> ba = badApps.next(); 3730 if (ba.get(uid) != null) { 3731 badApps.remove(); 3732 } 3733 } 3734 } 3735 3736 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3737 callerWillRestart, false, doit, evenPersistent, "force stop"); 3738 3739 TaskRecord lastTask = null; 3740 for (i=0; i<mMainStack.mHistory.size(); i++) { 3741 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3742 final boolean samePackage = r.packageName.equals(name); 3743 if (r.userId == userId 3744 && (samePackage || r.task == lastTask) 3745 && (r.app == null || evenPersistent || !r.app.persistent)) { 3746 if (!doit) { 3747 if (r.finishing) { 3748 // If this activity is just finishing, then it is not 3749 // interesting as far as something to stop. 3750 continue; 3751 } 3752 return true; 3753 } 3754 didSomething = true; 3755 Slog.i(TAG, " Force finishing activity " + r); 3756 if (samePackage) { 3757 if (r.app != null) { 3758 r.app.removed = true; 3759 } 3760 r.app = null; 3761 } 3762 lastTask = r.task; 3763 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3764 null, "force-stop", true)) { 3765 i--; 3766 } 3767 } 3768 } 3769 3770 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3771 if (!doit) { 3772 return true; 3773 } 3774 didSomething = true; 3775 } 3776 3777 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3778 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3779 if (provider.info.packageName.equals(name) 3780 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3781 if (!doit) { 3782 return true; 3783 } 3784 didSomething = true; 3785 providers.add(provider); 3786 } 3787 } 3788 3789 N = providers.size(); 3790 for (i=0; i<N; i++) { 3791 removeDyingProviderLocked(null, providers.get(i), true); 3792 } 3793 3794 if (doit) { 3795 if (purgeCache) { 3796 AttributeCache ac = AttributeCache.instance(); 3797 if (ac != null) { 3798 ac.removePackage(name); 3799 } 3800 } 3801 if (mBooted) { 3802 mMainStack.resumeTopActivityLocked(null); 3803 mMainStack.scheduleIdleLocked(); 3804 } 3805 } 3806 3807 return didSomething; 3808 } 3809 3810 private final boolean removeProcessLocked(ProcessRecord app, 3811 boolean callerWillRestart, boolean allowRestart, String reason) { 3812 final String name = app.processName; 3813 final int uid = app.uid; 3814 if (DEBUG_PROCESSES) Slog.d( 3815 TAG, "Force removing proc " + app.toShortString() + " (" + name 3816 + "/" + uid + ")"); 3817 3818 mProcessNames.remove(name, uid); 3819 mIsolatedProcesses.remove(app.uid); 3820 if (mHeavyWeightProcess == app) { 3821 mHeavyWeightProcess = null; 3822 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3823 } 3824 boolean needRestart = false; 3825 if (app.pid > 0 && app.pid != MY_PID) { 3826 int pid = app.pid; 3827 synchronized (mPidsSelfLocked) { 3828 mPidsSelfLocked.remove(pid); 3829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3830 } 3831 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3832 handleAppDiedLocked(app, true, allowRestart); 3833 mLruProcesses.remove(app); 3834 Process.killProcessQuiet(pid); 3835 3836 if (app.persistent && !app.isolated) { 3837 if (!callerWillRestart) { 3838 addAppLocked(app.info, false); 3839 } else { 3840 needRestart = true; 3841 } 3842 } 3843 } else { 3844 mRemovedProcesses.add(app); 3845 } 3846 3847 return needRestart; 3848 } 3849 3850 private final void processStartTimedOutLocked(ProcessRecord app) { 3851 final int pid = app.pid; 3852 boolean gone = false; 3853 synchronized (mPidsSelfLocked) { 3854 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3855 if (knownApp != null && knownApp.thread == null) { 3856 mPidsSelfLocked.remove(pid); 3857 gone = true; 3858 } 3859 } 3860 3861 if (gone) { 3862 Slog.w(TAG, "Process " + app + " failed to attach"); 3863 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3864 app.processName); 3865 mProcessNames.remove(app.processName, app.uid); 3866 mIsolatedProcesses.remove(app.uid); 3867 if (mHeavyWeightProcess == app) { 3868 mHeavyWeightProcess = null; 3869 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3870 } 3871 // Take care of any launching providers waiting for this process. 3872 checkAppInLaunchingProvidersLocked(app, true); 3873 // Take care of any services that are waiting for the process. 3874 mServices.processStartTimedOutLocked(app); 3875 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3876 app.processName, app.setAdj, "start timeout"); 3877 Process.killProcessQuiet(pid); 3878 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3879 Slog.w(TAG, "Unattached app died before backup, skipping"); 3880 try { 3881 IBackupManager bm = IBackupManager.Stub.asInterface( 3882 ServiceManager.getService(Context.BACKUP_SERVICE)); 3883 bm.agentDisconnected(app.info.packageName); 3884 } catch (RemoteException e) { 3885 // Can't happen; the backup manager is local 3886 } 3887 } 3888 if (isPendingBroadcastProcessLocked(pid)) { 3889 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3890 skipPendingBroadcastLocked(pid); 3891 } 3892 } else { 3893 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3894 } 3895 } 3896 3897 private final boolean attachApplicationLocked(IApplicationThread thread, 3898 int pid) { 3899 3900 // Find the application record that is being attached... either via 3901 // the pid if we are running in multiple processes, or just pull the 3902 // next app record if we are emulating process with anonymous threads. 3903 ProcessRecord app; 3904 if (pid != MY_PID && pid >= 0) { 3905 synchronized (mPidsSelfLocked) { 3906 app = mPidsSelfLocked.get(pid); 3907 } 3908 } else { 3909 app = null; 3910 } 3911 3912 if (app == null) { 3913 Slog.w(TAG, "No pending application record for pid " + pid 3914 + " (IApplicationThread " + thread + "); dropping process"); 3915 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3916 if (pid > 0 && pid != MY_PID) { 3917 Process.killProcessQuiet(pid); 3918 } else { 3919 try { 3920 thread.scheduleExit(); 3921 } catch (Exception e) { 3922 // Ignore exceptions. 3923 } 3924 } 3925 return false; 3926 } 3927 3928 // If this application record is still attached to a previous 3929 // process, clean it up now. 3930 if (app.thread != null) { 3931 handleAppDiedLocked(app, true, true); 3932 } 3933 3934 // Tell the process all about itself. 3935 3936 if (localLOGV) Slog.v( 3937 TAG, "Binding process pid " + pid + " to record " + app); 3938 3939 String processName = app.processName; 3940 try { 3941 AppDeathRecipient adr = new AppDeathRecipient( 3942 app, pid, thread); 3943 thread.asBinder().linkToDeath(adr, 0); 3944 app.deathRecipient = adr; 3945 } catch (RemoteException e) { 3946 app.resetPackageList(); 3947 startProcessLocked(app, "link fail", processName); 3948 return false; 3949 } 3950 3951 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3952 3953 app.thread = thread; 3954 app.curAdj = app.setAdj = -100; 3955 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3956 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3957 app.forcingToForeground = null; 3958 app.foregroundServices = false; 3959 app.hasShownUi = false; 3960 app.debugging = false; 3961 3962 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3963 3964 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3965 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3966 3967 if (!normalMode) { 3968 Slog.i(TAG, "Launching preboot mode app: " + app); 3969 } 3970 3971 if (localLOGV) Slog.v( 3972 TAG, "New app record " + app 3973 + " thread=" + thread.asBinder() + " pid=" + pid); 3974 try { 3975 int testMode = IApplicationThread.DEBUG_OFF; 3976 if (mDebugApp != null && mDebugApp.equals(processName)) { 3977 testMode = mWaitForDebugger 3978 ? IApplicationThread.DEBUG_WAIT 3979 : IApplicationThread.DEBUG_ON; 3980 app.debugging = true; 3981 if (mDebugTransient) { 3982 mDebugApp = mOrigDebugApp; 3983 mWaitForDebugger = mOrigWaitForDebugger; 3984 } 3985 } 3986 String profileFile = app.instrumentationProfileFile; 3987 ParcelFileDescriptor profileFd = null; 3988 boolean profileAutoStop = false; 3989 if (mProfileApp != null && mProfileApp.equals(processName)) { 3990 mProfileProc = app; 3991 profileFile = mProfileFile; 3992 profileFd = mProfileFd; 3993 profileAutoStop = mAutoStopProfiler; 3994 } 3995 boolean enableOpenGlTrace = false; 3996 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3997 enableOpenGlTrace = true; 3998 mOpenGlTraceApp = null; 3999 } 4000 4001 // If the app is being launched for restore or full backup, set it up specially 4002 boolean isRestrictedBackupMode = false; 4003 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4004 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4005 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4006 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4007 } 4008 4009 ensurePackageDexOpt(app.instrumentationInfo != null 4010 ? app.instrumentationInfo.packageName 4011 : app.info.packageName); 4012 if (app.instrumentationClass != null) { 4013 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4014 } 4015 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4016 + processName + " with config " + mConfiguration); 4017 ApplicationInfo appInfo = app.instrumentationInfo != null 4018 ? app.instrumentationInfo : app.info; 4019 app.compat = compatibilityInfoForPackageLocked(appInfo); 4020 if (profileFd != null) { 4021 profileFd = profileFd.dup(); 4022 } 4023 thread.bindApplication(processName, appInfo, providers, 4024 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4025 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4026 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4027 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4028 mCoreSettingsObserver.getCoreSettingsLocked()); 4029 updateLruProcessLocked(app, false, true); 4030 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4031 } catch (Exception e) { 4032 // todo: Yikes! What should we do? For now we will try to 4033 // start another process, but that could easily get us in 4034 // an infinite loop of restarting processes... 4035 Slog.w(TAG, "Exception thrown during bind!", e); 4036 4037 app.resetPackageList(); 4038 app.unlinkDeathRecipient(); 4039 startProcessLocked(app, "bind fail", processName); 4040 return false; 4041 } 4042 4043 // Remove this record from the list of starting applications. 4044 mPersistentStartingProcesses.remove(app); 4045 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4046 "Attach application locked removing on hold: " + app); 4047 mProcessesOnHold.remove(app); 4048 4049 boolean badApp = false; 4050 boolean didSomething = false; 4051 4052 // See if the top visible activity is waiting to run in this process... 4053 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4054 if (hr != null && normalMode) { 4055 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4056 && processName.equals(hr.processName)) { 4057 try { 4058 if (mHeadless) { 4059 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4060 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4061 didSomething = true; 4062 } 4063 } catch (Exception e) { 4064 Slog.w(TAG, "Exception in new application when starting activity " 4065 + hr.intent.getComponent().flattenToShortString(), e); 4066 badApp = true; 4067 } 4068 } else { 4069 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4070 } 4071 } 4072 4073 // Find any services that should be running in this process... 4074 if (!badApp) { 4075 try { 4076 didSomething |= mServices.attachApplicationLocked(app, processName); 4077 } catch (Exception e) { 4078 badApp = true; 4079 } 4080 } 4081 4082 // Check if a next-broadcast receiver is in this process... 4083 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4084 try { 4085 didSomething = sendPendingBroadcastsLocked(app); 4086 } catch (Exception e) { 4087 // If the app died trying to launch the receiver we declare it 'bad' 4088 badApp = true; 4089 } 4090 } 4091 4092 // Check whether the next backup agent is in this process... 4093 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4094 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4095 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4096 try { 4097 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4098 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4099 mBackupTarget.backupMode); 4100 } catch (Exception e) { 4101 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4102 e.printStackTrace(); 4103 } 4104 } 4105 4106 if (badApp) { 4107 // todo: Also need to kill application to deal with all 4108 // kinds of exceptions. 4109 handleAppDiedLocked(app, false, true); 4110 return false; 4111 } 4112 4113 if (!didSomething) { 4114 updateOomAdjLocked(); 4115 } 4116 4117 return true; 4118 } 4119 4120 public final void attachApplication(IApplicationThread thread) { 4121 synchronized (this) { 4122 int callingPid = Binder.getCallingPid(); 4123 final long origId = Binder.clearCallingIdentity(); 4124 attachApplicationLocked(thread, callingPid); 4125 Binder.restoreCallingIdentity(origId); 4126 } 4127 } 4128 4129 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4130 final long origId = Binder.clearCallingIdentity(); 4131 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4132 if (stopProfiling) { 4133 synchronized (this) { 4134 if (mProfileProc == r.app) { 4135 if (mProfileFd != null) { 4136 try { 4137 mProfileFd.close(); 4138 } catch (IOException e) { 4139 } 4140 clearProfilerLocked(); 4141 } 4142 } 4143 } 4144 } 4145 Binder.restoreCallingIdentity(origId); 4146 } 4147 4148 void enableScreenAfterBoot() { 4149 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4150 SystemClock.uptimeMillis()); 4151 mWindowManager.enableScreenAfterBoot(); 4152 4153 synchronized (this) { 4154 updateEventDispatchingLocked(); 4155 } 4156 } 4157 4158 public void showBootMessage(final CharSequence msg, final boolean always) { 4159 enforceNotIsolatedCaller("showBootMessage"); 4160 mWindowManager.showBootMessage(msg, always); 4161 } 4162 4163 public void dismissKeyguardOnNextActivity() { 4164 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4165 final long token = Binder.clearCallingIdentity(); 4166 try { 4167 synchronized (this) { 4168 if (mLockScreenShown) { 4169 mLockScreenShown = false; 4170 comeOutOfSleepIfNeededLocked(); 4171 } 4172 mMainStack.dismissKeyguardOnNextActivityLocked(); 4173 } 4174 } finally { 4175 Binder.restoreCallingIdentity(token); 4176 } 4177 } 4178 4179 final void finishBooting() { 4180 IntentFilter pkgFilter = new IntentFilter(); 4181 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4182 pkgFilter.addDataScheme("package"); 4183 mContext.registerReceiver(new BroadcastReceiver() { 4184 @Override 4185 public void onReceive(Context context, Intent intent) { 4186 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4187 if (pkgs != null) { 4188 for (String pkg : pkgs) { 4189 synchronized (ActivityManagerService.this) { 4190 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4191 setResultCode(Activity.RESULT_OK); 4192 return; 4193 } 4194 } 4195 } 4196 } 4197 } 4198 }, pkgFilter); 4199 4200 IntentFilter userFilter = new IntentFilter(); 4201 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4202 mContext.registerReceiver(new BroadcastReceiver() { 4203 @Override 4204 public void onReceive(Context context, Intent intent) { 4205 onUserRemoved(intent); 4206 } 4207 }, userFilter); 4208 4209 synchronized (this) { 4210 // Ensure that any processes we had put on hold are now started 4211 // up. 4212 final int NP = mProcessesOnHold.size(); 4213 if (NP > 0) { 4214 ArrayList<ProcessRecord> procs = 4215 new ArrayList<ProcessRecord>(mProcessesOnHold); 4216 for (int ip=0; ip<NP; ip++) { 4217 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4218 + procs.get(ip)); 4219 startProcessLocked(procs.get(ip), "on-hold", null); 4220 } 4221 } 4222 4223 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4224 // Start looking for apps that are abusing wake locks. 4225 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4226 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4227 // Tell anyone interested that we are done booting! 4228 SystemProperties.set("sys.boot_completed", "1"); 4229 SystemProperties.set("dev.bootcomplete", "1"); 4230 List<UserInfo> users = getUserManager().getUsers(); 4231 for (UserInfo user : users) { 4232 broadcastIntentLocked(null, null, 4233 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4234 null, null, 0, null, null, 4235 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4236 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4237 } 4238 } 4239 } 4240 } 4241 4242 final void ensureBootCompleted() { 4243 boolean booting; 4244 boolean enableScreen; 4245 synchronized (this) { 4246 booting = mBooting; 4247 mBooting = false; 4248 enableScreen = !mBooted; 4249 mBooted = true; 4250 } 4251 4252 if (booting) { 4253 finishBooting(); 4254 } 4255 4256 if (enableScreen) { 4257 enableScreenAfterBoot(); 4258 } 4259 } 4260 4261 public final void activityPaused(IBinder token) { 4262 final long origId = Binder.clearCallingIdentity(); 4263 mMainStack.activityPaused(token, false); 4264 Binder.restoreCallingIdentity(origId); 4265 } 4266 4267 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4268 CharSequence description) { 4269 if (localLOGV) Slog.v( 4270 TAG, "Activity stopped: token=" + token); 4271 4272 // Refuse possible leaked file descriptors 4273 if (icicle != null && icicle.hasFileDescriptors()) { 4274 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4275 } 4276 4277 ActivityRecord r = null; 4278 4279 final long origId = Binder.clearCallingIdentity(); 4280 4281 synchronized (this) { 4282 r = mMainStack.isInStackLocked(token); 4283 if (r != null) { 4284 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4285 } 4286 } 4287 4288 if (r != null) { 4289 sendPendingThumbnail(r, null, null, null, false); 4290 } 4291 4292 trimApplications(); 4293 4294 Binder.restoreCallingIdentity(origId); 4295 } 4296 4297 public final void activityDestroyed(IBinder token) { 4298 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4299 mMainStack.activityDestroyed(token); 4300 } 4301 4302 public String getCallingPackage(IBinder token) { 4303 synchronized (this) { 4304 ActivityRecord r = getCallingRecordLocked(token); 4305 return r != null && r.app != null ? r.info.packageName : null; 4306 } 4307 } 4308 4309 public ComponentName getCallingActivity(IBinder token) { 4310 synchronized (this) { 4311 ActivityRecord r = getCallingRecordLocked(token); 4312 return r != null ? r.intent.getComponent() : null; 4313 } 4314 } 4315 4316 private ActivityRecord getCallingRecordLocked(IBinder token) { 4317 ActivityRecord r = mMainStack.isInStackLocked(token); 4318 if (r == null) { 4319 return null; 4320 } 4321 return r.resultTo; 4322 } 4323 4324 public ComponentName getActivityClassForToken(IBinder token) { 4325 synchronized(this) { 4326 ActivityRecord r = mMainStack.isInStackLocked(token); 4327 if (r == null) { 4328 return null; 4329 } 4330 return r.intent.getComponent(); 4331 } 4332 } 4333 4334 public String getPackageForToken(IBinder token) { 4335 synchronized(this) { 4336 ActivityRecord r = mMainStack.isInStackLocked(token); 4337 if (r == null) { 4338 return null; 4339 } 4340 return r.packageName; 4341 } 4342 } 4343 4344 public IIntentSender getIntentSender(int type, 4345 String packageName, IBinder token, String resultWho, 4346 int requestCode, Intent[] intents, String[] resolvedTypes, 4347 int flags, Bundle options) { 4348 enforceNotIsolatedCaller("getIntentSender"); 4349 // Refuse possible leaked file descriptors 4350 if (intents != null) { 4351 if (intents.length < 1) { 4352 throw new IllegalArgumentException("Intents array length must be >= 1"); 4353 } 4354 for (int i=0; i<intents.length; i++) { 4355 Intent intent = intents[i]; 4356 if (intent != null) { 4357 if (intent.hasFileDescriptors()) { 4358 throw new IllegalArgumentException("File descriptors passed in Intent"); 4359 } 4360 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4361 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4362 throw new IllegalArgumentException( 4363 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4364 } 4365 intents[i] = new Intent(intent); 4366 } 4367 } 4368 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4369 throw new IllegalArgumentException( 4370 "Intent array length does not match resolvedTypes length"); 4371 } 4372 } 4373 if (options != null) { 4374 if (options.hasFileDescriptors()) { 4375 throw new IllegalArgumentException("File descriptors passed in options"); 4376 } 4377 } 4378 4379 synchronized(this) { 4380 int callingUid = Binder.getCallingUid(); 4381 try { 4382 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4383 int uid = AppGlobals.getPackageManager() 4384 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4385 if (!UserHandle.isSameApp(callingUid, uid)) { 4386 String msg = "Permission Denial: getIntentSender() from pid=" 4387 + Binder.getCallingPid() 4388 + ", uid=" + Binder.getCallingUid() 4389 + ", (need uid=" + uid + ")" 4390 + " is not allowed to send as package " + packageName; 4391 Slog.w(TAG, msg); 4392 throw new SecurityException(msg); 4393 } 4394 } 4395 4396 if (DEBUG_MU) 4397 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4398 + Binder.getOrigCallingUid()); 4399 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4400 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4401 4402 } catch (RemoteException e) { 4403 throw new SecurityException(e); 4404 } 4405 } 4406 } 4407 4408 IIntentSender getIntentSenderLocked(int type, 4409 String packageName, int callingUid, IBinder token, String resultWho, 4410 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4411 Bundle options) { 4412 if (DEBUG_MU) 4413 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4414 ActivityRecord activity = null; 4415 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4416 activity = mMainStack.isInStackLocked(token); 4417 if (activity == null) { 4418 return null; 4419 } 4420 if (activity.finishing) { 4421 return null; 4422 } 4423 } 4424 4425 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4426 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4427 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4428 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4429 |PendingIntent.FLAG_UPDATE_CURRENT); 4430 4431 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4432 type, packageName, activity, resultWho, 4433 requestCode, intents, resolvedTypes, flags, options); 4434 WeakReference<PendingIntentRecord> ref; 4435 ref = mIntentSenderRecords.get(key); 4436 PendingIntentRecord rec = ref != null ? ref.get() : null; 4437 if (rec != null) { 4438 if (!cancelCurrent) { 4439 if (updateCurrent) { 4440 if (rec.key.requestIntent != null) { 4441 rec.key.requestIntent.replaceExtras(intents != null ? 4442 intents[intents.length - 1] : null); 4443 } 4444 if (intents != null) { 4445 intents[intents.length-1] = rec.key.requestIntent; 4446 rec.key.allIntents = intents; 4447 rec.key.allResolvedTypes = resolvedTypes; 4448 } else { 4449 rec.key.allIntents = null; 4450 rec.key.allResolvedTypes = null; 4451 } 4452 } 4453 return rec; 4454 } 4455 rec.canceled = true; 4456 mIntentSenderRecords.remove(key); 4457 } 4458 if (noCreate) { 4459 return rec; 4460 } 4461 rec = new PendingIntentRecord(this, key, callingUid); 4462 mIntentSenderRecords.put(key, rec.ref); 4463 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4464 if (activity.pendingResults == null) { 4465 activity.pendingResults 4466 = new HashSet<WeakReference<PendingIntentRecord>>(); 4467 } 4468 activity.pendingResults.add(rec.ref); 4469 } 4470 return rec; 4471 } 4472 4473 public void cancelIntentSender(IIntentSender sender) { 4474 if (!(sender instanceof PendingIntentRecord)) { 4475 return; 4476 } 4477 synchronized(this) { 4478 PendingIntentRecord rec = (PendingIntentRecord)sender; 4479 try { 4480 int uid = AppGlobals.getPackageManager() 4481 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4482 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4483 String msg = "Permission Denial: cancelIntentSender() from pid=" 4484 + Binder.getCallingPid() 4485 + ", uid=" + Binder.getCallingUid() 4486 + " is not allowed to cancel packges " 4487 + rec.key.packageName; 4488 Slog.w(TAG, msg); 4489 throw new SecurityException(msg); 4490 } 4491 } catch (RemoteException e) { 4492 throw new SecurityException(e); 4493 } 4494 cancelIntentSenderLocked(rec, true); 4495 } 4496 } 4497 4498 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4499 rec.canceled = true; 4500 mIntentSenderRecords.remove(rec.key); 4501 if (cleanActivity && rec.key.activity != null) { 4502 rec.key.activity.pendingResults.remove(rec.ref); 4503 } 4504 } 4505 4506 public String getPackageForIntentSender(IIntentSender pendingResult) { 4507 if (!(pendingResult instanceof PendingIntentRecord)) { 4508 return null; 4509 } 4510 try { 4511 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4512 return res.key.packageName; 4513 } catch (ClassCastException e) { 4514 } 4515 return null; 4516 } 4517 4518 public int getUidForIntentSender(IIntentSender sender) { 4519 if (sender instanceof PendingIntentRecord) { 4520 try { 4521 PendingIntentRecord res = (PendingIntentRecord)sender; 4522 return res.uid; 4523 } catch (ClassCastException e) { 4524 } 4525 } 4526 return -1; 4527 } 4528 4529 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4530 if (!(pendingResult instanceof PendingIntentRecord)) { 4531 return false; 4532 } 4533 try { 4534 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4535 if (res.key.allIntents == null) { 4536 return false; 4537 } 4538 for (int i=0; i<res.key.allIntents.length; i++) { 4539 Intent intent = res.key.allIntents[i]; 4540 if (intent.getPackage() != null && intent.getComponent() != null) { 4541 return false; 4542 } 4543 } 4544 return true; 4545 } catch (ClassCastException e) { 4546 } 4547 return false; 4548 } 4549 4550 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4551 if (!(pendingResult instanceof PendingIntentRecord)) { 4552 return false; 4553 } 4554 try { 4555 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4556 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4557 return true; 4558 } 4559 return false; 4560 } catch (ClassCastException e) { 4561 } 4562 return false; 4563 } 4564 4565 public void setProcessLimit(int max) { 4566 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4567 "setProcessLimit()"); 4568 synchronized (this) { 4569 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4570 mProcessLimitOverride = max; 4571 } 4572 trimApplications(); 4573 } 4574 4575 public int getProcessLimit() { 4576 synchronized (this) { 4577 return mProcessLimitOverride; 4578 } 4579 } 4580 4581 void foregroundTokenDied(ForegroundToken token) { 4582 synchronized (ActivityManagerService.this) { 4583 synchronized (mPidsSelfLocked) { 4584 ForegroundToken cur 4585 = mForegroundProcesses.get(token.pid); 4586 if (cur != token) { 4587 return; 4588 } 4589 mForegroundProcesses.remove(token.pid); 4590 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4591 if (pr == null) { 4592 return; 4593 } 4594 pr.forcingToForeground = null; 4595 pr.foregroundServices = false; 4596 } 4597 updateOomAdjLocked(); 4598 } 4599 } 4600 4601 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4602 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4603 "setProcessForeground()"); 4604 synchronized(this) { 4605 boolean changed = false; 4606 4607 synchronized (mPidsSelfLocked) { 4608 ProcessRecord pr = mPidsSelfLocked.get(pid); 4609 if (pr == null && isForeground) { 4610 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4611 return; 4612 } 4613 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4614 if (oldToken != null) { 4615 oldToken.token.unlinkToDeath(oldToken, 0); 4616 mForegroundProcesses.remove(pid); 4617 if (pr != null) { 4618 pr.forcingToForeground = null; 4619 } 4620 changed = true; 4621 } 4622 if (isForeground && token != null) { 4623 ForegroundToken newToken = new ForegroundToken() { 4624 public void binderDied() { 4625 foregroundTokenDied(this); 4626 } 4627 }; 4628 newToken.pid = pid; 4629 newToken.token = token; 4630 try { 4631 token.linkToDeath(newToken, 0); 4632 mForegroundProcesses.put(pid, newToken); 4633 pr.forcingToForeground = token; 4634 changed = true; 4635 } catch (RemoteException e) { 4636 // If the process died while doing this, we will later 4637 // do the cleanup with the process death link. 4638 } 4639 } 4640 } 4641 4642 if (changed) { 4643 updateOomAdjLocked(); 4644 } 4645 } 4646 } 4647 4648 // ========================================================= 4649 // PERMISSIONS 4650 // ========================================================= 4651 4652 static class PermissionController extends IPermissionController.Stub { 4653 ActivityManagerService mActivityManagerService; 4654 PermissionController(ActivityManagerService activityManagerService) { 4655 mActivityManagerService = activityManagerService; 4656 } 4657 4658 public boolean checkPermission(String permission, int pid, int uid) { 4659 return mActivityManagerService.checkPermission(permission, pid, 4660 uid) == PackageManager.PERMISSION_GRANTED; 4661 } 4662 } 4663 4664 /** 4665 * This can be called with or without the global lock held. 4666 */ 4667 int checkComponentPermission(String permission, int pid, int uid, 4668 int owningUid, boolean exported) { 4669 // We might be performing an operation on behalf of an indirect binder 4670 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4671 // client identity accordingly before proceeding. 4672 Identity tlsIdentity = sCallerIdentity.get(); 4673 if (tlsIdentity != null) { 4674 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4675 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4676 uid = tlsIdentity.uid; 4677 pid = tlsIdentity.pid; 4678 } 4679 4680 if (pid == MY_PID) { 4681 return PackageManager.PERMISSION_GRANTED; 4682 } 4683 4684 return ActivityManager.checkComponentPermission(permission, uid, 4685 owningUid, exported); 4686 } 4687 4688 /** 4689 * As the only public entry point for permissions checking, this method 4690 * can enforce the semantic that requesting a check on a null global 4691 * permission is automatically denied. (Internally a null permission 4692 * string is used when calling {@link #checkComponentPermission} in cases 4693 * when only uid-based security is needed.) 4694 * 4695 * This can be called with or without the global lock held. 4696 */ 4697 public int checkPermission(String permission, int pid, int uid) { 4698 if (permission == null) { 4699 return PackageManager.PERMISSION_DENIED; 4700 } 4701 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4702 } 4703 4704 /** 4705 * Binder IPC calls go through the public entry point. 4706 * This can be called with or without the global lock held. 4707 */ 4708 int checkCallingPermission(String permission) { 4709 return checkPermission(permission, 4710 Binder.getCallingPid(), 4711 UserHandle.getAppId(Binder.getCallingUid())); 4712 } 4713 4714 /** 4715 * This can be called with or without the global lock held. 4716 */ 4717 void enforceCallingPermission(String permission, String func) { 4718 if (checkCallingPermission(permission) 4719 == PackageManager.PERMISSION_GRANTED) { 4720 return; 4721 } 4722 4723 String msg = "Permission Denial: " + func + " from pid=" 4724 + Binder.getCallingPid() 4725 + ", uid=" + Binder.getCallingUid() 4726 + " requires " + permission; 4727 Slog.w(TAG, msg); 4728 throw new SecurityException(msg); 4729 } 4730 4731 /** 4732 * Determine if UID is holding permissions required to access {@link Uri} in 4733 * the given {@link ProviderInfo}. Final permission checking is always done 4734 * in {@link ContentProvider}. 4735 */ 4736 private final boolean checkHoldingPermissionsLocked( 4737 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4738 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4739 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4740 4741 if (pi.applicationInfo.uid == uid) { 4742 return true; 4743 } else if (!pi.exported) { 4744 return false; 4745 } 4746 4747 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4748 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4749 try { 4750 // check if target holds top-level <provider> permissions 4751 if (!readMet && pi.readPermission != null 4752 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4753 readMet = true; 4754 } 4755 if (!writeMet && pi.writePermission != null 4756 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4757 writeMet = true; 4758 } 4759 4760 // track if unprotected read/write is allowed; any denied 4761 // <path-permission> below removes this ability 4762 boolean allowDefaultRead = pi.readPermission == null; 4763 boolean allowDefaultWrite = pi.writePermission == null; 4764 4765 // check if target holds any <path-permission> that match uri 4766 final PathPermission[] pps = pi.pathPermissions; 4767 if (pps != null) { 4768 final String path = uri.getPath(); 4769 int i = pps.length; 4770 while (i > 0 && (!readMet || !writeMet)) { 4771 i--; 4772 PathPermission pp = pps[i]; 4773 if (pp.match(path)) { 4774 if (!readMet) { 4775 final String pprperm = pp.getReadPermission(); 4776 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4777 + pprperm + " for " + pp.getPath() 4778 + ": match=" + pp.match(path) 4779 + " check=" + pm.checkUidPermission(pprperm, uid)); 4780 if (pprperm != null) { 4781 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4782 readMet = true; 4783 } else { 4784 allowDefaultRead = false; 4785 } 4786 } 4787 } 4788 if (!writeMet) { 4789 final String ppwperm = pp.getWritePermission(); 4790 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4791 + ppwperm + " for " + pp.getPath() 4792 + ": match=" + pp.match(path) 4793 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4794 if (ppwperm != null) { 4795 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4796 writeMet = true; 4797 } else { 4798 allowDefaultWrite = false; 4799 } 4800 } 4801 } 4802 } 4803 } 4804 } 4805 4806 // grant unprotected <provider> read/write, if not blocked by 4807 // <path-permission> above 4808 if (allowDefaultRead) readMet = true; 4809 if (allowDefaultWrite) writeMet = true; 4810 4811 } catch (RemoteException e) { 4812 return false; 4813 } 4814 4815 return readMet && writeMet; 4816 } 4817 4818 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4819 int modeFlags) { 4820 // Root gets to do everything. 4821 if (uid == 0) { 4822 return true; 4823 } 4824 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4825 if (perms == null) return false; 4826 UriPermission perm = perms.get(uri); 4827 if (perm == null) return false; 4828 return (modeFlags&perm.modeFlags) == modeFlags; 4829 } 4830 4831 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4832 enforceNotIsolatedCaller("checkUriPermission"); 4833 4834 // Another redirected-binder-call permissions check as in 4835 // {@link checkComponentPermission}. 4836 Identity tlsIdentity = sCallerIdentity.get(); 4837 if (tlsIdentity != null) { 4838 uid = tlsIdentity.uid; 4839 pid = tlsIdentity.pid; 4840 } 4841 4842 uid = UserHandle.getAppId(uid); 4843 // Our own process gets to do everything. 4844 if (pid == MY_PID) { 4845 return PackageManager.PERMISSION_GRANTED; 4846 } 4847 synchronized(this) { 4848 return checkUriPermissionLocked(uri, uid, modeFlags) 4849 ? PackageManager.PERMISSION_GRANTED 4850 : PackageManager.PERMISSION_DENIED; 4851 } 4852 } 4853 4854 /** 4855 * Check if the targetPkg can be granted permission to access uri by 4856 * the callingUid using the given modeFlags. Throws a security exception 4857 * if callingUid is not allowed to do this. Returns the uid of the target 4858 * if the URI permission grant should be performed; returns -1 if it is not 4859 * needed (for example targetPkg already has permission to access the URI). 4860 * If you already know the uid of the target, you can supply it in 4861 * lastTargetUid else set that to -1. 4862 */ 4863 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4864 Uri uri, int modeFlags, int lastTargetUid) { 4865 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4866 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4867 if (modeFlags == 0) { 4868 return -1; 4869 } 4870 4871 if (targetPkg != null) { 4872 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4873 "Checking grant " + targetPkg + " permission to " + uri); 4874 } 4875 4876 final IPackageManager pm = AppGlobals.getPackageManager(); 4877 4878 // If this is not a content: uri, we can't do anything with it. 4879 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4880 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4881 "Can't grant URI permission for non-content URI: " + uri); 4882 return -1; 4883 } 4884 4885 String name = uri.getAuthority(); 4886 ProviderInfo pi = null; 4887 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4888 UserHandle.getUserId(callingUid)); 4889 if (cpr != null) { 4890 pi = cpr.info; 4891 } else { 4892 try { 4893 pi = pm.resolveContentProvider(name, 4894 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4895 } catch (RemoteException ex) { 4896 } 4897 } 4898 if (pi == null) { 4899 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4900 return -1; 4901 } 4902 4903 int targetUid = lastTargetUid; 4904 if (targetUid < 0 && targetPkg != null) { 4905 try { 4906 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4907 if (targetUid < 0) { 4908 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4909 "Can't grant URI permission no uid for: " + targetPkg); 4910 return -1; 4911 } 4912 } catch (RemoteException ex) { 4913 return -1; 4914 } 4915 } 4916 4917 if (targetUid >= 0) { 4918 // First... does the target actually need this permission? 4919 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4920 // No need to grant the target this permission. 4921 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4922 "Target " + targetPkg + " already has full permission to " + uri); 4923 return -1; 4924 } 4925 } else { 4926 // First... there is no target package, so can anyone access it? 4927 boolean allowed = pi.exported; 4928 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4929 if (pi.readPermission != null) { 4930 allowed = false; 4931 } 4932 } 4933 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4934 if (pi.writePermission != null) { 4935 allowed = false; 4936 } 4937 } 4938 if (allowed) { 4939 return -1; 4940 } 4941 } 4942 4943 // Second... is the provider allowing granting of URI permissions? 4944 if (!pi.grantUriPermissions) { 4945 throw new SecurityException("Provider " + pi.packageName 4946 + "/" + pi.name 4947 + " does not allow granting of Uri permissions (uri " 4948 + uri + ")"); 4949 } 4950 if (pi.uriPermissionPatterns != null) { 4951 final int N = pi.uriPermissionPatterns.length; 4952 boolean allowed = false; 4953 for (int i=0; i<N; i++) { 4954 if (pi.uriPermissionPatterns[i] != null 4955 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4956 allowed = true; 4957 break; 4958 } 4959 } 4960 if (!allowed) { 4961 throw new SecurityException("Provider " + pi.packageName 4962 + "/" + pi.name 4963 + " does not allow granting of permission to path of Uri " 4964 + uri); 4965 } 4966 } 4967 4968 // Third... does the caller itself have permission to access 4969 // this uri? 4970 if (callingUid != Process.myUid()) { 4971 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4972 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4973 throw new SecurityException("Uid " + callingUid 4974 + " does not have permission to uri " + uri); 4975 } 4976 } 4977 } 4978 4979 return targetUid; 4980 } 4981 4982 public int checkGrantUriPermission(int callingUid, String targetPkg, 4983 Uri uri, int modeFlags) { 4984 enforceNotIsolatedCaller("checkGrantUriPermission"); 4985 synchronized(this) { 4986 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4987 } 4988 } 4989 4990 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4991 Uri uri, int modeFlags, UriPermissionOwner owner) { 4992 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4993 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4994 if (modeFlags == 0) { 4995 return; 4996 } 4997 4998 // So here we are: the caller has the assumed permission 4999 // to the uri, and the target doesn't. Let's now give this to 5000 // the target. 5001 5002 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5003 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5004 5005 HashMap<Uri, UriPermission> targetUris 5006 = mGrantedUriPermissions.get(targetUid); 5007 if (targetUris == null) { 5008 targetUris = new HashMap<Uri, UriPermission>(); 5009 mGrantedUriPermissions.put(targetUid, targetUris); 5010 } 5011 5012 UriPermission perm = targetUris.get(uri); 5013 if (perm == null) { 5014 perm = new UriPermission(targetUid, uri); 5015 targetUris.put(uri, perm); 5016 } 5017 5018 perm.modeFlags |= modeFlags; 5019 if (owner == null) { 5020 perm.globalModeFlags |= modeFlags; 5021 } else { 5022 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5023 perm.readOwners.add(owner); 5024 owner.addReadPermission(perm); 5025 } 5026 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5027 perm.writeOwners.add(owner); 5028 owner.addWritePermission(perm); 5029 } 5030 } 5031 } 5032 5033 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5034 int modeFlags, UriPermissionOwner owner) { 5035 if (targetPkg == null) { 5036 throw new NullPointerException("targetPkg"); 5037 } 5038 5039 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5040 if (targetUid < 0) { 5041 return; 5042 } 5043 5044 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5045 } 5046 5047 static class NeededUriGrants extends ArrayList<Uri> { 5048 final String targetPkg; 5049 final int targetUid; 5050 final int flags; 5051 5052 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5053 targetPkg = _targetPkg; 5054 targetUid = _targetUid; 5055 flags = _flags; 5056 } 5057 } 5058 5059 /** 5060 * Like checkGrantUriPermissionLocked, but takes an Intent. 5061 */ 5062 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5063 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5065 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5066 + " clip=" + (intent != null ? intent.getClipData() : null) 5067 + " from " + intent + "; flags=0x" 5068 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5069 5070 if (targetPkg == null) { 5071 throw new NullPointerException("targetPkg"); 5072 } 5073 5074 if (intent == null) { 5075 return null; 5076 } 5077 Uri data = intent.getData(); 5078 ClipData clip = intent.getClipData(); 5079 if (data == null && clip == null) { 5080 return null; 5081 } 5082 if (data != null) { 5083 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5084 mode, needed != null ? needed.targetUid : -1); 5085 if (target > 0) { 5086 if (needed == null) { 5087 needed = new NeededUriGrants(targetPkg, target, mode); 5088 } 5089 needed.add(data); 5090 } 5091 } 5092 if (clip != null) { 5093 for (int i=0; i<clip.getItemCount(); i++) { 5094 Uri uri = clip.getItemAt(i).getUri(); 5095 if (uri != null) { 5096 int target = -1; 5097 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5098 mode, needed != null ? needed.targetUid : -1); 5099 if (target > 0) { 5100 if (needed == null) { 5101 needed = new NeededUriGrants(targetPkg, target, mode); 5102 } 5103 needed.add(uri); 5104 } 5105 } else { 5106 Intent clipIntent = clip.getItemAt(i).getIntent(); 5107 if (clipIntent != null) { 5108 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5109 callingUid, targetPkg, clipIntent, mode, needed); 5110 if (newNeeded != null) { 5111 needed = newNeeded; 5112 } 5113 } 5114 } 5115 } 5116 } 5117 5118 return needed; 5119 } 5120 5121 /** 5122 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5123 */ 5124 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5125 UriPermissionOwner owner) { 5126 if (needed != null) { 5127 for (int i=0; i<needed.size(); i++) { 5128 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5129 needed.get(i), needed.flags, owner); 5130 } 5131 } 5132 } 5133 5134 void grantUriPermissionFromIntentLocked(int callingUid, 5135 String targetPkg, Intent intent, UriPermissionOwner owner) { 5136 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5137 intent, intent != null ? intent.getFlags() : 0, null); 5138 if (needed == null) { 5139 return; 5140 } 5141 5142 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5143 } 5144 5145 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5146 Uri uri, int modeFlags) { 5147 enforceNotIsolatedCaller("grantUriPermission"); 5148 synchronized(this) { 5149 final ProcessRecord r = getRecordForAppLocked(caller); 5150 if (r == null) { 5151 throw new SecurityException("Unable to find app for caller " 5152 + caller 5153 + " when granting permission to uri " + uri); 5154 } 5155 if (targetPkg == null) { 5156 throw new IllegalArgumentException("null target"); 5157 } 5158 if (uri == null) { 5159 throw new IllegalArgumentException("null uri"); 5160 } 5161 5162 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5163 null); 5164 } 5165 } 5166 5167 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5168 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5169 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5170 HashMap<Uri, UriPermission> perms 5171 = mGrantedUriPermissions.get(perm.uid); 5172 if (perms != null) { 5173 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5174 "Removing " + perm.uid + " permission to " + perm.uri); 5175 perms.remove(perm.uri); 5176 if (perms.size() == 0) { 5177 mGrantedUriPermissions.remove(perm.uid); 5178 } 5179 } 5180 } 5181 } 5182 5183 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5184 int modeFlags) { 5185 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5186 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5187 if (modeFlags == 0) { 5188 return; 5189 } 5190 5191 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5192 "Revoking all granted permissions to " + uri); 5193 5194 final IPackageManager pm = AppGlobals.getPackageManager(); 5195 5196 final String authority = uri.getAuthority(); 5197 ProviderInfo pi = null; 5198 int userId = UserHandle.getUserId(callingUid); 5199 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5200 if (cpr != null) { 5201 pi = cpr.info; 5202 } else { 5203 try { 5204 pi = pm.resolveContentProvider(authority, 5205 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5206 } catch (RemoteException ex) { 5207 } 5208 } 5209 if (pi == null) { 5210 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5211 return; 5212 } 5213 5214 // Does the caller have this permission on the URI? 5215 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5216 // Right now, if you are not the original owner of the permission, 5217 // you are not allowed to revoke it. 5218 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5219 throw new SecurityException("Uid " + callingUid 5220 + " does not have permission to uri " + uri); 5221 //} 5222 } 5223 5224 // Go through all of the permissions and remove any that match. 5225 final List<String> SEGMENTS = uri.getPathSegments(); 5226 if (SEGMENTS != null) { 5227 final int NS = SEGMENTS.size(); 5228 int N = mGrantedUriPermissions.size(); 5229 for (int i=0; i<N; i++) { 5230 HashMap<Uri, UriPermission> perms 5231 = mGrantedUriPermissions.valueAt(i); 5232 Iterator<UriPermission> it = perms.values().iterator(); 5233 toploop: 5234 while (it.hasNext()) { 5235 UriPermission perm = it.next(); 5236 Uri targetUri = perm.uri; 5237 if (!authority.equals(targetUri.getAuthority())) { 5238 continue; 5239 } 5240 List<String> targetSegments = targetUri.getPathSegments(); 5241 if (targetSegments == null) { 5242 continue; 5243 } 5244 if (targetSegments.size() < NS) { 5245 continue; 5246 } 5247 for (int j=0; j<NS; j++) { 5248 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5249 continue toploop; 5250 } 5251 } 5252 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5253 "Revoking " + perm.uid + " permission to " + perm.uri); 5254 perm.clearModes(modeFlags); 5255 if (perm.modeFlags == 0) { 5256 it.remove(); 5257 } 5258 } 5259 if (perms.size() == 0) { 5260 mGrantedUriPermissions.remove( 5261 mGrantedUriPermissions.keyAt(i)); 5262 N--; 5263 i--; 5264 } 5265 } 5266 } 5267 } 5268 5269 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5270 int modeFlags) { 5271 enforceNotIsolatedCaller("revokeUriPermission"); 5272 synchronized(this) { 5273 final ProcessRecord r = getRecordForAppLocked(caller); 5274 if (r == null) { 5275 throw new SecurityException("Unable to find app for caller " 5276 + caller 5277 + " when revoking permission to uri " + uri); 5278 } 5279 if (uri == null) { 5280 Slog.w(TAG, "revokeUriPermission: null uri"); 5281 return; 5282 } 5283 5284 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5285 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5286 if (modeFlags == 0) { 5287 return; 5288 } 5289 5290 final IPackageManager pm = AppGlobals.getPackageManager(); 5291 5292 final String authority = uri.getAuthority(); 5293 ProviderInfo pi = null; 5294 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5295 if (cpr != null) { 5296 pi = cpr.info; 5297 } else { 5298 try { 5299 pi = pm.resolveContentProvider(authority, 5300 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5301 } catch (RemoteException ex) { 5302 } 5303 } 5304 if (pi == null) { 5305 Slog.w(TAG, "No content provider found for permission revoke: " 5306 + uri.toSafeString()); 5307 return; 5308 } 5309 5310 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5311 } 5312 } 5313 5314 @Override 5315 public IBinder newUriPermissionOwner(String name) { 5316 enforceNotIsolatedCaller("newUriPermissionOwner"); 5317 synchronized(this) { 5318 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5319 return owner.getExternalTokenLocked(); 5320 } 5321 } 5322 5323 @Override 5324 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5325 Uri uri, int modeFlags) { 5326 synchronized(this) { 5327 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5328 if (owner == null) { 5329 throw new IllegalArgumentException("Unknown owner: " + token); 5330 } 5331 if (fromUid != Binder.getCallingUid()) { 5332 if (Binder.getCallingUid() != Process.myUid()) { 5333 // Only system code can grant URI permissions on behalf 5334 // of other users. 5335 throw new SecurityException("nice try"); 5336 } 5337 } 5338 if (targetPkg == null) { 5339 throw new IllegalArgumentException("null target"); 5340 } 5341 if (uri == null) { 5342 throw new IllegalArgumentException("null uri"); 5343 } 5344 5345 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5346 } 5347 } 5348 5349 @Override 5350 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5351 synchronized(this) { 5352 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5353 if (owner == null) { 5354 throw new IllegalArgumentException("Unknown owner: " + token); 5355 } 5356 5357 if (uri == null) { 5358 owner.removeUriPermissionsLocked(mode); 5359 } else { 5360 owner.removeUriPermissionLocked(uri, mode); 5361 } 5362 } 5363 } 5364 5365 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5366 synchronized (this) { 5367 ProcessRecord app = 5368 who != null ? getRecordForAppLocked(who) : null; 5369 if (app == null) return; 5370 5371 Message msg = Message.obtain(); 5372 msg.what = WAIT_FOR_DEBUGGER_MSG; 5373 msg.obj = app; 5374 msg.arg1 = waiting ? 1 : 0; 5375 mHandler.sendMessage(msg); 5376 } 5377 } 5378 5379 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5380 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5381 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5382 outInfo.availMem = Process.getFreeMemory(); 5383 outInfo.totalMem = Process.getTotalMemory(); 5384 outInfo.threshold = homeAppMem; 5385 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5386 outInfo.hiddenAppThreshold = hiddenAppMem; 5387 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5388 ProcessList.SERVICE_ADJ); 5389 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5390 ProcessList.VISIBLE_APP_ADJ); 5391 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5392 ProcessList.FOREGROUND_APP_ADJ); 5393 } 5394 5395 // ========================================================= 5396 // TASK MANAGEMENT 5397 // ========================================================= 5398 5399 public List getTasks(int maxNum, int flags, 5400 IThumbnailReceiver receiver) { 5401 ArrayList list = new ArrayList(); 5402 5403 PendingThumbnailsRecord pending = null; 5404 IApplicationThread topThumbnail = null; 5405 ActivityRecord topRecord = null; 5406 5407 synchronized(this) { 5408 if (localLOGV) Slog.v( 5409 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5410 + ", receiver=" + receiver); 5411 5412 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5413 != PackageManager.PERMISSION_GRANTED) { 5414 if (receiver != null) { 5415 // If the caller wants to wait for pending thumbnails, 5416 // it ain't gonna get them. 5417 try { 5418 receiver.finished(); 5419 } catch (RemoteException ex) { 5420 } 5421 } 5422 String msg = "Permission Denial: getTasks() from pid=" 5423 + Binder.getCallingPid() 5424 + ", uid=" + Binder.getCallingUid() 5425 + " requires " + android.Manifest.permission.GET_TASKS; 5426 Slog.w(TAG, msg); 5427 throw new SecurityException(msg); 5428 } 5429 5430 int pos = mMainStack.mHistory.size()-1; 5431 ActivityRecord next = 5432 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5433 ActivityRecord top = null; 5434 TaskRecord curTask = null; 5435 int numActivities = 0; 5436 int numRunning = 0; 5437 while (pos >= 0 && maxNum > 0) { 5438 final ActivityRecord r = next; 5439 pos--; 5440 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5441 5442 // Initialize state for next task if needed. 5443 if (top == null || 5444 (top.state == ActivityState.INITIALIZING 5445 && top.task == r.task)) { 5446 top = r; 5447 curTask = r.task; 5448 numActivities = numRunning = 0; 5449 } 5450 5451 // Add 'r' into the current task. 5452 numActivities++; 5453 if (r.app != null && r.app.thread != null) { 5454 numRunning++; 5455 } 5456 5457 if (localLOGV) Slog.v( 5458 TAG, r.intent.getComponent().flattenToShortString() 5459 + ": task=" + r.task); 5460 5461 // If the next one is a different task, generate a new 5462 // TaskInfo entry for what we have. 5463 if (next == null || next.task != curTask) { 5464 ActivityManager.RunningTaskInfo ci 5465 = new ActivityManager.RunningTaskInfo(); 5466 ci.id = curTask.taskId; 5467 ci.baseActivity = r.intent.getComponent(); 5468 ci.topActivity = top.intent.getComponent(); 5469 if (top.thumbHolder != null) { 5470 ci.description = top.thumbHolder.lastDescription; 5471 } 5472 ci.numActivities = numActivities; 5473 ci.numRunning = numRunning; 5474 //System.out.println( 5475 // "#" + maxNum + ": " + " descr=" + ci.description); 5476 if (ci.thumbnail == null && receiver != null) { 5477 if (localLOGV) Slog.v( 5478 TAG, "State=" + top.state + "Idle=" + top.idle 5479 + " app=" + top.app 5480 + " thr=" + (top.app != null ? top.app.thread : null)); 5481 if (top.state == ActivityState.RESUMED 5482 || top.state == ActivityState.PAUSING) { 5483 if (top.idle && top.app != null 5484 && top.app.thread != null) { 5485 topRecord = top; 5486 topThumbnail = top.app.thread; 5487 } else { 5488 top.thumbnailNeeded = true; 5489 } 5490 } 5491 if (pending == null) { 5492 pending = new PendingThumbnailsRecord(receiver); 5493 } 5494 pending.pendingRecords.add(top); 5495 } 5496 list.add(ci); 5497 maxNum--; 5498 top = null; 5499 } 5500 } 5501 5502 if (pending != null) { 5503 mPendingThumbnails.add(pending); 5504 } 5505 } 5506 5507 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5508 5509 if (topThumbnail != null) { 5510 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5511 try { 5512 topThumbnail.requestThumbnail(topRecord.appToken); 5513 } catch (Exception e) { 5514 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5515 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5516 } 5517 } 5518 5519 if (pending == null && receiver != null) { 5520 // In this case all thumbnails were available and the client 5521 // is being asked to be told when the remaining ones come in... 5522 // which is unusually, since the top-most currently running 5523 // activity should never have a canned thumbnail! Oh well. 5524 try { 5525 receiver.finished(); 5526 } catch (RemoteException ex) { 5527 } 5528 } 5529 5530 return list; 5531 } 5532 5533 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5534 int flags, int userId) { 5535 final int callingUid = Binder.getCallingUid(); 5536 if (userId != UserHandle.getCallingUserId()) { 5537 // Check if the caller is holding permissions for cross-user requests. 5538 if (checkComponentPermission( 5539 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5540 Binder.getCallingPid(), callingUid, -1, true) 5541 != PackageManager.PERMISSION_GRANTED) { 5542 String msg = "Permission Denial: " 5543 + "Request to get recent tasks for user " + userId 5544 + " but is calling from user " + UserHandle.getUserId(callingUid) 5545 + "; this requires " 5546 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5547 Slog.w(TAG, msg); 5548 throw new SecurityException(msg); 5549 } else { 5550 if (userId == UserHandle.USER_CURRENT) { 5551 userId = mCurrentUserId; 5552 } 5553 } 5554 } 5555 5556 synchronized (this) { 5557 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5558 "getRecentTasks()"); 5559 final boolean detailed = checkCallingPermission( 5560 android.Manifest.permission.GET_DETAILED_TASKS) 5561 == PackageManager.PERMISSION_GRANTED; 5562 5563 IPackageManager pm = AppGlobals.getPackageManager(); 5564 5565 final int N = mRecentTasks.size(); 5566 ArrayList<ActivityManager.RecentTaskInfo> res 5567 = new ArrayList<ActivityManager.RecentTaskInfo>( 5568 maxNum < N ? maxNum : N); 5569 for (int i=0; i<N && maxNum > 0; i++) { 5570 TaskRecord tr = mRecentTasks.get(i); 5571 // Only add calling user's recent tasks 5572 if (tr.userId != userId) continue; 5573 // Return the entry if desired by the caller. We always return 5574 // the first entry, because callers always expect this to be the 5575 // foreground app. We may filter others if the caller has 5576 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5577 // we should exclude the entry. 5578 5579 if (i == 0 5580 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5581 || (tr.intent == null) 5582 || ((tr.intent.getFlags() 5583 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5584 ActivityManager.RecentTaskInfo rti 5585 = new ActivityManager.RecentTaskInfo(); 5586 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5587 rti.persistentId = tr.taskId; 5588 rti.baseIntent = new Intent( 5589 tr.intent != null ? tr.intent : tr.affinityIntent); 5590 if (!detailed) { 5591 rti.baseIntent.replaceExtras((Bundle)null); 5592 } 5593 rti.origActivity = tr.origActivity; 5594 rti.description = tr.lastDescription; 5595 5596 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5597 // Check whether this activity is currently available. 5598 try { 5599 if (rti.origActivity != null) { 5600 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5601 == null) { 5602 continue; 5603 } 5604 } else if (rti.baseIntent != null) { 5605 if (pm.queryIntentActivities(rti.baseIntent, 5606 null, 0, userId) == null) { 5607 continue; 5608 } 5609 } 5610 } catch (RemoteException e) { 5611 // Will never happen. 5612 } 5613 } 5614 5615 res.add(rti); 5616 maxNum--; 5617 } 5618 } 5619 return res; 5620 } 5621 } 5622 5623 private TaskRecord taskForIdLocked(int id) { 5624 final int N = mRecentTasks.size(); 5625 for (int i=0; i<N; i++) { 5626 TaskRecord tr = mRecentTasks.get(i); 5627 if (tr.taskId == id) { 5628 return tr; 5629 } 5630 } 5631 return null; 5632 } 5633 5634 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5635 synchronized (this) { 5636 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5637 "getTaskThumbnails()"); 5638 TaskRecord tr = taskForIdLocked(id); 5639 if (tr != null) { 5640 return mMainStack.getTaskThumbnailsLocked(tr); 5641 } 5642 } 5643 return null; 5644 } 5645 5646 public boolean removeSubTask(int taskId, int subTaskIndex) { 5647 synchronized (this) { 5648 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5649 "removeSubTask()"); 5650 long ident = Binder.clearCallingIdentity(); 5651 try { 5652 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5653 true) != null; 5654 } finally { 5655 Binder.restoreCallingIdentity(ident); 5656 } 5657 } 5658 } 5659 5660 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5661 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5662 Intent baseIntent = new Intent( 5663 tr.intent != null ? tr.intent : tr.affinityIntent); 5664 ComponentName component = baseIntent.getComponent(); 5665 if (component == null) { 5666 Slog.w(TAG, "Now component for base intent of task: " + tr); 5667 return; 5668 } 5669 5670 // Find any running services associated with this app. 5671 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5672 5673 if (killProcesses) { 5674 // Find any running processes associated with this app. 5675 final String pkg = component.getPackageName(); 5676 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5677 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5678 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5679 for (int i=0; i<uids.size(); i++) { 5680 ProcessRecord proc = uids.valueAt(i); 5681 if (proc.userId != tr.userId) { 5682 continue; 5683 } 5684 if (!proc.pkgList.contains(pkg)) { 5685 continue; 5686 } 5687 procs.add(proc); 5688 } 5689 } 5690 5691 // Kill the running processes. 5692 for (int i=0; i<procs.size(); i++) { 5693 ProcessRecord pr = procs.get(i); 5694 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5695 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5696 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5697 pr.processName, pr.setAdj, "remove task"); 5698 pr.killedBackground = true; 5699 Process.killProcessQuiet(pr.pid); 5700 } else { 5701 pr.waitingToKill = "remove task"; 5702 } 5703 } 5704 } 5705 } 5706 5707 public boolean removeTask(int taskId, int flags) { 5708 synchronized (this) { 5709 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5710 "removeTask()"); 5711 long ident = Binder.clearCallingIdentity(); 5712 try { 5713 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5714 false); 5715 if (r != null) { 5716 mRecentTasks.remove(r.task); 5717 cleanUpRemovedTaskLocked(r.task, flags); 5718 return true; 5719 } else { 5720 TaskRecord tr = null; 5721 int i=0; 5722 while (i < mRecentTasks.size()) { 5723 TaskRecord t = mRecentTasks.get(i); 5724 if (t.taskId == taskId) { 5725 tr = t; 5726 break; 5727 } 5728 i++; 5729 } 5730 if (tr != null) { 5731 if (tr.numActivities <= 0) { 5732 // Caller is just removing a recent task that is 5733 // not actively running. That is easy! 5734 mRecentTasks.remove(i); 5735 cleanUpRemovedTaskLocked(tr, flags); 5736 return true; 5737 } else { 5738 Slog.w(TAG, "removeTask: task " + taskId 5739 + " does not have activities to remove, " 5740 + " but numActivities=" + tr.numActivities 5741 + ": " + tr); 5742 } 5743 } 5744 } 5745 } finally { 5746 Binder.restoreCallingIdentity(ident); 5747 } 5748 } 5749 return false; 5750 } 5751 5752 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5753 int j; 5754 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5755 TaskRecord jt = startTask; 5756 5757 // First look backwards 5758 for (j=startIndex-1; j>=0; j--) { 5759 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5760 if (r.task != jt) { 5761 jt = r.task; 5762 if (affinity.equals(jt.affinity)) { 5763 return j; 5764 } 5765 } 5766 } 5767 5768 // Now look forwards 5769 final int N = mMainStack.mHistory.size(); 5770 jt = startTask; 5771 for (j=startIndex+1; j<N; j++) { 5772 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5773 if (r.task != jt) { 5774 if (affinity.equals(jt.affinity)) { 5775 return j; 5776 } 5777 jt = r.task; 5778 } 5779 } 5780 5781 // Might it be at the top? 5782 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5783 return N-1; 5784 } 5785 5786 return -1; 5787 } 5788 5789 /** 5790 * TODO: Add mController hook 5791 */ 5792 public void moveTaskToFront(int task, int flags, Bundle options) { 5793 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5794 "moveTaskToFront()"); 5795 5796 synchronized(this) { 5797 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5798 Binder.getCallingUid(), "Task to front")) { 5799 ActivityOptions.abort(options); 5800 return; 5801 } 5802 final long origId = Binder.clearCallingIdentity(); 5803 try { 5804 TaskRecord tr = taskForIdLocked(task); 5805 if (tr != null) { 5806 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5807 mMainStack.mUserLeaving = true; 5808 } 5809 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5810 // Caller wants the home activity moved with it. To accomplish this, 5811 // we'll just move the home task to the top first. 5812 mMainStack.moveHomeToFrontLocked(); 5813 } 5814 mMainStack.moveTaskToFrontLocked(tr, null, options); 5815 return; 5816 } 5817 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5818 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5819 if (hr.task.taskId == task) { 5820 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5821 mMainStack.mUserLeaving = true; 5822 } 5823 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5824 // Caller wants the home activity moved with it. To accomplish this, 5825 // we'll just move the home task to the top first. 5826 mMainStack.moveHomeToFrontLocked(); 5827 } 5828 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5829 return; 5830 } 5831 } 5832 } finally { 5833 Binder.restoreCallingIdentity(origId); 5834 } 5835 ActivityOptions.abort(options); 5836 } 5837 } 5838 5839 public void moveTaskToBack(int task) { 5840 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5841 "moveTaskToBack()"); 5842 5843 synchronized(this) { 5844 if (mMainStack.mResumedActivity != null 5845 && mMainStack.mResumedActivity.task.taskId == task) { 5846 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5847 Binder.getCallingUid(), "Task to back")) { 5848 return; 5849 } 5850 } 5851 final long origId = Binder.clearCallingIdentity(); 5852 mMainStack.moveTaskToBackLocked(task, null); 5853 Binder.restoreCallingIdentity(origId); 5854 } 5855 } 5856 5857 /** 5858 * Moves an activity, and all of the other activities within the same task, to the bottom 5859 * of the history stack. The activity's order within the task is unchanged. 5860 * 5861 * @param token A reference to the activity we wish to move 5862 * @param nonRoot If false then this only works if the activity is the root 5863 * of a task; if true it will work for any activity in a task. 5864 * @return Returns true if the move completed, false if not. 5865 */ 5866 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5867 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5868 synchronized(this) { 5869 final long origId = Binder.clearCallingIdentity(); 5870 int taskId = getTaskForActivityLocked(token, !nonRoot); 5871 if (taskId >= 0) { 5872 return mMainStack.moveTaskToBackLocked(taskId, null); 5873 } 5874 Binder.restoreCallingIdentity(origId); 5875 } 5876 return false; 5877 } 5878 5879 public void moveTaskBackwards(int task) { 5880 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5881 "moveTaskBackwards()"); 5882 5883 synchronized(this) { 5884 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5885 Binder.getCallingUid(), "Task backwards")) { 5886 return; 5887 } 5888 final long origId = Binder.clearCallingIdentity(); 5889 moveTaskBackwardsLocked(task); 5890 Binder.restoreCallingIdentity(origId); 5891 } 5892 } 5893 5894 private final void moveTaskBackwardsLocked(int task) { 5895 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5896 } 5897 5898 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5899 synchronized(this) { 5900 return getTaskForActivityLocked(token, onlyRoot); 5901 } 5902 } 5903 5904 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5905 final int N = mMainStack.mHistory.size(); 5906 TaskRecord lastTask = null; 5907 for (int i=0; i<N; i++) { 5908 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5909 if (r.appToken == token) { 5910 if (!onlyRoot || lastTask != r.task) { 5911 return r.task.taskId; 5912 } 5913 return -1; 5914 } 5915 lastTask = r.task; 5916 } 5917 5918 return -1; 5919 } 5920 5921 // ========================================================= 5922 // THUMBNAILS 5923 // ========================================================= 5924 5925 public void reportThumbnail(IBinder token, 5926 Bitmap thumbnail, CharSequence description) { 5927 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5928 final long origId = Binder.clearCallingIdentity(); 5929 sendPendingThumbnail(null, token, thumbnail, description, true); 5930 Binder.restoreCallingIdentity(origId); 5931 } 5932 5933 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5934 Bitmap thumbnail, CharSequence description, boolean always) { 5935 TaskRecord task = null; 5936 ArrayList receivers = null; 5937 5938 //System.out.println("Send pending thumbnail: " + r); 5939 5940 synchronized(this) { 5941 if (r == null) { 5942 r = mMainStack.isInStackLocked(token); 5943 if (r == null) { 5944 return; 5945 } 5946 } 5947 if (thumbnail == null && r.thumbHolder != null) { 5948 thumbnail = r.thumbHolder.lastThumbnail; 5949 description = r.thumbHolder.lastDescription; 5950 } 5951 if (thumbnail == null && !always) { 5952 // If there is no thumbnail, and this entry is not actually 5953 // going away, then abort for now and pick up the next 5954 // thumbnail we get. 5955 return; 5956 } 5957 task = r.task; 5958 5959 int N = mPendingThumbnails.size(); 5960 int i=0; 5961 while (i<N) { 5962 PendingThumbnailsRecord pr = 5963 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5964 //System.out.println("Looking in " + pr.pendingRecords); 5965 if (pr.pendingRecords.remove(r)) { 5966 if (receivers == null) { 5967 receivers = new ArrayList(); 5968 } 5969 receivers.add(pr); 5970 if (pr.pendingRecords.size() == 0) { 5971 pr.finished = true; 5972 mPendingThumbnails.remove(i); 5973 N--; 5974 continue; 5975 } 5976 } 5977 i++; 5978 } 5979 } 5980 5981 if (receivers != null) { 5982 final int N = receivers.size(); 5983 for (int i=0; i<N; i++) { 5984 try { 5985 PendingThumbnailsRecord pr = 5986 (PendingThumbnailsRecord)receivers.get(i); 5987 pr.receiver.newThumbnail( 5988 task != null ? task.taskId : -1, thumbnail, description); 5989 if (pr.finished) { 5990 pr.receiver.finished(); 5991 } 5992 } catch (Exception e) { 5993 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5994 } 5995 } 5996 } 5997 } 5998 5999 // ========================================================= 6000 // CONTENT PROVIDERS 6001 // ========================================================= 6002 6003 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6004 List<ProviderInfo> providers = null; 6005 try { 6006 providers = AppGlobals.getPackageManager(). 6007 queryContentProviders(app.processName, app.uid, 6008 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6009 } catch (RemoteException ex) { 6010 } 6011 if (DEBUG_MU) 6012 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6013 int userId = app.userId; 6014 if (providers != null) { 6015 int N = providers.size(); 6016 for (int i=0; i<N; i++) { 6017 ProviderInfo cpi = 6018 (ProviderInfo)providers.get(i); 6019 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6020 cpi.name, cpi.flags); 6021 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6022 // This is a singleton provider, but a user besides the 6023 // default user is asking to initialize a process it runs 6024 // in... well, no, it doesn't actually run in this process, 6025 // it runs in the process of the default user. Get rid of it. 6026 providers.remove(i); 6027 N--; 6028 continue; 6029 } 6030 6031 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6032 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6033 if (cpr == null) { 6034 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6035 mProviderMap.putProviderByClass(comp, cpr); 6036 } 6037 if (DEBUG_MU) 6038 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6039 app.pubProviders.put(cpi.name, cpr); 6040 app.addPackage(cpi.applicationInfo.packageName); 6041 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6042 } 6043 } 6044 return providers; 6045 } 6046 6047 /** 6048 * Check if {@link ProcessRecord} has a possible chance at accessing the 6049 * given {@link ProviderInfo}. Final permission checking is always done 6050 * in {@link ContentProvider}. 6051 */ 6052 private final String checkContentProviderPermissionLocked( 6053 ProviderInfo cpi, ProcessRecord r) { 6054 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6055 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6056 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6057 cpi.applicationInfo.uid, cpi.exported) 6058 == PackageManager.PERMISSION_GRANTED) { 6059 return null; 6060 } 6061 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6062 cpi.applicationInfo.uid, cpi.exported) 6063 == PackageManager.PERMISSION_GRANTED) { 6064 return null; 6065 } 6066 6067 PathPermission[] pps = cpi.pathPermissions; 6068 if (pps != null) { 6069 int i = pps.length; 6070 while (i > 0) { 6071 i--; 6072 PathPermission pp = pps[i]; 6073 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6074 cpi.applicationInfo.uid, cpi.exported) 6075 == PackageManager.PERMISSION_GRANTED) { 6076 return null; 6077 } 6078 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6079 cpi.applicationInfo.uid, cpi.exported) 6080 == PackageManager.PERMISSION_GRANTED) { 6081 return null; 6082 } 6083 } 6084 } 6085 6086 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6087 if (perms != null) { 6088 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6089 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6090 return null; 6091 } 6092 } 6093 } 6094 6095 String msg; 6096 if (!cpi.exported) { 6097 msg = "Permission Denial: opening provider " + cpi.name 6098 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6099 + ", uid=" + callingUid + ") that is not exported from uid " 6100 + cpi.applicationInfo.uid; 6101 } else { 6102 msg = "Permission Denial: opening provider " + cpi.name 6103 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6104 + ", uid=" + callingUid + ") requires " 6105 + cpi.readPermission + " or " + cpi.writePermission; 6106 } 6107 Slog.w(TAG, msg); 6108 return msg; 6109 } 6110 6111 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6112 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6113 if (r != null) { 6114 for (int i=0; i<r.conProviders.size(); i++) { 6115 ContentProviderConnection conn = r.conProviders.get(i); 6116 if (conn.provider == cpr) { 6117 if (DEBUG_PROVIDER) Slog.v(TAG, 6118 "Adding provider requested by " 6119 + r.processName + " from process " 6120 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6121 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6122 if (stable) { 6123 conn.stableCount++; 6124 conn.numStableIncs++; 6125 } else { 6126 conn.unstableCount++; 6127 conn.numUnstableIncs++; 6128 } 6129 return conn; 6130 } 6131 } 6132 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6133 if (stable) { 6134 conn.stableCount = 1; 6135 conn.numStableIncs = 1; 6136 } else { 6137 conn.unstableCount = 1; 6138 conn.numUnstableIncs = 1; 6139 } 6140 cpr.connections.add(conn); 6141 r.conProviders.add(conn); 6142 return conn; 6143 } 6144 cpr.addExternalProcessHandleLocked(externalProcessToken); 6145 return null; 6146 } 6147 6148 boolean decProviderCountLocked(ContentProviderConnection conn, 6149 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6150 if (conn != null) { 6151 cpr = conn.provider; 6152 if (DEBUG_PROVIDER) Slog.v(TAG, 6153 "Removing provider requested by " 6154 + conn.client.processName + " from process " 6155 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6156 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6157 if (stable) { 6158 conn.stableCount--; 6159 } else { 6160 conn.unstableCount--; 6161 } 6162 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6163 cpr.connections.remove(conn); 6164 conn.client.conProviders.remove(conn); 6165 return true; 6166 } 6167 return false; 6168 } 6169 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6170 return false; 6171 } 6172 6173 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6174 String name, IBinder token, boolean stable) { 6175 ContentProviderRecord cpr; 6176 ContentProviderConnection conn = null; 6177 ProviderInfo cpi = null; 6178 6179 synchronized(this) { 6180 ProcessRecord r = null; 6181 if (caller != null) { 6182 r = getRecordForAppLocked(caller); 6183 if (r == null) { 6184 throw new SecurityException( 6185 "Unable to find app for caller " + caller 6186 + " (pid=" + Binder.getCallingPid() 6187 + ") when getting content provider " + name); 6188 } 6189 } 6190 6191 // First check if this content provider has been published... 6192 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6193 cpr = mProviderMap.getProviderByName(name, userId); 6194 boolean providerRunning = cpr != null; 6195 if (providerRunning) { 6196 cpi = cpr.info; 6197 String msg; 6198 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6199 throw new SecurityException(msg); 6200 } 6201 6202 if (r != null && cpr.canRunHere(r)) { 6203 // This provider has been published or is in the process 6204 // of being published... but it is also allowed to run 6205 // in the caller's process, so don't make a connection 6206 // and just let the caller instantiate its own instance. 6207 ContentProviderHolder holder = cpr.newHolder(null); 6208 // don't give caller the provider object, it needs 6209 // to make its own. 6210 holder.provider = null; 6211 return holder; 6212 } 6213 6214 final long origId = Binder.clearCallingIdentity(); 6215 6216 // In this case the provider instance already exists, so we can 6217 // return it right away. 6218 conn = incProviderCountLocked(r, cpr, token, stable); 6219 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6220 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6221 // If this is a perceptible app accessing the provider, 6222 // make sure to count it as being accessed and thus 6223 // back up on the LRU list. This is good because 6224 // content providers are often expensive to start. 6225 updateLruProcessLocked(cpr.proc, false, true); 6226 } 6227 } 6228 6229 if (cpr.proc != null) { 6230 if (false) { 6231 if (cpr.name.flattenToShortString().equals( 6232 "com.android.providers.calendar/.CalendarProvider2")) { 6233 Slog.v(TAG, "****************** KILLING " 6234 + cpr.name.flattenToShortString()); 6235 Process.killProcess(cpr.proc.pid); 6236 } 6237 } 6238 boolean success = updateOomAdjLocked(cpr.proc); 6239 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6240 // NOTE: there is still a race here where a signal could be 6241 // pending on the process even though we managed to update its 6242 // adj level. Not sure what to do about this, but at least 6243 // the race is now smaller. 6244 if (!success) { 6245 // Uh oh... it looks like the provider's process 6246 // has been killed on us. We need to wait for a new 6247 // process to be started, and make sure its death 6248 // doesn't kill our process. 6249 Slog.i(TAG, 6250 "Existing provider " + cpr.name.flattenToShortString() 6251 + " is crashing; detaching " + r); 6252 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6253 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6254 if (!lastRef) { 6255 // This wasn't the last ref our process had on 6256 // the provider... we have now been killed, bail. 6257 return null; 6258 } 6259 providerRunning = false; 6260 conn = null; 6261 } 6262 } 6263 6264 Binder.restoreCallingIdentity(origId); 6265 } 6266 6267 boolean singleton; 6268 if (!providerRunning) { 6269 try { 6270 cpi = AppGlobals.getPackageManager(). 6271 resolveContentProvider(name, 6272 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6273 } catch (RemoteException ex) { 6274 } 6275 if (cpi == null) { 6276 return null; 6277 } 6278 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6279 cpi.name, cpi.flags); 6280 if (singleton) { 6281 userId = 0; 6282 } 6283 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6284 6285 String msg; 6286 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6287 throw new SecurityException(msg); 6288 } 6289 6290 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6291 && !cpi.processName.equals("system")) { 6292 // If this content provider does not run in the system 6293 // process, and the system is not yet ready to run other 6294 // processes, then fail fast instead of hanging. 6295 throw new IllegalArgumentException( 6296 "Attempt to launch content provider before system ready"); 6297 } 6298 6299 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6300 cpr = mProviderMap.getProviderByClass(comp, userId); 6301 final boolean firstClass = cpr == null; 6302 if (firstClass) { 6303 try { 6304 ApplicationInfo ai = 6305 AppGlobals.getPackageManager(). 6306 getApplicationInfo( 6307 cpi.applicationInfo.packageName, 6308 STOCK_PM_FLAGS, userId); 6309 if (ai == null) { 6310 Slog.w(TAG, "No package info for content provider " 6311 + cpi.name); 6312 return null; 6313 } 6314 ai = getAppInfoForUser(ai, userId); 6315 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6316 } catch (RemoteException ex) { 6317 // pm is in same process, this will never happen. 6318 } 6319 } 6320 6321 if (r != null && cpr.canRunHere(r)) { 6322 // If this is a multiprocess provider, then just return its 6323 // info and allow the caller to instantiate it. Only do 6324 // this if the provider is the same user as the caller's 6325 // process, or can run as root (so can be in any process). 6326 return cpr.newHolder(null); 6327 } 6328 6329 if (DEBUG_PROVIDER) { 6330 RuntimeException e = new RuntimeException("here"); 6331 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6332 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6333 } 6334 6335 // This is single process, and our app is now connecting to it. 6336 // See if we are already in the process of launching this 6337 // provider. 6338 final int N = mLaunchingProviders.size(); 6339 int i; 6340 for (i=0; i<N; i++) { 6341 if (mLaunchingProviders.get(i) == cpr) { 6342 break; 6343 } 6344 } 6345 6346 // If the provider is not already being launched, then get it 6347 // started. 6348 if (i >= N) { 6349 final long origId = Binder.clearCallingIdentity(); 6350 6351 try { 6352 // Content provider is now in use, its package can't be stopped. 6353 try { 6354 AppGlobals.getPackageManager().setPackageStoppedState( 6355 cpr.appInfo.packageName, false, userId); 6356 } catch (RemoteException e) { 6357 } catch (IllegalArgumentException e) { 6358 Slog.w(TAG, "Failed trying to unstop package " 6359 + cpr.appInfo.packageName + ": " + e); 6360 } 6361 6362 ProcessRecord proc = startProcessLocked(cpi.processName, 6363 cpr.appInfo, false, 0, "content provider", 6364 new ComponentName(cpi.applicationInfo.packageName, 6365 cpi.name), false, false); 6366 if (proc == null) { 6367 Slog.w(TAG, "Unable to launch app " 6368 + cpi.applicationInfo.packageName + "/" 6369 + cpi.applicationInfo.uid + " for provider " 6370 + name + ": process is bad"); 6371 return null; 6372 } 6373 cpr.launchingApp = proc; 6374 mLaunchingProviders.add(cpr); 6375 } finally { 6376 Binder.restoreCallingIdentity(origId); 6377 } 6378 } 6379 6380 // Make sure the provider is published (the same provider class 6381 // may be published under multiple names). 6382 if (firstClass) { 6383 mProviderMap.putProviderByClass(comp, cpr); 6384 } 6385 6386 mProviderMap.putProviderByName(name, cpr); 6387 conn = incProviderCountLocked(r, cpr, token, stable); 6388 if (conn != null) { 6389 conn.waiting = true; 6390 } 6391 } 6392 } 6393 6394 // Wait for the provider to be published... 6395 synchronized (cpr) { 6396 while (cpr.provider == null) { 6397 if (cpr.launchingApp == null) { 6398 Slog.w(TAG, "Unable to launch app " 6399 + cpi.applicationInfo.packageName + "/" 6400 + cpi.applicationInfo.uid + " for provider " 6401 + name + ": launching app became null"); 6402 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6403 cpi.applicationInfo.packageName, 6404 cpi.applicationInfo.uid, name); 6405 return null; 6406 } 6407 try { 6408 if (DEBUG_MU) { 6409 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6410 + cpr.launchingApp); 6411 } 6412 if (conn != null) { 6413 conn.waiting = true; 6414 } 6415 cpr.wait(); 6416 } catch (InterruptedException ex) { 6417 } finally { 6418 if (conn != null) { 6419 conn.waiting = false; 6420 } 6421 } 6422 } 6423 } 6424 return cpr != null ? cpr.newHolder(conn) : null; 6425 } 6426 6427 public final ContentProviderHolder getContentProvider( 6428 IApplicationThread caller, String name, boolean stable) { 6429 enforceNotIsolatedCaller("getContentProvider"); 6430 if (caller == null) { 6431 String msg = "null IApplicationThread when getting content provider " 6432 + name; 6433 Slog.w(TAG, msg); 6434 throw new SecurityException(msg); 6435 } 6436 6437 return getContentProviderImpl(caller, name, null, stable); 6438 } 6439 6440 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6441 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6442 "Do not have permission in call getContentProviderExternal()"); 6443 return getContentProviderExternalUnchecked(name, token); 6444 } 6445 6446 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6447 return getContentProviderImpl(null, name, token, true); 6448 } 6449 6450 /** 6451 * Drop a content provider from a ProcessRecord's bookkeeping 6452 * @param cpr 6453 */ 6454 public void removeContentProvider(IBinder connection, boolean stable) { 6455 enforceNotIsolatedCaller("removeContentProvider"); 6456 synchronized (this) { 6457 ContentProviderConnection conn; 6458 try { 6459 conn = (ContentProviderConnection)connection; 6460 } catch (ClassCastException e) { 6461 String msg ="removeContentProvider: " + connection 6462 + " not a ContentProviderConnection"; 6463 Slog.w(TAG, msg); 6464 throw new IllegalArgumentException(msg); 6465 } 6466 if (conn == null) { 6467 throw new NullPointerException("connection is null"); 6468 } 6469 if (decProviderCountLocked(conn, null, null, stable)) { 6470 updateOomAdjLocked(); 6471 } 6472 } 6473 } 6474 6475 public void removeContentProviderExternal(String name, IBinder token) { 6476 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6477 "Do not have permission in call removeContentProviderExternal()"); 6478 removeContentProviderExternalUnchecked(name, token); 6479 } 6480 6481 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6482 synchronized (this) { 6483 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6484 Binder.getOrigCallingUser()); 6485 if(cpr == null) { 6486 //remove from mProvidersByClass 6487 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6488 return; 6489 } 6490 6491 //update content provider record entry info 6492 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6493 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6494 Binder.getOrigCallingUser()); 6495 if (localCpr.hasExternalProcessHandles()) { 6496 if (localCpr.removeExternalProcessHandleLocked(token)) { 6497 updateOomAdjLocked(); 6498 } else { 6499 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6500 + " with no external reference for token: " 6501 + token + "."); 6502 } 6503 } else { 6504 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6505 + " with no external references."); 6506 } 6507 } 6508 } 6509 6510 public final void publishContentProviders(IApplicationThread caller, 6511 List<ContentProviderHolder> providers) { 6512 if (providers == null) { 6513 return; 6514 } 6515 6516 enforceNotIsolatedCaller("publishContentProviders"); 6517 synchronized (this) { 6518 final ProcessRecord r = getRecordForAppLocked(caller); 6519 if (DEBUG_MU) 6520 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6521 if (r == null) { 6522 throw new SecurityException( 6523 "Unable to find app for caller " + caller 6524 + " (pid=" + Binder.getCallingPid() 6525 + ") when publishing content providers"); 6526 } 6527 6528 final long origId = Binder.clearCallingIdentity(); 6529 6530 final int N = providers.size(); 6531 for (int i=0; i<N; i++) { 6532 ContentProviderHolder src = providers.get(i); 6533 if (src == null || src.info == null || src.provider == null) { 6534 continue; 6535 } 6536 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6537 if (DEBUG_MU) 6538 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6539 if (dst != null) { 6540 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6541 mProviderMap.putProviderByClass(comp, dst); 6542 String names[] = dst.info.authority.split(";"); 6543 for (int j = 0; j < names.length; j++) { 6544 mProviderMap.putProviderByName(names[j], dst); 6545 } 6546 6547 int NL = mLaunchingProviders.size(); 6548 int j; 6549 for (j=0; j<NL; j++) { 6550 if (mLaunchingProviders.get(j) == dst) { 6551 mLaunchingProviders.remove(j); 6552 j--; 6553 NL--; 6554 } 6555 } 6556 synchronized (dst) { 6557 dst.provider = src.provider; 6558 dst.proc = r; 6559 dst.notifyAll(); 6560 } 6561 updateOomAdjLocked(r); 6562 } 6563 } 6564 6565 Binder.restoreCallingIdentity(origId); 6566 } 6567 } 6568 6569 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6570 ContentProviderConnection conn; 6571 try { 6572 conn = (ContentProviderConnection)connection; 6573 } catch (ClassCastException e) { 6574 String msg ="refContentProvider: " + connection 6575 + " not a ContentProviderConnection"; 6576 Slog.w(TAG, msg); 6577 throw new IllegalArgumentException(msg); 6578 } 6579 if (conn == null) { 6580 throw new NullPointerException("connection is null"); 6581 } 6582 6583 synchronized (this) { 6584 if (stable > 0) { 6585 conn.numStableIncs += stable; 6586 } 6587 stable = conn.stableCount + stable; 6588 if (stable < 0) { 6589 throw new IllegalStateException("stableCount < 0: " + stable); 6590 } 6591 6592 if (unstable > 0) { 6593 conn.numUnstableIncs += unstable; 6594 } 6595 unstable = conn.unstableCount + unstable; 6596 if (unstable < 0) { 6597 throw new IllegalStateException("unstableCount < 0: " + unstable); 6598 } 6599 6600 if ((stable+unstable) <= 0) { 6601 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6602 + stable + " unstable=" + unstable); 6603 } 6604 conn.stableCount = stable; 6605 conn.unstableCount = unstable; 6606 return !conn.dead; 6607 } 6608 } 6609 6610 public void unstableProviderDied(IBinder connection) { 6611 ContentProviderConnection conn; 6612 try { 6613 conn = (ContentProviderConnection)connection; 6614 } catch (ClassCastException e) { 6615 String msg ="refContentProvider: " + connection 6616 + " not a ContentProviderConnection"; 6617 Slog.w(TAG, msg); 6618 throw new IllegalArgumentException(msg); 6619 } 6620 if (conn == null) { 6621 throw new NullPointerException("connection is null"); 6622 } 6623 6624 // Safely retrieve the content provider associated with the connection. 6625 IContentProvider provider; 6626 synchronized (this) { 6627 provider = conn.provider.provider; 6628 } 6629 6630 if (provider == null) { 6631 // Um, yeah, we're way ahead of you. 6632 return; 6633 } 6634 6635 // Make sure the caller is being honest with us. 6636 if (provider.asBinder().pingBinder()) { 6637 // Er, no, still looks good to us. 6638 synchronized (this) { 6639 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6640 + " says " + conn + " died, but we don't agree"); 6641 return; 6642 } 6643 } 6644 6645 // Well look at that! It's dead! 6646 synchronized (this) { 6647 if (conn.provider.provider != provider) { 6648 // But something changed... good enough. 6649 return; 6650 } 6651 6652 ProcessRecord proc = conn.provider.proc; 6653 if (proc == null || proc.thread == null) { 6654 // Seems like the process is already cleaned up. 6655 return; 6656 } 6657 6658 // As far as we're concerned, this is just like receiving a 6659 // death notification... just a bit prematurely. 6660 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6661 + ") early provider death"); 6662 final long ident = Binder.clearCallingIdentity(); 6663 try { 6664 appDiedLocked(proc, proc.pid, proc.thread); 6665 } finally { 6666 Binder.restoreCallingIdentity(ident); 6667 } 6668 } 6669 } 6670 6671 public static final void installSystemProviders() { 6672 List<ProviderInfo> providers; 6673 synchronized (mSelf) { 6674 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6675 providers = mSelf.generateApplicationProvidersLocked(app); 6676 if (providers != null) { 6677 for (int i=providers.size()-1; i>=0; i--) { 6678 ProviderInfo pi = (ProviderInfo)providers.get(i); 6679 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6680 Slog.w(TAG, "Not installing system proc provider " + pi.name 6681 + ": not system .apk"); 6682 providers.remove(i); 6683 } 6684 } 6685 } 6686 } 6687 if (providers != null) { 6688 mSystemThread.installSystemProviders(providers); 6689 } 6690 6691 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6692 6693 mSelf.mUsageStatsService.monitorPackages(); 6694 } 6695 6696 /** 6697 * Allows app to retrieve the MIME type of a URI without having permission 6698 * to access its content provider. 6699 * 6700 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6701 * 6702 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6703 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6704 */ 6705 public String getProviderMimeType(Uri uri) { 6706 enforceNotIsolatedCaller("getProviderMimeType"); 6707 final String name = uri.getAuthority(); 6708 final long ident = Binder.clearCallingIdentity(); 6709 ContentProviderHolder holder = null; 6710 6711 try { 6712 holder = getContentProviderExternalUnchecked(name, null); 6713 if (holder != null) { 6714 return holder.provider.getType(uri); 6715 } 6716 } catch (RemoteException e) { 6717 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6718 return null; 6719 } finally { 6720 if (holder != null) { 6721 removeContentProviderExternalUnchecked(name, null); 6722 } 6723 Binder.restoreCallingIdentity(ident); 6724 } 6725 6726 return null; 6727 } 6728 6729 // ========================================================= 6730 // GLOBAL MANAGEMENT 6731 // ========================================================= 6732 6733 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6734 ApplicationInfo info, String customProcess, boolean isolated) { 6735 String proc = customProcess != null ? customProcess : info.processName; 6736 BatteryStatsImpl.Uid.Proc ps = null; 6737 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6738 int uid = info.uid; 6739 if (isolated) { 6740 int userId = UserHandle.getUserId(uid); 6741 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6742 uid = 0; 6743 while (true) { 6744 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6745 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6746 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6747 } 6748 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6749 mNextIsolatedProcessUid++; 6750 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6751 // No process for this uid, use it. 6752 break; 6753 } 6754 stepsLeft--; 6755 if (stepsLeft <= 0) { 6756 return null; 6757 } 6758 } 6759 } 6760 synchronized (stats) { 6761 ps = stats.getProcessStatsLocked(info.uid, proc); 6762 } 6763 return new ProcessRecord(ps, thread, info, proc, uid); 6764 } 6765 6766 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6767 ProcessRecord app; 6768 if (!isolated) { 6769 app = getProcessRecordLocked(info.processName, info.uid); 6770 } else { 6771 app = null; 6772 } 6773 6774 if (app == null) { 6775 app = newProcessRecordLocked(null, info, null, isolated); 6776 mProcessNames.put(info.processName, app.uid, app); 6777 if (isolated) { 6778 mIsolatedProcesses.put(app.uid, app); 6779 } 6780 updateLruProcessLocked(app, true, true); 6781 } 6782 6783 // This package really, really can not be stopped. 6784 try { 6785 AppGlobals.getPackageManager().setPackageStoppedState( 6786 info.packageName, false, UserHandle.getUserId(app.uid)); 6787 } catch (RemoteException e) { 6788 } catch (IllegalArgumentException e) { 6789 Slog.w(TAG, "Failed trying to unstop package " 6790 + info.packageName + ": " + e); 6791 } 6792 6793 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6794 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6795 app.persistent = true; 6796 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6797 } 6798 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6799 mPersistentStartingProcesses.add(app); 6800 startProcessLocked(app, "added application", app.processName); 6801 } 6802 6803 return app; 6804 } 6805 6806 public void unhandledBack() { 6807 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6808 "unhandledBack()"); 6809 6810 synchronized(this) { 6811 int count = mMainStack.mHistory.size(); 6812 if (DEBUG_SWITCH) Slog.d( 6813 TAG, "Performing unhandledBack(): stack size = " + count); 6814 if (count > 1) { 6815 final long origId = Binder.clearCallingIdentity(); 6816 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6817 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6818 Binder.restoreCallingIdentity(origId); 6819 } 6820 } 6821 } 6822 6823 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6824 enforceNotIsolatedCaller("openContentUri"); 6825 String name = uri.getAuthority(); 6826 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6827 ParcelFileDescriptor pfd = null; 6828 if (cph != null) { 6829 // We record the binder invoker's uid in thread-local storage before 6830 // going to the content provider to open the file. Later, in the code 6831 // that handles all permissions checks, we look for this uid and use 6832 // that rather than the Activity Manager's own uid. The effect is that 6833 // we do the check against the caller's permissions even though it looks 6834 // to the content provider like the Activity Manager itself is making 6835 // the request. 6836 sCallerIdentity.set(new Identity( 6837 Binder.getCallingPid(), Binder.getCallingUid())); 6838 try { 6839 pfd = cph.provider.openFile(uri, "r"); 6840 } catch (FileNotFoundException e) { 6841 // do nothing; pfd will be returned null 6842 } finally { 6843 // Ensure that whatever happens, we clean up the identity state 6844 sCallerIdentity.remove(); 6845 } 6846 6847 // We've got the fd now, so we're done with the provider. 6848 removeContentProviderExternalUnchecked(name, null); 6849 } else { 6850 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6851 } 6852 return pfd; 6853 } 6854 6855 // Actually is sleeping or shutting down or whatever else in the future 6856 // is an inactive state. 6857 public boolean isSleeping() { 6858 return mSleeping || mShuttingDown; 6859 } 6860 6861 public void goingToSleep() { 6862 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6863 != PackageManager.PERMISSION_GRANTED) { 6864 throw new SecurityException("Requires permission " 6865 + android.Manifest.permission.DEVICE_POWER); 6866 } 6867 6868 synchronized(this) { 6869 mWentToSleep = true; 6870 updateEventDispatchingLocked(); 6871 6872 if (!mSleeping) { 6873 mSleeping = true; 6874 mMainStack.stopIfSleepingLocked(); 6875 6876 // Initialize the wake times of all processes. 6877 checkExcessivePowerUsageLocked(false); 6878 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6879 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6880 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6881 } 6882 } 6883 } 6884 6885 public boolean shutdown(int timeout) { 6886 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6887 != PackageManager.PERMISSION_GRANTED) { 6888 throw new SecurityException("Requires permission " 6889 + android.Manifest.permission.SHUTDOWN); 6890 } 6891 6892 boolean timedout = false; 6893 6894 synchronized(this) { 6895 mShuttingDown = true; 6896 updateEventDispatchingLocked(); 6897 6898 if (mMainStack.mResumedActivity != null) { 6899 mMainStack.stopIfSleepingLocked(); 6900 final long endTime = System.currentTimeMillis() + timeout; 6901 while (mMainStack.mResumedActivity != null 6902 || mMainStack.mPausingActivity != null) { 6903 long delay = endTime - System.currentTimeMillis(); 6904 if (delay <= 0) { 6905 Slog.w(TAG, "Activity manager shutdown timed out"); 6906 timedout = true; 6907 break; 6908 } 6909 try { 6910 this.wait(); 6911 } catch (InterruptedException e) { 6912 } 6913 } 6914 } 6915 } 6916 6917 mUsageStatsService.shutdown(); 6918 mBatteryStatsService.shutdown(); 6919 6920 return timedout; 6921 } 6922 6923 public final void activitySlept(IBinder token) { 6924 if (localLOGV) Slog.v( 6925 TAG, "Activity slept: token=" + token); 6926 6927 ActivityRecord r = null; 6928 6929 final long origId = Binder.clearCallingIdentity(); 6930 6931 synchronized (this) { 6932 r = mMainStack.isInStackLocked(token); 6933 if (r != null) { 6934 mMainStack.activitySleptLocked(r); 6935 } 6936 } 6937 6938 Binder.restoreCallingIdentity(origId); 6939 } 6940 6941 private void comeOutOfSleepIfNeededLocked() { 6942 if (!mWentToSleep && !mLockScreenShown) { 6943 if (mSleeping) { 6944 mSleeping = false; 6945 mMainStack.awakeFromSleepingLocked(); 6946 mMainStack.resumeTopActivityLocked(null); 6947 } 6948 } 6949 } 6950 6951 public void wakingUp() { 6952 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6953 != PackageManager.PERMISSION_GRANTED) { 6954 throw new SecurityException("Requires permission " 6955 + android.Manifest.permission.DEVICE_POWER); 6956 } 6957 6958 synchronized(this) { 6959 mWentToSleep = false; 6960 updateEventDispatchingLocked(); 6961 comeOutOfSleepIfNeededLocked(); 6962 } 6963 } 6964 6965 private void updateEventDispatchingLocked() { 6966 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6967 } 6968 6969 public void setLockScreenShown(boolean shown) { 6970 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6971 != PackageManager.PERMISSION_GRANTED) { 6972 throw new SecurityException("Requires permission " 6973 + android.Manifest.permission.DEVICE_POWER); 6974 } 6975 6976 synchronized(this) { 6977 mLockScreenShown = shown; 6978 comeOutOfSleepIfNeededLocked(); 6979 } 6980 } 6981 6982 public void stopAppSwitches() { 6983 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6984 != PackageManager.PERMISSION_GRANTED) { 6985 throw new SecurityException("Requires permission " 6986 + android.Manifest.permission.STOP_APP_SWITCHES); 6987 } 6988 6989 synchronized(this) { 6990 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6991 + APP_SWITCH_DELAY_TIME; 6992 mDidAppSwitch = false; 6993 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6994 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6995 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6996 } 6997 } 6998 6999 public void resumeAppSwitches() { 7000 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7001 != PackageManager.PERMISSION_GRANTED) { 7002 throw new SecurityException("Requires permission " 7003 + android.Manifest.permission.STOP_APP_SWITCHES); 7004 } 7005 7006 synchronized(this) { 7007 // Note that we don't execute any pending app switches... we will 7008 // let those wait until either the timeout, or the next start 7009 // activity request. 7010 mAppSwitchesAllowedTime = 0; 7011 } 7012 } 7013 7014 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7015 String name) { 7016 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7017 return true; 7018 } 7019 7020 final int perm = checkComponentPermission( 7021 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7022 callingUid, -1, true); 7023 if (perm == PackageManager.PERMISSION_GRANTED) { 7024 return true; 7025 } 7026 7027 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7028 return false; 7029 } 7030 7031 public void setDebugApp(String packageName, boolean waitForDebugger, 7032 boolean persistent) { 7033 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7034 "setDebugApp()"); 7035 7036 // Note that this is not really thread safe if there are multiple 7037 // callers into it at the same time, but that's not a situation we 7038 // care about. 7039 if (persistent) { 7040 final ContentResolver resolver = mContext.getContentResolver(); 7041 Settings.System.putString( 7042 resolver, Settings.System.DEBUG_APP, 7043 packageName); 7044 Settings.System.putInt( 7045 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7046 waitForDebugger ? 1 : 0); 7047 } 7048 7049 synchronized (this) { 7050 if (!persistent) { 7051 mOrigDebugApp = mDebugApp; 7052 mOrigWaitForDebugger = mWaitForDebugger; 7053 } 7054 mDebugApp = packageName; 7055 mWaitForDebugger = waitForDebugger; 7056 mDebugTransient = !persistent; 7057 if (packageName != null) { 7058 final long origId = Binder.clearCallingIdentity(); 7059 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7060 Binder.restoreCallingIdentity(origId); 7061 } 7062 } 7063 } 7064 7065 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7066 synchronized (this) { 7067 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7068 if (!isDebuggable) { 7069 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7070 throw new SecurityException("Process not debuggable: " + app.packageName); 7071 } 7072 } 7073 7074 mOpenGlTraceApp = processName; 7075 } 7076 } 7077 7078 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7079 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7080 synchronized (this) { 7081 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7082 if (!isDebuggable) { 7083 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7084 throw new SecurityException("Process not debuggable: " + app.packageName); 7085 } 7086 } 7087 mProfileApp = processName; 7088 mProfileFile = profileFile; 7089 if (mProfileFd != null) { 7090 try { 7091 mProfileFd.close(); 7092 } catch (IOException e) { 7093 } 7094 mProfileFd = null; 7095 } 7096 mProfileFd = profileFd; 7097 mProfileType = 0; 7098 mAutoStopProfiler = autoStopProfiler; 7099 } 7100 } 7101 7102 public void setAlwaysFinish(boolean enabled) { 7103 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7104 "setAlwaysFinish()"); 7105 7106 Settings.System.putInt( 7107 mContext.getContentResolver(), 7108 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7109 7110 synchronized (this) { 7111 mAlwaysFinishActivities = enabled; 7112 } 7113 } 7114 7115 public void setActivityController(IActivityController controller) { 7116 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7117 "setActivityController()"); 7118 synchronized (this) { 7119 mController = controller; 7120 } 7121 } 7122 7123 public boolean isUserAMonkey() { 7124 // For now the fact that there is a controller implies 7125 // we have a monkey. 7126 synchronized (this) { 7127 return mController != null; 7128 } 7129 } 7130 7131 public void registerProcessObserver(IProcessObserver observer) { 7132 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7133 "registerProcessObserver()"); 7134 synchronized (this) { 7135 mProcessObservers.register(observer); 7136 } 7137 } 7138 7139 public void unregisterProcessObserver(IProcessObserver observer) { 7140 synchronized (this) { 7141 mProcessObservers.unregister(observer); 7142 } 7143 } 7144 7145 public void setImmersive(IBinder token, boolean immersive) { 7146 synchronized(this) { 7147 ActivityRecord r = mMainStack.isInStackLocked(token); 7148 if (r == null) { 7149 throw new IllegalArgumentException(); 7150 } 7151 r.immersive = immersive; 7152 } 7153 } 7154 7155 public boolean isImmersive(IBinder token) { 7156 synchronized (this) { 7157 ActivityRecord r = mMainStack.isInStackLocked(token); 7158 if (r == null) { 7159 throw new IllegalArgumentException(); 7160 } 7161 return r.immersive; 7162 } 7163 } 7164 7165 public boolean isTopActivityImmersive() { 7166 enforceNotIsolatedCaller("startActivity"); 7167 synchronized (this) { 7168 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7169 return (r != null) ? r.immersive : false; 7170 } 7171 } 7172 7173 public final void enterSafeMode() { 7174 synchronized(this) { 7175 // It only makes sense to do this before the system is ready 7176 // and started launching other packages. 7177 if (!mSystemReady) { 7178 try { 7179 AppGlobals.getPackageManager().enterSafeMode(); 7180 } catch (RemoteException e) { 7181 } 7182 } 7183 } 7184 } 7185 7186 public final void showSafeModeOverlay() { 7187 View v = LayoutInflater.from(mContext).inflate( 7188 com.android.internal.R.layout.safe_mode, null); 7189 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7190 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7191 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7192 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7193 lp.gravity = Gravity.BOTTOM | Gravity.START; 7194 lp.format = v.getBackground().getOpacity(); 7195 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7196 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7197 ((WindowManager)mContext.getSystemService( 7198 Context.WINDOW_SERVICE)).addView(v, lp); 7199 } 7200 7201 public void noteWakeupAlarm(IIntentSender sender) { 7202 if (!(sender instanceof PendingIntentRecord)) { 7203 return; 7204 } 7205 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7206 synchronized (stats) { 7207 if (mBatteryStatsService.isOnBattery()) { 7208 mBatteryStatsService.enforceCallingPermission(); 7209 PendingIntentRecord rec = (PendingIntentRecord)sender; 7210 int MY_UID = Binder.getCallingUid(); 7211 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7212 BatteryStatsImpl.Uid.Pkg pkg = 7213 stats.getPackageStatsLocked(uid, rec.key.packageName); 7214 pkg.incWakeupsLocked(); 7215 } 7216 } 7217 } 7218 7219 public boolean killPids(int[] pids, String pReason, boolean secure) { 7220 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7221 throw new SecurityException("killPids only available to the system"); 7222 } 7223 String reason = (pReason == null) ? "Unknown" : pReason; 7224 // XXX Note: don't acquire main activity lock here, because the window 7225 // manager calls in with its locks held. 7226 7227 boolean killed = false; 7228 synchronized (mPidsSelfLocked) { 7229 int[] types = new int[pids.length]; 7230 int worstType = 0; 7231 for (int i=0; i<pids.length; i++) { 7232 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7233 if (proc != null) { 7234 int type = proc.setAdj; 7235 types[i] = type; 7236 if (type > worstType) { 7237 worstType = type; 7238 } 7239 } 7240 } 7241 7242 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7243 // then constrain it so we will kill all hidden procs. 7244 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7245 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7246 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7247 } 7248 7249 // If this is not a secure call, don't let it kill processes that 7250 // are important. 7251 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7252 worstType = ProcessList.SERVICE_ADJ; 7253 } 7254 7255 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7256 for (int i=0; i<pids.length; i++) { 7257 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7258 if (proc == null) { 7259 continue; 7260 } 7261 int adj = proc.setAdj; 7262 if (adj >= worstType && !proc.killedBackground) { 7263 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7264 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7265 proc.processName, adj, reason); 7266 killed = true; 7267 proc.killedBackground = true; 7268 Process.killProcessQuiet(pids[i]); 7269 } 7270 } 7271 } 7272 return killed; 7273 } 7274 7275 @Override 7276 public boolean killProcessesBelowForeground(String reason) { 7277 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7278 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7279 } 7280 7281 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7282 } 7283 7284 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7285 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7286 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7287 } 7288 7289 boolean killed = false; 7290 synchronized (mPidsSelfLocked) { 7291 final int size = mPidsSelfLocked.size(); 7292 for (int i = 0; i < size; i++) { 7293 final int pid = mPidsSelfLocked.keyAt(i); 7294 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7295 if (proc == null) continue; 7296 7297 final int adj = proc.setAdj; 7298 if (adj > belowAdj && !proc.killedBackground) { 7299 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7300 EventLog.writeEvent( 7301 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7302 killed = true; 7303 proc.killedBackground = true; 7304 Process.killProcessQuiet(pid); 7305 } 7306 } 7307 } 7308 return killed; 7309 } 7310 7311 public final void startRunning(String pkg, String cls, String action, 7312 String data) { 7313 synchronized(this) { 7314 if (mStartRunning) { 7315 return; 7316 } 7317 mStartRunning = true; 7318 mTopComponent = pkg != null && cls != null 7319 ? new ComponentName(pkg, cls) : null; 7320 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7321 mTopData = data; 7322 if (!mSystemReady) { 7323 return; 7324 } 7325 } 7326 7327 systemReady(null); 7328 } 7329 7330 private void retrieveSettings() { 7331 final ContentResolver resolver = mContext.getContentResolver(); 7332 String debugApp = Settings.System.getString( 7333 resolver, Settings.System.DEBUG_APP); 7334 boolean waitForDebugger = Settings.System.getInt( 7335 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7336 boolean alwaysFinishActivities = Settings.System.getInt( 7337 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7338 7339 Configuration configuration = new Configuration(); 7340 Settings.System.getConfiguration(resolver, configuration); 7341 7342 synchronized (this) { 7343 mDebugApp = mOrigDebugApp = debugApp; 7344 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7345 mAlwaysFinishActivities = alwaysFinishActivities; 7346 // This happens before any activities are started, so we can 7347 // change mConfiguration in-place. 7348 updateConfigurationLocked(configuration, null, false, true); 7349 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7350 } 7351 } 7352 7353 public boolean testIsSystemReady() { 7354 // no need to synchronize(this) just to read & return the value 7355 return mSystemReady; 7356 } 7357 7358 private static File getCalledPreBootReceiversFile() { 7359 File dataDir = Environment.getDataDirectory(); 7360 File systemDir = new File(dataDir, "system"); 7361 File fname = new File(systemDir, "called_pre_boots.dat"); 7362 return fname; 7363 } 7364 7365 static final int LAST_DONE_VERSION = 10000; 7366 7367 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7368 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7369 File file = getCalledPreBootReceiversFile(); 7370 FileInputStream fis = null; 7371 try { 7372 fis = new FileInputStream(file); 7373 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7374 int fvers = dis.readInt(); 7375 if (fvers == LAST_DONE_VERSION) { 7376 String vers = dis.readUTF(); 7377 String codename = dis.readUTF(); 7378 String build = dis.readUTF(); 7379 if (android.os.Build.VERSION.RELEASE.equals(vers) 7380 && android.os.Build.VERSION.CODENAME.equals(codename) 7381 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7382 int num = dis.readInt(); 7383 while (num > 0) { 7384 num--; 7385 String pkg = dis.readUTF(); 7386 String cls = dis.readUTF(); 7387 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7388 } 7389 } 7390 } 7391 } catch (FileNotFoundException e) { 7392 } catch (IOException e) { 7393 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7394 } finally { 7395 if (fis != null) { 7396 try { 7397 fis.close(); 7398 } catch (IOException e) { 7399 } 7400 } 7401 } 7402 return lastDoneReceivers; 7403 } 7404 7405 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7406 File file = getCalledPreBootReceiversFile(); 7407 FileOutputStream fos = null; 7408 DataOutputStream dos = null; 7409 try { 7410 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7411 fos = new FileOutputStream(file); 7412 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7413 dos.writeInt(LAST_DONE_VERSION); 7414 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7415 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7416 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7417 dos.writeInt(list.size()); 7418 for (int i=0; i<list.size(); i++) { 7419 dos.writeUTF(list.get(i).getPackageName()); 7420 dos.writeUTF(list.get(i).getClassName()); 7421 } 7422 } catch (IOException e) { 7423 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7424 file.delete(); 7425 } finally { 7426 FileUtils.sync(fos); 7427 if (dos != null) { 7428 try { 7429 dos.close(); 7430 } catch (IOException e) { 7431 // TODO Auto-generated catch block 7432 e.printStackTrace(); 7433 } 7434 } 7435 } 7436 } 7437 7438 public void systemReady(final Runnable goingCallback) { 7439 synchronized(this) { 7440 if (mSystemReady) { 7441 if (goingCallback != null) goingCallback.run(); 7442 return; 7443 } 7444 7445 // Check to see if there are any update receivers to run. 7446 if (!mDidUpdate) { 7447 if (mWaitingUpdate) { 7448 return; 7449 } 7450 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7451 List<ResolveInfo> ris = null; 7452 try { 7453 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7454 intent, null, 0, 0); 7455 } catch (RemoteException e) { 7456 } 7457 if (ris != null) { 7458 for (int i=ris.size()-1; i>=0; i--) { 7459 if ((ris.get(i).activityInfo.applicationInfo.flags 7460 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7461 ris.remove(i); 7462 } 7463 } 7464 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7465 7466 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7467 7468 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7469 for (int i=0; i<ris.size(); i++) { 7470 ActivityInfo ai = ris.get(i).activityInfo; 7471 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7472 if (lastDoneReceivers.contains(comp)) { 7473 ris.remove(i); 7474 i--; 7475 } 7476 } 7477 7478 for (int i=0; i<ris.size(); i++) { 7479 ActivityInfo ai = ris.get(i).activityInfo; 7480 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7481 doneReceivers.add(comp); 7482 intent.setComponent(comp); 7483 IIntentReceiver finisher = null; 7484 if (i == ris.size()-1) { 7485 finisher = new IIntentReceiver.Stub() { 7486 public void performReceive(Intent intent, int resultCode, 7487 String data, Bundle extras, boolean ordered, 7488 boolean sticky) { 7489 // The raw IIntentReceiver interface is called 7490 // with the AM lock held, so redispatch to 7491 // execute our code without the lock. 7492 mHandler.post(new Runnable() { 7493 public void run() { 7494 synchronized (ActivityManagerService.this) { 7495 mDidUpdate = true; 7496 } 7497 writeLastDonePreBootReceivers(doneReceivers); 7498 showBootMessage(mContext.getText( 7499 R.string.android_upgrading_complete), 7500 false); 7501 systemReady(goingCallback); 7502 } 7503 }); 7504 } 7505 }; 7506 } 7507 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7508 /* TODO: Send this to all users */ 7509 broadcastIntentLocked(null, null, intent, null, finisher, 7510 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7511 0 /* UserId zero */); 7512 if (finisher != null) { 7513 mWaitingUpdate = true; 7514 } 7515 } 7516 } 7517 if (mWaitingUpdate) { 7518 return; 7519 } 7520 mDidUpdate = true; 7521 } 7522 7523 mSystemReady = true; 7524 if (!mStartRunning) { 7525 return; 7526 } 7527 } 7528 7529 ArrayList<ProcessRecord> procsToKill = null; 7530 synchronized(mPidsSelfLocked) { 7531 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7532 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7533 if (!isAllowedWhileBooting(proc.info)){ 7534 if (procsToKill == null) { 7535 procsToKill = new ArrayList<ProcessRecord>(); 7536 } 7537 procsToKill.add(proc); 7538 } 7539 } 7540 } 7541 7542 synchronized(this) { 7543 if (procsToKill != null) { 7544 for (int i=procsToKill.size()-1; i>=0; i--) { 7545 ProcessRecord proc = procsToKill.get(i); 7546 Slog.i(TAG, "Removing system update proc: " + proc); 7547 removeProcessLocked(proc, true, false, "system update done"); 7548 } 7549 } 7550 7551 // Now that we have cleaned up any update processes, we 7552 // are ready to start launching real processes and know that 7553 // we won't trample on them any more. 7554 mProcessesReady = true; 7555 } 7556 7557 Slog.i(TAG, "System now ready"); 7558 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7559 SystemClock.uptimeMillis()); 7560 7561 synchronized(this) { 7562 // Make sure we have no pre-ready processes sitting around. 7563 7564 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7565 ResolveInfo ri = mContext.getPackageManager() 7566 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7567 STOCK_PM_FLAGS); 7568 CharSequence errorMsg = null; 7569 if (ri != null) { 7570 ActivityInfo ai = ri.activityInfo; 7571 ApplicationInfo app = ai.applicationInfo; 7572 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7573 mTopAction = Intent.ACTION_FACTORY_TEST; 7574 mTopData = null; 7575 mTopComponent = new ComponentName(app.packageName, 7576 ai.name); 7577 } else { 7578 errorMsg = mContext.getResources().getText( 7579 com.android.internal.R.string.factorytest_not_system); 7580 } 7581 } else { 7582 errorMsg = mContext.getResources().getText( 7583 com.android.internal.R.string.factorytest_no_action); 7584 } 7585 if (errorMsg != null) { 7586 mTopAction = null; 7587 mTopData = null; 7588 mTopComponent = null; 7589 Message msg = Message.obtain(); 7590 msg.what = SHOW_FACTORY_ERROR_MSG; 7591 msg.getData().putCharSequence("msg", errorMsg); 7592 mHandler.sendMessage(msg); 7593 } 7594 } 7595 } 7596 7597 retrieveSettings(); 7598 7599 if (goingCallback != null) goingCallback.run(); 7600 7601 synchronized (this) { 7602 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7603 try { 7604 List apps = AppGlobals.getPackageManager(). 7605 getPersistentApplications(STOCK_PM_FLAGS); 7606 if (apps != null) { 7607 int N = apps.size(); 7608 int i; 7609 for (i=0; i<N; i++) { 7610 ApplicationInfo info 7611 = (ApplicationInfo)apps.get(i); 7612 if (info != null && 7613 !info.packageName.equals("android")) { 7614 addAppLocked(info, false); 7615 } 7616 } 7617 } 7618 } catch (RemoteException ex) { 7619 // pm is in same process, this will never happen. 7620 } 7621 } 7622 7623 // Start up initial activity. 7624 mBooting = true; 7625 7626 try { 7627 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7628 Message msg = Message.obtain(); 7629 msg.what = SHOW_UID_ERROR_MSG; 7630 mHandler.sendMessage(msg); 7631 } 7632 } catch (RemoteException e) { 7633 } 7634 7635 mMainStack.resumeTopActivityLocked(null); 7636 } 7637 } 7638 7639 private boolean makeAppCrashingLocked(ProcessRecord app, 7640 String shortMsg, String longMsg, String stackTrace) { 7641 app.crashing = true; 7642 app.crashingReport = generateProcessError(app, 7643 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7644 startAppProblemLocked(app); 7645 app.stopFreezingAllLocked(); 7646 return handleAppCrashLocked(app); 7647 } 7648 7649 private void makeAppNotRespondingLocked(ProcessRecord app, 7650 String activity, String shortMsg, String longMsg) { 7651 app.notResponding = true; 7652 app.notRespondingReport = generateProcessError(app, 7653 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7654 activity, shortMsg, longMsg, null); 7655 startAppProblemLocked(app); 7656 app.stopFreezingAllLocked(); 7657 } 7658 7659 /** 7660 * Generate a process error record, suitable for attachment to a ProcessRecord. 7661 * 7662 * @param app The ProcessRecord in which the error occurred. 7663 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7664 * ActivityManager.AppErrorStateInfo 7665 * @param activity The activity associated with the crash, if known. 7666 * @param shortMsg Short message describing the crash. 7667 * @param longMsg Long message describing the crash. 7668 * @param stackTrace Full crash stack trace, may be null. 7669 * 7670 * @return Returns a fully-formed AppErrorStateInfo record. 7671 */ 7672 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7673 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7674 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7675 7676 report.condition = condition; 7677 report.processName = app.processName; 7678 report.pid = app.pid; 7679 report.uid = app.info.uid; 7680 report.tag = activity; 7681 report.shortMsg = shortMsg; 7682 report.longMsg = longMsg; 7683 report.stackTrace = stackTrace; 7684 7685 return report; 7686 } 7687 7688 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7689 synchronized (this) { 7690 app.crashing = false; 7691 app.crashingReport = null; 7692 app.notResponding = false; 7693 app.notRespondingReport = null; 7694 if (app.anrDialog == fromDialog) { 7695 app.anrDialog = null; 7696 } 7697 if (app.waitDialog == fromDialog) { 7698 app.waitDialog = null; 7699 } 7700 if (app.pid > 0 && app.pid != MY_PID) { 7701 handleAppCrashLocked(app); 7702 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7703 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7704 app.processName, app.setAdj, "user's request after error"); 7705 Process.killProcessQuiet(app.pid); 7706 } 7707 } 7708 } 7709 7710 private boolean handleAppCrashLocked(ProcessRecord app) { 7711 if (mHeadless) { 7712 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7713 return false; 7714 } 7715 long now = SystemClock.uptimeMillis(); 7716 7717 Long crashTime; 7718 if (!app.isolated) { 7719 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7720 } else { 7721 crashTime = null; 7722 } 7723 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7724 // This process loses! 7725 Slog.w(TAG, "Process " + app.info.processName 7726 + " has crashed too many times: killing!"); 7727 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7728 app.info.processName, app.uid); 7729 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7730 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7731 if (r.app == app) { 7732 Slog.w(TAG, " Force finishing activity " 7733 + r.intent.getComponent().flattenToShortString()); 7734 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7735 } 7736 } 7737 if (!app.persistent) { 7738 // We don't want to start this process again until the user 7739 // explicitly does so... but for persistent process, we really 7740 // need to keep it running. If a persistent process is actually 7741 // repeatedly crashing, then badness for everyone. 7742 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7743 app.info.processName); 7744 if (!app.isolated) { 7745 // XXX We don't have a way to mark isolated processes 7746 // as bad, since they don't have a peristent identity. 7747 mBadProcesses.put(app.info.processName, app.uid, now); 7748 mProcessCrashTimes.remove(app.info.processName, app.uid); 7749 } 7750 app.bad = true; 7751 app.removed = true; 7752 // Don't let services in this process be restarted and potentially 7753 // annoy the user repeatedly. Unless it is persistent, since those 7754 // processes run critical code. 7755 removeProcessLocked(app, false, false, "crash"); 7756 mMainStack.resumeTopActivityLocked(null); 7757 return false; 7758 } 7759 mMainStack.resumeTopActivityLocked(null); 7760 } else { 7761 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7762 if (r != null && r.app == app) { 7763 // If the top running activity is from this crashing 7764 // process, then terminate it to avoid getting in a loop. 7765 Slog.w(TAG, " Force finishing activity " 7766 + r.intent.getComponent().flattenToShortString()); 7767 int index = mMainStack.indexOfActivityLocked(r); 7768 r.stack.finishActivityLocked(r, index, 7769 Activity.RESULT_CANCELED, null, "crashed"); 7770 // Also terminate any activities below it that aren't yet 7771 // stopped, to avoid a situation where one will get 7772 // re-start our crashing activity once it gets resumed again. 7773 index--; 7774 if (index >= 0) { 7775 r = (ActivityRecord)mMainStack.mHistory.get(index); 7776 if (r.state == ActivityState.RESUMED 7777 || r.state == ActivityState.PAUSING 7778 || r.state == ActivityState.PAUSED) { 7779 if (!r.isHomeActivity || mHomeProcess != r.app) { 7780 Slog.w(TAG, " Force finishing activity " 7781 + r.intent.getComponent().flattenToShortString()); 7782 r.stack.finishActivityLocked(r, index, 7783 Activity.RESULT_CANCELED, null, "crashed"); 7784 } 7785 } 7786 } 7787 } 7788 } 7789 7790 // Bump up the crash count of any services currently running in the proc. 7791 if (app.services.size() != 0) { 7792 // Any services running in the application need to be placed 7793 // back in the pending list. 7794 Iterator<ServiceRecord> it = app.services.iterator(); 7795 while (it.hasNext()) { 7796 ServiceRecord sr = it.next(); 7797 sr.crashCount++; 7798 } 7799 } 7800 7801 // If the crashing process is what we consider to be the "home process" and it has been 7802 // replaced by a third-party app, clear the package preferred activities from packages 7803 // with a home activity running in the process to prevent a repeatedly crashing app 7804 // from blocking the user to manually clear the list. 7805 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7806 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7807 Iterator it = mHomeProcess.activities.iterator(); 7808 while (it.hasNext()) { 7809 ActivityRecord r = (ActivityRecord)it.next(); 7810 if (r.isHomeActivity) { 7811 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7812 try { 7813 ActivityThread.getPackageManager() 7814 .clearPackagePreferredActivities(r.packageName); 7815 } catch (RemoteException c) { 7816 // pm is in same process, this will never happen. 7817 } 7818 } 7819 } 7820 } 7821 7822 if (!app.isolated) { 7823 // XXX Can't keep track of crash times for isolated processes, 7824 // because they don't have a perisistent identity. 7825 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7826 } 7827 7828 return true; 7829 } 7830 7831 void startAppProblemLocked(ProcessRecord app) { 7832 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7833 mContext, app.info.packageName, app.info.flags); 7834 skipCurrentReceiverLocked(app); 7835 } 7836 7837 void skipCurrentReceiverLocked(ProcessRecord app) { 7838 for (BroadcastQueue queue : mBroadcastQueues) { 7839 queue.skipCurrentReceiverLocked(app); 7840 } 7841 } 7842 7843 /** 7844 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7845 * The application process will exit immediately after this call returns. 7846 * @param app object of the crashing app, null for the system server 7847 * @param crashInfo describing the exception 7848 */ 7849 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7850 ProcessRecord r = findAppProcess(app, "Crash"); 7851 final String processName = app == null ? "system_server" 7852 : (r == null ? "unknown" : r.processName); 7853 7854 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7855 processName, 7856 r == null ? -1 : r.info.flags, 7857 crashInfo.exceptionClassName, 7858 crashInfo.exceptionMessage, 7859 crashInfo.throwFileName, 7860 crashInfo.throwLineNumber); 7861 7862 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7863 7864 crashApplication(r, crashInfo); 7865 } 7866 7867 public void handleApplicationStrictModeViolation( 7868 IBinder app, 7869 int violationMask, 7870 StrictMode.ViolationInfo info) { 7871 ProcessRecord r = findAppProcess(app, "StrictMode"); 7872 if (r == null) { 7873 return; 7874 } 7875 7876 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7877 Integer stackFingerprint = info.hashCode(); 7878 boolean logIt = true; 7879 synchronized (mAlreadyLoggedViolatedStacks) { 7880 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7881 logIt = false; 7882 // TODO: sub-sample into EventLog for these, with 7883 // the info.durationMillis? Then we'd get 7884 // the relative pain numbers, without logging all 7885 // the stack traces repeatedly. We'd want to do 7886 // likewise in the client code, which also does 7887 // dup suppression, before the Binder call. 7888 } else { 7889 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7890 mAlreadyLoggedViolatedStacks.clear(); 7891 } 7892 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7893 } 7894 } 7895 if (logIt) { 7896 logStrictModeViolationToDropBox(r, info); 7897 } 7898 } 7899 7900 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7901 AppErrorResult result = new AppErrorResult(); 7902 synchronized (this) { 7903 final long origId = Binder.clearCallingIdentity(); 7904 7905 Message msg = Message.obtain(); 7906 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7907 HashMap<String, Object> data = new HashMap<String, Object>(); 7908 data.put("result", result); 7909 data.put("app", r); 7910 data.put("violationMask", violationMask); 7911 data.put("info", info); 7912 msg.obj = data; 7913 mHandler.sendMessage(msg); 7914 7915 Binder.restoreCallingIdentity(origId); 7916 } 7917 int res = result.get(); 7918 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7919 } 7920 } 7921 7922 // Depending on the policy in effect, there could be a bunch of 7923 // these in quick succession so we try to batch these together to 7924 // minimize disk writes, number of dropbox entries, and maximize 7925 // compression, by having more fewer, larger records. 7926 private void logStrictModeViolationToDropBox( 7927 ProcessRecord process, 7928 StrictMode.ViolationInfo info) { 7929 if (info == null) { 7930 return; 7931 } 7932 final boolean isSystemApp = process == null || 7933 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7934 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7935 final String processName = process == null ? "unknown" : process.processName; 7936 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7937 final DropBoxManager dbox = (DropBoxManager) 7938 mContext.getSystemService(Context.DROPBOX_SERVICE); 7939 7940 // Exit early if the dropbox isn't configured to accept this report type. 7941 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7942 7943 boolean bufferWasEmpty; 7944 boolean needsFlush; 7945 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7946 synchronized (sb) { 7947 bufferWasEmpty = sb.length() == 0; 7948 appendDropBoxProcessHeaders(process, processName, sb); 7949 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7950 sb.append("System-App: ").append(isSystemApp).append("\n"); 7951 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7952 if (info.violationNumThisLoop != 0) { 7953 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7954 } 7955 if (info.numAnimationsRunning != 0) { 7956 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7957 } 7958 if (info.broadcastIntentAction != null) { 7959 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7960 } 7961 if (info.durationMillis != -1) { 7962 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7963 } 7964 if (info.numInstances != -1) { 7965 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7966 } 7967 if (info.tags != null) { 7968 for (String tag : info.tags) { 7969 sb.append("Span-Tag: ").append(tag).append("\n"); 7970 } 7971 } 7972 sb.append("\n"); 7973 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7974 sb.append(info.crashInfo.stackTrace); 7975 } 7976 sb.append("\n"); 7977 7978 // Only buffer up to ~64k. Various logging bits truncate 7979 // things at 128k. 7980 needsFlush = (sb.length() > 64 * 1024); 7981 } 7982 7983 // Flush immediately if the buffer's grown too large, or this 7984 // is a non-system app. Non-system apps are isolated with a 7985 // different tag & policy and not batched. 7986 // 7987 // Batching is useful during internal testing with 7988 // StrictMode settings turned up high. Without batching, 7989 // thousands of separate files could be created on boot. 7990 if (!isSystemApp || needsFlush) { 7991 new Thread("Error dump: " + dropboxTag) { 7992 @Override 7993 public void run() { 7994 String report; 7995 synchronized (sb) { 7996 report = sb.toString(); 7997 sb.delete(0, sb.length()); 7998 sb.trimToSize(); 7999 } 8000 if (report.length() != 0) { 8001 dbox.addText(dropboxTag, report); 8002 } 8003 } 8004 }.start(); 8005 return; 8006 } 8007 8008 // System app batching: 8009 if (!bufferWasEmpty) { 8010 // An existing dropbox-writing thread is outstanding, so 8011 // we don't need to start it up. The existing thread will 8012 // catch the buffer appends we just did. 8013 return; 8014 } 8015 8016 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8017 // (After this point, we shouldn't access AMS internal data structures.) 8018 new Thread("Error dump: " + dropboxTag) { 8019 @Override 8020 public void run() { 8021 // 5 second sleep to let stacks arrive and be batched together 8022 try { 8023 Thread.sleep(5000); // 5 seconds 8024 } catch (InterruptedException e) {} 8025 8026 String errorReport; 8027 synchronized (mStrictModeBuffer) { 8028 errorReport = mStrictModeBuffer.toString(); 8029 if (errorReport.length() == 0) { 8030 return; 8031 } 8032 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8033 mStrictModeBuffer.trimToSize(); 8034 } 8035 dbox.addText(dropboxTag, errorReport); 8036 } 8037 }.start(); 8038 } 8039 8040 /** 8041 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8042 * @param app object of the crashing app, null for the system server 8043 * @param tag reported by the caller 8044 * @param crashInfo describing the context of the error 8045 * @return true if the process should exit immediately (WTF is fatal) 8046 */ 8047 public boolean handleApplicationWtf(IBinder app, String tag, 8048 ApplicationErrorReport.CrashInfo crashInfo) { 8049 ProcessRecord r = findAppProcess(app, "WTF"); 8050 final String processName = app == null ? "system_server" 8051 : (r == null ? "unknown" : r.processName); 8052 8053 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8054 processName, 8055 r == null ? -1 : r.info.flags, 8056 tag, crashInfo.exceptionMessage); 8057 8058 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8059 8060 if (r != null && r.pid != Process.myPid() && 8061 Settings.Secure.getInt(mContext.getContentResolver(), 8062 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8063 crashApplication(r, crashInfo); 8064 return true; 8065 } else { 8066 return false; 8067 } 8068 } 8069 8070 /** 8071 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8072 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8073 */ 8074 private ProcessRecord findAppProcess(IBinder app, String reason) { 8075 if (app == null) { 8076 return null; 8077 } 8078 8079 synchronized (this) { 8080 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8081 final int NA = apps.size(); 8082 for (int ia=0; ia<NA; ia++) { 8083 ProcessRecord p = apps.valueAt(ia); 8084 if (p.thread != null && p.thread.asBinder() == app) { 8085 return p; 8086 } 8087 } 8088 } 8089 8090 Slog.w(TAG, "Can't find mystery application for " + reason 8091 + " from pid=" + Binder.getCallingPid() 8092 + " uid=" + Binder.getCallingUid() + ": " + app); 8093 return null; 8094 } 8095 } 8096 8097 /** 8098 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8099 * to append various headers to the dropbox log text. 8100 */ 8101 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8102 StringBuilder sb) { 8103 // Watchdog thread ends up invoking this function (with 8104 // a null ProcessRecord) to add the stack file to dropbox. 8105 // Do not acquire a lock on this (am) in such cases, as it 8106 // could cause a potential deadlock, if and when watchdog 8107 // is invoked due to unavailability of lock on am and it 8108 // would prevent watchdog from killing system_server. 8109 if (process == null) { 8110 sb.append("Process: ").append(processName).append("\n"); 8111 return; 8112 } 8113 // Note: ProcessRecord 'process' is guarded by the service 8114 // instance. (notably process.pkgList, which could otherwise change 8115 // concurrently during execution of this method) 8116 synchronized (this) { 8117 sb.append("Process: ").append(processName).append("\n"); 8118 int flags = process.info.flags; 8119 IPackageManager pm = AppGlobals.getPackageManager(); 8120 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8121 for (String pkg : process.pkgList) { 8122 sb.append("Package: ").append(pkg); 8123 try { 8124 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8125 if (pi != null) { 8126 sb.append(" v").append(pi.versionCode); 8127 if (pi.versionName != null) { 8128 sb.append(" (").append(pi.versionName).append(")"); 8129 } 8130 } 8131 } catch (RemoteException e) { 8132 Slog.e(TAG, "Error getting package info: " + pkg, e); 8133 } 8134 sb.append("\n"); 8135 } 8136 } 8137 } 8138 8139 private static String processClass(ProcessRecord process) { 8140 if (process == null || process.pid == MY_PID) { 8141 return "system_server"; 8142 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8143 return "system_app"; 8144 } else { 8145 return "data_app"; 8146 } 8147 } 8148 8149 /** 8150 * Write a description of an error (crash, WTF, ANR) to the drop box. 8151 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8152 * @param process which caused the error, null means the system server 8153 * @param activity which triggered the error, null if unknown 8154 * @param parent activity related to the error, null if unknown 8155 * @param subject line related to the error, null if absent 8156 * @param report in long form describing the error, null if absent 8157 * @param logFile to include in the report, null if none 8158 * @param crashInfo giving an application stack trace, null if absent 8159 */ 8160 public void addErrorToDropBox(String eventType, 8161 ProcessRecord process, String processName, ActivityRecord activity, 8162 ActivityRecord parent, String subject, 8163 final String report, final File logFile, 8164 final ApplicationErrorReport.CrashInfo crashInfo) { 8165 // NOTE -- this must never acquire the ActivityManagerService lock, 8166 // otherwise the watchdog may be prevented from resetting the system. 8167 8168 final String dropboxTag = processClass(process) + "_" + eventType; 8169 final DropBoxManager dbox = (DropBoxManager) 8170 mContext.getSystemService(Context.DROPBOX_SERVICE); 8171 8172 // Exit early if the dropbox isn't configured to accept this report type. 8173 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8174 8175 final StringBuilder sb = new StringBuilder(1024); 8176 appendDropBoxProcessHeaders(process, processName, sb); 8177 if (activity != null) { 8178 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8179 } 8180 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8181 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8182 } 8183 if (parent != null && parent != activity) { 8184 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8185 } 8186 if (subject != null) { 8187 sb.append("Subject: ").append(subject).append("\n"); 8188 } 8189 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8190 if (Debug.isDebuggerConnected()) { 8191 sb.append("Debugger: Connected\n"); 8192 } 8193 sb.append("\n"); 8194 8195 // Do the rest in a worker thread to avoid blocking the caller on I/O 8196 // (After this point, we shouldn't access AMS internal data structures.) 8197 Thread worker = new Thread("Error dump: " + dropboxTag) { 8198 @Override 8199 public void run() { 8200 if (report != null) { 8201 sb.append(report); 8202 } 8203 if (logFile != null) { 8204 try { 8205 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8206 } catch (IOException e) { 8207 Slog.e(TAG, "Error reading " + logFile, e); 8208 } 8209 } 8210 if (crashInfo != null && crashInfo.stackTrace != null) { 8211 sb.append(crashInfo.stackTrace); 8212 } 8213 8214 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8215 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8216 if (lines > 0) { 8217 sb.append("\n"); 8218 8219 // Merge several logcat streams, and take the last N lines 8220 InputStreamReader input = null; 8221 try { 8222 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8223 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8224 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8225 8226 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8227 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8228 input = new InputStreamReader(logcat.getInputStream()); 8229 8230 int num; 8231 char[] buf = new char[8192]; 8232 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8233 } catch (IOException e) { 8234 Slog.e(TAG, "Error running logcat", e); 8235 } finally { 8236 if (input != null) try { input.close(); } catch (IOException e) {} 8237 } 8238 } 8239 8240 dbox.addText(dropboxTag, sb.toString()); 8241 } 8242 }; 8243 8244 if (process == null) { 8245 // If process is null, we are being called from some internal code 8246 // and may be about to die -- run this synchronously. 8247 worker.run(); 8248 } else { 8249 worker.start(); 8250 } 8251 } 8252 8253 /** 8254 * Bring up the "unexpected error" dialog box for a crashing app. 8255 * Deal with edge cases (intercepts from instrumented applications, 8256 * ActivityController, error intent receivers, that sort of thing). 8257 * @param r the application crashing 8258 * @param crashInfo describing the failure 8259 */ 8260 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8261 long timeMillis = System.currentTimeMillis(); 8262 String shortMsg = crashInfo.exceptionClassName; 8263 String longMsg = crashInfo.exceptionMessage; 8264 String stackTrace = crashInfo.stackTrace; 8265 if (shortMsg != null && longMsg != null) { 8266 longMsg = shortMsg + ": " + longMsg; 8267 } else if (shortMsg != null) { 8268 longMsg = shortMsg; 8269 } 8270 8271 AppErrorResult result = new AppErrorResult(); 8272 synchronized (this) { 8273 if (mController != null) { 8274 try { 8275 String name = r != null ? r.processName : null; 8276 int pid = r != null ? r.pid : Binder.getCallingPid(); 8277 if (!mController.appCrashed(name, pid, 8278 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8279 Slog.w(TAG, "Force-killing crashed app " + name 8280 + " at watcher's request"); 8281 Process.killProcess(pid); 8282 return; 8283 } 8284 } catch (RemoteException e) { 8285 mController = null; 8286 } 8287 } 8288 8289 final long origId = Binder.clearCallingIdentity(); 8290 8291 // If this process is running instrumentation, finish it. 8292 if (r != null && r.instrumentationClass != null) { 8293 Slog.w(TAG, "Error in app " + r.processName 8294 + " running instrumentation " + r.instrumentationClass + ":"); 8295 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8296 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8297 Bundle info = new Bundle(); 8298 info.putString("shortMsg", shortMsg); 8299 info.putString("longMsg", longMsg); 8300 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8301 Binder.restoreCallingIdentity(origId); 8302 return; 8303 } 8304 8305 // If we can't identify the process or it's already exceeded its crash quota, 8306 // quit right away without showing a crash dialog. 8307 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8308 Binder.restoreCallingIdentity(origId); 8309 return; 8310 } 8311 8312 Message msg = Message.obtain(); 8313 msg.what = SHOW_ERROR_MSG; 8314 HashMap data = new HashMap(); 8315 data.put("result", result); 8316 data.put("app", r); 8317 msg.obj = data; 8318 mHandler.sendMessage(msg); 8319 8320 Binder.restoreCallingIdentity(origId); 8321 } 8322 8323 int res = result.get(); 8324 8325 Intent appErrorIntent = null; 8326 synchronized (this) { 8327 if (r != null && !r.isolated) { 8328 // XXX Can't keep track of crash time for isolated processes, 8329 // since they don't have a persistent identity. 8330 mProcessCrashTimes.put(r.info.processName, r.uid, 8331 SystemClock.uptimeMillis()); 8332 } 8333 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8334 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8335 } 8336 } 8337 8338 if (appErrorIntent != null) { 8339 try { 8340 mContext.startActivity(appErrorIntent); 8341 } catch (ActivityNotFoundException e) { 8342 Slog.w(TAG, "bug report receiver dissappeared", e); 8343 } 8344 } 8345 } 8346 8347 Intent createAppErrorIntentLocked(ProcessRecord r, 8348 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8349 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8350 if (report == null) { 8351 return null; 8352 } 8353 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8354 result.setComponent(r.errorReportReceiver); 8355 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8356 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8357 return result; 8358 } 8359 8360 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8361 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8362 if (r.errorReportReceiver == null) { 8363 return null; 8364 } 8365 8366 if (!r.crashing && !r.notResponding) { 8367 return null; 8368 } 8369 8370 ApplicationErrorReport report = new ApplicationErrorReport(); 8371 report.packageName = r.info.packageName; 8372 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8373 report.processName = r.processName; 8374 report.time = timeMillis; 8375 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8376 8377 if (r.crashing) { 8378 report.type = ApplicationErrorReport.TYPE_CRASH; 8379 report.crashInfo = crashInfo; 8380 } else if (r.notResponding) { 8381 report.type = ApplicationErrorReport.TYPE_ANR; 8382 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8383 8384 report.anrInfo.activity = r.notRespondingReport.tag; 8385 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8386 report.anrInfo.info = r.notRespondingReport.longMsg; 8387 } 8388 8389 return report; 8390 } 8391 8392 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8393 enforceNotIsolatedCaller("getProcessesInErrorState"); 8394 // assume our apps are happy - lazy create the list 8395 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8396 8397 final boolean allUsers = ActivityManager.checkUidPermission( 8398 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8399 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8400 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8401 8402 synchronized (this) { 8403 8404 // iterate across all processes 8405 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8406 ProcessRecord app = mLruProcesses.get(i); 8407 if (!allUsers && app.userId != userId) { 8408 continue; 8409 } 8410 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8411 // This one's in trouble, so we'll generate a report for it 8412 // crashes are higher priority (in case there's a crash *and* an anr) 8413 ActivityManager.ProcessErrorStateInfo report = null; 8414 if (app.crashing) { 8415 report = app.crashingReport; 8416 } else if (app.notResponding) { 8417 report = app.notRespondingReport; 8418 } 8419 8420 if (report != null) { 8421 if (errList == null) { 8422 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8423 } 8424 errList.add(report); 8425 } else { 8426 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8427 " crashing = " + app.crashing + 8428 " notResponding = " + app.notResponding); 8429 } 8430 } 8431 } 8432 } 8433 8434 return errList; 8435 } 8436 8437 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8438 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8439 if (currApp != null) { 8440 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8441 } 8442 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8443 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8444 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8445 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8446 if (currApp != null) { 8447 currApp.lru = 0; 8448 } 8449 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8450 } else if (adj >= ProcessList.SERVICE_ADJ) { 8451 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8452 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8453 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8454 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8455 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8456 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8457 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8458 } else { 8459 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8460 } 8461 } 8462 8463 private void fillInProcMemInfo(ProcessRecord app, 8464 ActivityManager.RunningAppProcessInfo outInfo) { 8465 outInfo.pid = app.pid; 8466 outInfo.uid = app.info.uid; 8467 if (mHeavyWeightProcess == app) { 8468 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8469 } 8470 if (app.persistent) { 8471 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8472 } 8473 if (app.hasActivities) { 8474 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8475 } 8476 outInfo.lastTrimLevel = app.trimMemoryLevel; 8477 int adj = app.curAdj; 8478 outInfo.importance = oomAdjToImportance(adj, outInfo); 8479 outInfo.importanceReasonCode = app.adjTypeCode; 8480 } 8481 8482 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8483 enforceNotIsolatedCaller("getRunningAppProcesses"); 8484 // Lazy instantiation of list 8485 List<ActivityManager.RunningAppProcessInfo> runList = null; 8486 final boolean allUsers = ActivityManager.checkUidPermission( 8487 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8488 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8489 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8490 synchronized (this) { 8491 // Iterate across all processes 8492 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8493 ProcessRecord app = mLruProcesses.get(i); 8494 if (!allUsers && app.userId != userId) { 8495 continue; 8496 } 8497 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8498 // Generate process state info for running application 8499 ActivityManager.RunningAppProcessInfo currApp = 8500 new ActivityManager.RunningAppProcessInfo(app.processName, 8501 app.pid, app.getPackageList()); 8502 fillInProcMemInfo(app, currApp); 8503 if (app.adjSource instanceof ProcessRecord) { 8504 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8505 currApp.importanceReasonImportance = oomAdjToImportance( 8506 app.adjSourceOom, null); 8507 } else if (app.adjSource instanceof ActivityRecord) { 8508 ActivityRecord r = (ActivityRecord)app.adjSource; 8509 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8510 } 8511 if (app.adjTarget instanceof ComponentName) { 8512 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8513 } 8514 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8515 // + " lru=" + currApp.lru); 8516 if (runList == null) { 8517 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8518 } 8519 runList.add(currApp); 8520 } 8521 } 8522 } 8523 return runList; 8524 } 8525 8526 public List<ApplicationInfo> getRunningExternalApplications() { 8527 enforceNotIsolatedCaller("getRunningExternalApplications"); 8528 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8529 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8530 if (runningApps != null && runningApps.size() > 0) { 8531 Set<String> extList = new HashSet<String>(); 8532 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8533 if (app.pkgList != null) { 8534 for (String pkg : app.pkgList) { 8535 extList.add(pkg); 8536 } 8537 } 8538 } 8539 IPackageManager pm = AppGlobals.getPackageManager(); 8540 for (String pkg : extList) { 8541 try { 8542 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8543 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8544 retList.add(info); 8545 } 8546 } catch (RemoteException e) { 8547 } 8548 } 8549 } 8550 return retList; 8551 } 8552 8553 @Override 8554 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8555 enforceNotIsolatedCaller("getMyMemoryState"); 8556 synchronized (this) { 8557 ProcessRecord proc; 8558 synchronized (mPidsSelfLocked) { 8559 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8560 } 8561 fillInProcMemInfo(proc, outInfo); 8562 } 8563 } 8564 8565 @Override 8566 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8567 if (checkCallingPermission(android.Manifest.permission.DUMP) 8568 != PackageManager.PERMISSION_GRANTED) { 8569 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8570 + Binder.getCallingPid() 8571 + ", uid=" + Binder.getCallingUid() 8572 + " without permission " 8573 + android.Manifest.permission.DUMP); 8574 return; 8575 } 8576 8577 boolean dumpAll = false; 8578 boolean dumpClient = false; 8579 String dumpPackage = null; 8580 8581 int opti = 0; 8582 while (opti < args.length) { 8583 String opt = args[opti]; 8584 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8585 break; 8586 } 8587 opti++; 8588 if ("-a".equals(opt)) { 8589 dumpAll = true; 8590 } else if ("-c".equals(opt)) { 8591 dumpClient = true; 8592 } else if ("-h".equals(opt)) { 8593 pw.println("Activity manager dump options:"); 8594 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8595 pw.println(" cmd may be one of:"); 8596 pw.println(" a[ctivities]: activity stack state"); 8597 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8598 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8599 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8600 pw.println(" o[om]: out of memory management"); 8601 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8602 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8603 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8604 pw.println(" service [COMP_SPEC]: service client-side state"); 8605 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8606 pw.println(" all: dump all activities"); 8607 pw.println(" top: dump the top activity"); 8608 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8609 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8610 pw.println(" a partial substring in a component name, a"); 8611 pw.println(" hex object identifier."); 8612 pw.println(" -a: include all available server state."); 8613 pw.println(" -c: include client state."); 8614 return; 8615 } else { 8616 pw.println("Unknown argument: " + opt + "; use -h for help"); 8617 } 8618 } 8619 8620 long origId = Binder.clearCallingIdentity(); 8621 boolean more = false; 8622 // Is the caller requesting to dump a particular piece of data? 8623 if (opti < args.length) { 8624 String cmd = args[opti]; 8625 opti++; 8626 if ("activities".equals(cmd) || "a".equals(cmd)) { 8627 synchronized (this) { 8628 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8629 } 8630 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8631 String[] newArgs; 8632 String name; 8633 if (opti >= args.length) { 8634 name = null; 8635 newArgs = EMPTY_STRING_ARRAY; 8636 } else { 8637 name = args[opti]; 8638 opti++; 8639 newArgs = new String[args.length - opti]; 8640 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8641 args.length - opti); 8642 } 8643 synchronized (this) { 8644 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8645 } 8646 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8647 String[] newArgs; 8648 String name; 8649 if (opti >= args.length) { 8650 name = null; 8651 newArgs = EMPTY_STRING_ARRAY; 8652 } else { 8653 name = args[opti]; 8654 opti++; 8655 newArgs = new String[args.length - opti]; 8656 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8657 args.length - opti); 8658 } 8659 synchronized (this) { 8660 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8661 } 8662 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8663 String[] newArgs; 8664 String name; 8665 if (opti >= args.length) { 8666 name = null; 8667 newArgs = EMPTY_STRING_ARRAY; 8668 } else { 8669 name = args[opti]; 8670 opti++; 8671 newArgs = new String[args.length - opti]; 8672 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8673 args.length - opti); 8674 } 8675 synchronized (this) { 8676 dumpProcessesLocked(fd, pw, args, opti, true, name); 8677 } 8678 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8679 synchronized (this) { 8680 dumpOomLocked(fd, pw, args, opti, true); 8681 } 8682 } else if ("provider".equals(cmd)) { 8683 String[] newArgs; 8684 String name; 8685 if (opti >= args.length) { 8686 name = null; 8687 newArgs = EMPTY_STRING_ARRAY; 8688 } else { 8689 name = args[opti]; 8690 opti++; 8691 newArgs = new String[args.length - opti]; 8692 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8693 } 8694 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8695 pw.println("No providers match: " + name); 8696 pw.println("Use -h for help."); 8697 } 8698 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8699 synchronized (this) { 8700 dumpProvidersLocked(fd, pw, args, opti, true, null); 8701 } 8702 } else if ("service".equals(cmd)) { 8703 String[] newArgs; 8704 String name; 8705 if (opti >= args.length) { 8706 name = null; 8707 newArgs = EMPTY_STRING_ARRAY; 8708 } else { 8709 name = args[opti]; 8710 opti++; 8711 newArgs = new String[args.length - opti]; 8712 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8713 args.length - opti); 8714 } 8715 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8716 pw.println("No services match: " + name); 8717 pw.println("Use -h for help."); 8718 } 8719 } else if ("package".equals(cmd)) { 8720 String[] newArgs; 8721 if (opti >= args.length) { 8722 pw.println("package: no package name specified"); 8723 pw.println("Use -h for help."); 8724 } else { 8725 dumpPackage = args[opti]; 8726 opti++; 8727 newArgs = new String[args.length - opti]; 8728 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8729 args.length - opti); 8730 args = newArgs; 8731 opti = 0; 8732 more = true; 8733 } 8734 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8735 synchronized (this) { 8736 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8737 } 8738 } else { 8739 // Dumping a single activity? 8740 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8741 pw.println("Bad activity command, or no activities match: " + cmd); 8742 pw.println("Use -h for help."); 8743 } 8744 } 8745 if (!more) { 8746 Binder.restoreCallingIdentity(origId); 8747 return; 8748 } 8749 } 8750 8751 // No piece of data specified, dump everything. 8752 synchronized (this) { 8753 boolean needSep; 8754 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8755 if (needSep) { 8756 pw.println(" "); 8757 } 8758 if (dumpAll) { 8759 pw.println("-------------------------------------------------------------------------------"); 8760 } 8761 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8762 if (needSep) { 8763 pw.println(" "); 8764 } 8765 if (dumpAll) { 8766 pw.println("-------------------------------------------------------------------------------"); 8767 } 8768 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8769 if (needSep) { 8770 pw.println(" "); 8771 } 8772 if (dumpAll) { 8773 pw.println("-------------------------------------------------------------------------------"); 8774 } 8775 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8776 if (needSep) { 8777 pw.println(" "); 8778 } 8779 if (dumpAll) { 8780 pw.println("-------------------------------------------------------------------------------"); 8781 } 8782 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8783 if (needSep) { 8784 pw.println(" "); 8785 } 8786 if (dumpAll) { 8787 pw.println("-------------------------------------------------------------------------------"); 8788 } 8789 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8790 } 8791 Binder.restoreCallingIdentity(origId); 8792 } 8793 8794 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8795 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8796 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8797 pw.println(" Main stack:"); 8798 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8799 dumpPackage); 8800 pw.println(" "); 8801 pw.println(" Running activities (most recent first):"); 8802 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8803 dumpPackage); 8804 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8805 pw.println(" "); 8806 pw.println(" Activities waiting for another to become visible:"); 8807 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8808 !dumpAll, false, dumpPackage); 8809 } 8810 if (mMainStack.mStoppingActivities.size() > 0) { 8811 pw.println(" "); 8812 pw.println(" Activities waiting to stop:"); 8813 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8814 !dumpAll, false, dumpPackage); 8815 } 8816 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8817 pw.println(" "); 8818 pw.println(" Activities waiting to sleep:"); 8819 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8820 !dumpAll, false, dumpPackage); 8821 } 8822 if (mMainStack.mFinishingActivities.size() > 0) { 8823 pw.println(" "); 8824 pw.println(" Activities waiting to finish:"); 8825 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8826 !dumpAll, false, dumpPackage); 8827 } 8828 8829 pw.println(" "); 8830 if (mMainStack.mPausingActivity != null) { 8831 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8832 } 8833 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8834 pw.println(" mFocusedActivity: " + mFocusedActivity); 8835 if (dumpAll) { 8836 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8837 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8838 pw.println(" mDismissKeyguardOnNextActivity: " 8839 + mMainStack.mDismissKeyguardOnNextActivity); 8840 } 8841 8842 if (mRecentTasks.size() > 0) { 8843 pw.println(); 8844 pw.println(" Recent tasks:"); 8845 8846 final int N = mRecentTasks.size(); 8847 for (int i=0; i<N; i++) { 8848 TaskRecord tr = mRecentTasks.get(i); 8849 if (dumpPackage != null) { 8850 if (tr.realActivity == null || 8851 !dumpPackage.equals(tr.realActivity)) { 8852 continue; 8853 } 8854 } 8855 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8856 pw.println(tr); 8857 if (dumpAll) { 8858 mRecentTasks.get(i).dump(pw, " "); 8859 } 8860 } 8861 } 8862 8863 if (dumpAll) { 8864 pw.println(" "); 8865 pw.println(" mCurTask: " + mCurTask); 8866 } 8867 8868 return true; 8869 } 8870 8871 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8872 int opti, boolean dumpAll, String dumpPackage) { 8873 boolean needSep = false; 8874 int numPers = 0; 8875 8876 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8877 8878 if (dumpAll) { 8879 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8880 final int NA = procs.size(); 8881 for (int ia=0; ia<NA; ia++) { 8882 ProcessRecord r = procs.valueAt(ia); 8883 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8884 continue; 8885 } 8886 if (!needSep) { 8887 pw.println(" All known processes:"); 8888 needSep = true; 8889 } 8890 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8891 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8892 pw.print(" "); pw.println(r); 8893 r.dump(pw, " "); 8894 if (r.persistent) { 8895 numPers++; 8896 } 8897 } 8898 } 8899 } 8900 8901 if (mIsolatedProcesses.size() > 0) { 8902 if (needSep) pw.println(" "); 8903 needSep = true; 8904 pw.println(" Isolated process list (sorted by uid):"); 8905 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8906 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8907 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8908 continue; 8909 } 8910 pw.println(String.format("%sIsolated #%2d: %s", 8911 " ", i, r.toString())); 8912 } 8913 } 8914 8915 if (mLruProcesses.size() > 0) { 8916 if (needSep) pw.println(" "); 8917 needSep = true; 8918 pw.println(" Process LRU list (sorted by oom_adj):"); 8919 dumpProcessOomList(pw, this, mLruProcesses, " ", 8920 "Proc", "PERS", false, dumpPackage); 8921 needSep = true; 8922 } 8923 8924 if (dumpAll) { 8925 synchronized (mPidsSelfLocked) { 8926 boolean printed = false; 8927 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8928 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8929 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8930 continue; 8931 } 8932 if (!printed) { 8933 if (needSep) pw.println(" "); 8934 needSep = true; 8935 pw.println(" PID mappings:"); 8936 printed = true; 8937 } 8938 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8939 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8940 } 8941 } 8942 } 8943 8944 if (mForegroundProcesses.size() > 0) { 8945 synchronized (mPidsSelfLocked) { 8946 boolean printed = false; 8947 for (int i=0; i<mForegroundProcesses.size(); i++) { 8948 ProcessRecord r = mPidsSelfLocked.get( 8949 mForegroundProcesses.valueAt(i).pid); 8950 if (dumpPackage != null && (r == null 8951 || !dumpPackage.equals(r.info.packageName))) { 8952 continue; 8953 } 8954 if (!printed) { 8955 if (needSep) pw.println(" "); 8956 needSep = true; 8957 pw.println(" Foreground Processes:"); 8958 printed = true; 8959 } 8960 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8961 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8962 } 8963 } 8964 } 8965 8966 if (mPersistentStartingProcesses.size() > 0) { 8967 if (needSep) pw.println(" "); 8968 needSep = true; 8969 pw.println(" Persisent processes that are starting:"); 8970 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8971 "Starting Norm", "Restarting PERS", dumpPackage); 8972 } 8973 8974 if (mRemovedProcesses.size() > 0) { 8975 if (needSep) pw.println(" "); 8976 needSep = true; 8977 pw.println(" Processes that are being removed:"); 8978 dumpProcessList(pw, this, mRemovedProcesses, " ", 8979 "Removed Norm", "Removed PERS", dumpPackage); 8980 } 8981 8982 if (mProcessesOnHold.size() > 0) { 8983 if (needSep) pw.println(" "); 8984 needSep = true; 8985 pw.println(" Processes that are on old until the system is ready:"); 8986 dumpProcessList(pw, this, mProcessesOnHold, " ", 8987 "OnHold Norm", "OnHold PERS", dumpPackage); 8988 } 8989 8990 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8991 8992 if (mProcessCrashTimes.getMap().size() > 0) { 8993 boolean printed = false; 8994 long now = SystemClock.uptimeMillis(); 8995 for (Map.Entry<String, SparseArray<Long>> procs 8996 : mProcessCrashTimes.getMap().entrySet()) { 8997 String pname = procs.getKey(); 8998 SparseArray<Long> uids = procs.getValue(); 8999 final int N = uids.size(); 9000 for (int i=0; i<N; i++) { 9001 int puid = uids.keyAt(i); 9002 ProcessRecord r = mProcessNames.get(pname, puid); 9003 if (dumpPackage != null && (r == null 9004 || !dumpPackage.equals(r.info.packageName))) { 9005 continue; 9006 } 9007 if (!printed) { 9008 if (needSep) pw.println(" "); 9009 needSep = true; 9010 pw.println(" Time since processes crashed:"); 9011 printed = true; 9012 } 9013 pw.print(" Process "); pw.print(pname); 9014 pw.print(" uid "); pw.print(puid); 9015 pw.print(": last crashed "); 9016 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9017 pw.println(" ago"); 9018 } 9019 } 9020 } 9021 9022 if (mBadProcesses.getMap().size() > 0) { 9023 boolean printed = false; 9024 for (Map.Entry<String, SparseArray<Long>> procs 9025 : mBadProcesses.getMap().entrySet()) { 9026 String pname = procs.getKey(); 9027 SparseArray<Long> uids = procs.getValue(); 9028 final int N = uids.size(); 9029 for (int i=0; i<N; i++) { 9030 int puid = uids.keyAt(i); 9031 ProcessRecord r = mProcessNames.get(pname, puid); 9032 if (dumpPackage != null && (r == null 9033 || !dumpPackage.equals(r.info.packageName))) { 9034 continue; 9035 } 9036 if (!printed) { 9037 if (needSep) pw.println(" "); 9038 needSep = true; 9039 pw.println(" Bad processes:"); 9040 } 9041 pw.print(" Bad process "); pw.print(pname); 9042 pw.print(" uid "); pw.print(puid); 9043 pw.print(": crashed at time "); 9044 pw.println(uids.valueAt(i)); 9045 } 9046 } 9047 } 9048 9049 pw.println(); 9050 pw.println(" mHomeProcess: " + mHomeProcess); 9051 pw.println(" mPreviousProcess: " + mPreviousProcess); 9052 if (dumpAll) { 9053 StringBuilder sb = new StringBuilder(128); 9054 sb.append(" mPreviousProcessVisibleTime: "); 9055 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9056 pw.println(sb); 9057 } 9058 if (mHeavyWeightProcess != null) { 9059 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9060 } 9061 pw.println(" mConfiguration: " + mConfiguration); 9062 if (dumpAll) { 9063 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9064 if (mCompatModePackages.getPackages().size() > 0) { 9065 boolean printed = false; 9066 for (Map.Entry<String, Integer> entry 9067 : mCompatModePackages.getPackages().entrySet()) { 9068 String pkg = entry.getKey(); 9069 int mode = entry.getValue(); 9070 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9071 continue; 9072 } 9073 if (!printed) { 9074 pw.println(" mScreenCompatPackages:"); 9075 printed = true; 9076 } 9077 pw.print(" "); pw.print(pkg); pw.print(": "); 9078 pw.print(mode); pw.println(); 9079 } 9080 } 9081 } 9082 if (mSleeping || mWentToSleep || mLockScreenShown) { 9083 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9084 + " mLockScreenShown " + mLockScreenShown); 9085 } 9086 if (mShuttingDown) { 9087 pw.println(" mShuttingDown=" + mShuttingDown); 9088 } 9089 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9090 || mOrigWaitForDebugger) { 9091 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9092 + " mDebugTransient=" + mDebugTransient 9093 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9094 } 9095 if (mOpenGlTraceApp != null) { 9096 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9097 } 9098 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9099 || mProfileFd != null) { 9100 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9101 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9102 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9103 + mAutoStopProfiler); 9104 } 9105 if (mAlwaysFinishActivities || mController != null) { 9106 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9107 + " mController=" + mController); 9108 } 9109 if (dumpAll) { 9110 pw.println(" Total persistent processes: " + numPers); 9111 pw.println(" mStartRunning=" + mStartRunning 9112 + " mProcessesReady=" + mProcessesReady 9113 + " mSystemReady=" + mSystemReady); 9114 pw.println(" mBooting=" + mBooting 9115 + " mBooted=" + mBooted 9116 + " mFactoryTest=" + mFactoryTest); 9117 pw.print(" mLastPowerCheckRealtime="); 9118 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9119 pw.println(""); 9120 pw.print(" mLastPowerCheckUptime="); 9121 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9122 pw.println(""); 9123 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9124 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9125 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9126 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9127 + " mNumHiddenProcs=" + mNumHiddenProcs 9128 + " mNumServiceProcs=" + mNumServiceProcs 9129 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9130 } 9131 9132 return true; 9133 } 9134 9135 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9136 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9137 if (mProcessesToGc.size() > 0) { 9138 boolean printed = false; 9139 long now = SystemClock.uptimeMillis(); 9140 for (int i=0; i<mProcessesToGc.size(); i++) { 9141 ProcessRecord proc = mProcessesToGc.get(i); 9142 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9143 continue; 9144 } 9145 if (!printed) { 9146 if (needSep) pw.println(" "); 9147 needSep = true; 9148 pw.println(" Processes that are waiting to GC:"); 9149 printed = true; 9150 } 9151 pw.print(" Process "); pw.println(proc); 9152 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9153 pw.print(", last gced="); 9154 pw.print(now-proc.lastRequestedGc); 9155 pw.print(" ms ago, last lowMem="); 9156 pw.print(now-proc.lastLowMemory); 9157 pw.println(" ms ago"); 9158 9159 } 9160 } 9161 return needSep; 9162 } 9163 9164 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9165 int opti, boolean dumpAll) { 9166 boolean needSep = false; 9167 9168 if (mLruProcesses.size() > 0) { 9169 if (needSep) pw.println(" "); 9170 needSep = true; 9171 pw.println(" OOM levels:"); 9172 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9173 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9174 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9175 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9176 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9177 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9178 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9179 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9180 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9181 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9182 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9183 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9184 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9185 9186 if (needSep) pw.println(" "); 9187 needSep = true; 9188 pw.println(" Process OOM control:"); 9189 dumpProcessOomList(pw, this, mLruProcesses, " ", 9190 "Proc", "PERS", true, null); 9191 needSep = true; 9192 } 9193 9194 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9195 9196 pw.println(); 9197 pw.println(" mHomeProcess: " + mHomeProcess); 9198 pw.println(" mPreviousProcess: " + mPreviousProcess); 9199 if (mHeavyWeightProcess != null) { 9200 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9201 } 9202 9203 return true; 9204 } 9205 9206 /** 9207 * There are three ways to call this: 9208 * - no provider specified: dump all the providers 9209 * - a flattened component name that matched an existing provider was specified as the 9210 * first arg: dump that one provider 9211 * - the first arg isn't the flattened component name of an existing provider: 9212 * dump all providers whose component contains the first arg as a substring 9213 */ 9214 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9215 int opti, boolean dumpAll) { 9216 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9217 } 9218 9219 static class ItemMatcher { 9220 ArrayList<ComponentName> components; 9221 ArrayList<String> strings; 9222 ArrayList<Integer> objects; 9223 boolean all; 9224 9225 ItemMatcher() { 9226 all = true; 9227 } 9228 9229 void build(String name) { 9230 ComponentName componentName = ComponentName.unflattenFromString(name); 9231 if (componentName != null) { 9232 if (components == null) { 9233 components = new ArrayList<ComponentName>(); 9234 } 9235 components.add(componentName); 9236 all = false; 9237 } else { 9238 int objectId = 0; 9239 // Not a '/' separated full component name; maybe an object ID? 9240 try { 9241 objectId = Integer.parseInt(name, 16); 9242 if (objects == null) { 9243 objects = new ArrayList<Integer>(); 9244 } 9245 objects.add(objectId); 9246 all = false; 9247 } catch (RuntimeException e) { 9248 // Not an integer; just do string match. 9249 if (strings == null) { 9250 strings = new ArrayList<String>(); 9251 } 9252 strings.add(name); 9253 all = false; 9254 } 9255 } 9256 } 9257 9258 int build(String[] args, int opti) { 9259 for (; opti<args.length; opti++) { 9260 String name = args[opti]; 9261 if ("--".equals(name)) { 9262 return opti+1; 9263 } 9264 build(name); 9265 } 9266 return opti; 9267 } 9268 9269 boolean match(Object object, ComponentName comp) { 9270 if (all) { 9271 return true; 9272 } 9273 if (components != null) { 9274 for (int i=0; i<components.size(); i++) { 9275 if (components.get(i).equals(comp)) { 9276 return true; 9277 } 9278 } 9279 } 9280 if (objects != null) { 9281 for (int i=0; i<objects.size(); i++) { 9282 if (System.identityHashCode(object) == objects.get(i)) { 9283 return true; 9284 } 9285 } 9286 } 9287 if (strings != null) { 9288 String flat = comp.flattenToString(); 9289 for (int i=0; i<strings.size(); i++) { 9290 if (flat.contains(strings.get(i))) { 9291 return true; 9292 } 9293 } 9294 } 9295 return false; 9296 } 9297 } 9298 9299 /** 9300 * There are three things that cmd can be: 9301 * - a flattened component name that matches an existing activity 9302 * - the cmd arg isn't the flattened component name of an existing activity: 9303 * dump all activity whose component contains the cmd as a substring 9304 * - A hex number of the ActivityRecord object instance. 9305 */ 9306 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9307 int opti, boolean dumpAll) { 9308 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9309 9310 if ("all".equals(name)) { 9311 synchronized (this) { 9312 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9313 activities.add(r1); 9314 } 9315 } 9316 } else if ("top".equals(name)) { 9317 synchronized (this) { 9318 final int N = mMainStack.mHistory.size(); 9319 if (N > 0) { 9320 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9321 } 9322 } 9323 } else { 9324 ItemMatcher matcher = new ItemMatcher(); 9325 matcher.build(name); 9326 9327 synchronized (this) { 9328 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9329 if (matcher.match(r1, r1.intent.getComponent())) { 9330 activities.add(r1); 9331 } 9332 } 9333 } 9334 } 9335 9336 if (activities.size() <= 0) { 9337 return false; 9338 } 9339 9340 String[] newArgs = new String[args.length - opti]; 9341 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9342 9343 TaskRecord lastTask = null; 9344 boolean needSep = false; 9345 for (int i=activities.size()-1; i>=0; i--) { 9346 ActivityRecord r = (ActivityRecord)activities.get(i); 9347 if (needSep) { 9348 pw.println(); 9349 } 9350 needSep = true; 9351 synchronized (this) { 9352 if (lastTask != r.task) { 9353 lastTask = r.task; 9354 pw.print("TASK "); pw.print(lastTask.affinity); 9355 pw.print(" id="); pw.println(lastTask.taskId); 9356 if (dumpAll) { 9357 lastTask.dump(pw, " "); 9358 } 9359 } 9360 } 9361 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9362 } 9363 return true; 9364 } 9365 9366 /** 9367 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9368 * there is a thread associated with the activity. 9369 */ 9370 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9371 final ActivityRecord r, String[] args, boolean dumpAll) { 9372 String innerPrefix = prefix + " "; 9373 synchronized (this) { 9374 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9375 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9376 pw.print(" pid="); 9377 if (r.app != null) pw.println(r.app.pid); 9378 else pw.println("(not running)"); 9379 if (dumpAll) { 9380 r.dump(pw, innerPrefix); 9381 } 9382 } 9383 if (r.app != null && r.app.thread != null) { 9384 // flush anything that is already in the PrintWriter since the thread is going 9385 // to write to the file descriptor directly 9386 pw.flush(); 9387 try { 9388 TransferPipe tp = new TransferPipe(); 9389 try { 9390 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9391 r.appToken, innerPrefix, args); 9392 tp.go(fd); 9393 } finally { 9394 tp.kill(); 9395 } 9396 } catch (IOException e) { 9397 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9398 } catch (RemoteException e) { 9399 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9400 } 9401 } 9402 } 9403 9404 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9405 int opti, boolean dumpAll, String dumpPackage) { 9406 boolean needSep = false; 9407 9408 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9409 if (dumpAll) { 9410 if (mRegisteredReceivers.size() > 0) { 9411 boolean printed = false; 9412 Iterator it = mRegisteredReceivers.values().iterator(); 9413 while (it.hasNext()) { 9414 ReceiverList r = (ReceiverList)it.next(); 9415 if (dumpPackage != null && (r.app == null || 9416 !dumpPackage.equals(r.app.info.packageName))) { 9417 continue; 9418 } 9419 if (!printed) { 9420 pw.println(" Registered Receivers:"); 9421 needSep = true; 9422 printed = true; 9423 } 9424 pw.print(" * "); pw.println(r); 9425 r.dump(pw, " "); 9426 } 9427 } 9428 9429 if (mReceiverResolver.dump(pw, needSep ? 9430 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9431 " ", dumpPackage, false)) { 9432 needSep = true; 9433 } 9434 } 9435 9436 for (BroadcastQueue q : mBroadcastQueues) { 9437 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9438 } 9439 9440 needSep = true; 9441 9442 if (mStickyBroadcasts != null && dumpPackage == null) { 9443 if (needSep) { 9444 pw.println(); 9445 } 9446 needSep = true; 9447 pw.println(" Sticky broadcasts:"); 9448 StringBuilder sb = new StringBuilder(128); 9449 for (Map.Entry<String, ArrayList<Intent>> ent 9450 : mStickyBroadcasts.entrySet()) { 9451 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9452 if (dumpAll) { 9453 pw.println(":"); 9454 ArrayList<Intent> intents = ent.getValue(); 9455 final int N = intents.size(); 9456 for (int i=0; i<N; i++) { 9457 sb.setLength(0); 9458 sb.append(" Intent: "); 9459 intents.get(i).toShortString(sb, false, true, false, false); 9460 pw.println(sb.toString()); 9461 Bundle bundle = intents.get(i).getExtras(); 9462 if (bundle != null) { 9463 pw.print(" "); 9464 pw.println(bundle.toString()); 9465 } 9466 } 9467 } else { 9468 pw.println(""); 9469 } 9470 } 9471 needSep = true; 9472 } 9473 9474 if (dumpAll) { 9475 pw.println(); 9476 for (BroadcastQueue queue : mBroadcastQueues) { 9477 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9478 + queue.mBroadcastsScheduled); 9479 } 9480 pw.println(" mHandler:"); 9481 mHandler.dump(new PrintWriterPrinter(pw), " "); 9482 needSep = true; 9483 } 9484 9485 return needSep; 9486 } 9487 9488 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9489 int opti, boolean dumpAll, String dumpPackage) { 9490 boolean needSep = true; 9491 9492 ItemMatcher matcher = new ItemMatcher(); 9493 matcher.build(args, opti); 9494 9495 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9496 9497 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9498 9499 if (mLaunchingProviders.size() > 0) { 9500 boolean printed = false; 9501 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9502 ContentProviderRecord r = mLaunchingProviders.get(i); 9503 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9504 continue; 9505 } 9506 if (!printed) { 9507 if (needSep) pw.println(" "); 9508 needSep = true; 9509 pw.println(" Launching content providers:"); 9510 printed = true; 9511 } 9512 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9513 pw.println(r); 9514 } 9515 } 9516 9517 if (mGrantedUriPermissions.size() > 0) { 9518 if (needSep) pw.println(); 9519 needSep = true; 9520 pw.println("Granted Uri Permissions:"); 9521 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9522 int uid = mGrantedUriPermissions.keyAt(i); 9523 HashMap<Uri, UriPermission> perms 9524 = mGrantedUriPermissions.valueAt(i); 9525 pw.print(" * UID "); pw.print(uid); 9526 pw.println(" holds:"); 9527 for (UriPermission perm : perms.values()) { 9528 pw.print(" "); pw.println(perm); 9529 if (dumpAll) { 9530 perm.dump(pw, " "); 9531 } 9532 } 9533 } 9534 needSep = true; 9535 } 9536 9537 return needSep; 9538 } 9539 9540 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9541 int opti, boolean dumpAll, String dumpPackage) { 9542 boolean needSep = false; 9543 9544 if (mIntentSenderRecords.size() > 0) { 9545 boolean printed = false; 9546 Iterator<WeakReference<PendingIntentRecord>> it 9547 = mIntentSenderRecords.values().iterator(); 9548 while (it.hasNext()) { 9549 WeakReference<PendingIntentRecord> ref = it.next(); 9550 PendingIntentRecord rec = ref != null ? ref.get(): null; 9551 if (dumpPackage != null && (rec == null 9552 || !dumpPackage.equals(rec.key.packageName))) { 9553 continue; 9554 } 9555 if (!printed) { 9556 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9557 printed = true; 9558 } 9559 needSep = true; 9560 if (rec != null) { 9561 pw.print(" * "); pw.println(rec); 9562 if (dumpAll) { 9563 rec.dump(pw, " "); 9564 } 9565 } else { 9566 pw.print(" * "); pw.println(ref); 9567 } 9568 } 9569 } 9570 9571 return needSep; 9572 } 9573 9574 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9575 String prefix, String label, boolean complete, boolean brief, boolean client, 9576 String dumpPackage) { 9577 TaskRecord lastTask = null; 9578 boolean needNL = false; 9579 final String innerPrefix = prefix + " "; 9580 final String[] args = new String[0]; 9581 for (int i=list.size()-1; i>=0; i--) { 9582 final ActivityRecord r = (ActivityRecord)list.get(i); 9583 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9584 continue; 9585 } 9586 final boolean full = !brief && (complete || !r.isInHistory()); 9587 if (needNL) { 9588 pw.println(" "); 9589 needNL = false; 9590 } 9591 if (lastTask != r.task) { 9592 lastTask = r.task; 9593 pw.print(prefix); 9594 pw.print(full ? "* " : " "); 9595 pw.println(lastTask); 9596 if (full) { 9597 lastTask.dump(pw, prefix + " "); 9598 } else if (complete) { 9599 // Complete + brief == give a summary. Isn't that obvious?!? 9600 if (lastTask.intent != null) { 9601 pw.print(prefix); pw.print(" "); 9602 pw.println(lastTask.intent.toInsecureStringWithClip()); 9603 } 9604 } 9605 } 9606 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9607 pw.print(" #"); pw.print(i); pw.print(": "); 9608 pw.println(r); 9609 if (full) { 9610 r.dump(pw, innerPrefix); 9611 } else if (complete) { 9612 // Complete + brief == give a summary. Isn't that obvious?!? 9613 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9614 if (r.app != null) { 9615 pw.print(innerPrefix); pw.println(r.app); 9616 } 9617 } 9618 if (client && r.app != null && r.app.thread != null) { 9619 // flush anything that is already in the PrintWriter since the thread is going 9620 // to write to the file descriptor directly 9621 pw.flush(); 9622 try { 9623 TransferPipe tp = new TransferPipe(); 9624 try { 9625 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9626 r.appToken, innerPrefix, args); 9627 // Short timeout, since blocking here can 9628 // deadlock with the application. 9629 tp.go(fd, 2000); 9630 } finally { 9631 tp.kill(); 9632 } 9633 } catch (IOException e) { 9634 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9635 } catch (RemoteException e) { 9636 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9637 } 9638 needNL = true; 9639 } 9640 } 9641 } 9642 9643 private static String buildOomTag(String prefix, String space, int val, int base) { 9644 if (val == base) { 9645 if (space == null) return prefix; 9646 return prefix + " "; 9647 } 9648 return prefix + "+" + Integer.toString(val-base); 9649 } 9650 9651 private static final int dumpProcessList(PrintWriter pw, 9652 ActivityManagerService service, List list, 9653 String prefix, String normalLabel, String persistentLabel, 9654 String dumpPackage) { 9655 int numPers = 0; 9656 final int N = list.size()-1; 9657 for (int i=N; i>=0; i--) { 9658 ProcessRecord r = (ProcessRecord)list.get(i); 9659 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9660 continue; 9661 } 9662 pw.println(String.format("%s%s #%2d: %s", 9663 prefix, (r.persistent ? persistentLabel : normalLabel), 9664 i, r.toString())); 9665 if (r.persistent) { 9666 numPers++; 9667 } 9668 } 9669 return numPers; 9670 } 9671 9672 private static final boolean dumpProcessOomList(PrintWriter pw, 9673 ActivityManagerService service, List<ProcessRecord> origList, 9674 String prefix, String normalLabel, String persistentLabel, 9675 boolean inclDetails, String dumpPackage) { 9676 9677 ArrayList<Pair<ProcessRecord, Integer>> list 9678 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9679 for (int i=0; i<origList.size(); i++) { 9680 ProcessRecord r = origList.get(i); 9681 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9682 continue; 9683 } 9684 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9685 } 9686 9687 if (list.size() <= 0) { 9688 return false; 9689 } 9690 9691 Comparator<Pair<ProcessRecord, Integer>> comparator 9692 = new Comparator<Pair<ProcessRecord, Integer>>() { 9693 @Override 9694 public int compare(Pair<ProcessRecord, Integer> object1, 9695 Pair<ProcessRecord, Integer> object2) { 9696 if (object1.first.setAdj != object2.first.setAdj) { 9697 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9698 } 9699 if (object1.second.intValue() != object2.second.intValue()) { 9700 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9701 } 9702 return 0; 9703 } 9704 }; 9705 9706 Collections.sort(list, comparator); 9707 9708 final long curRealtime = SystemClock.elapsedRealtime(); 9709 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9710 final long curUptime = SystemClock.uptimeMillis(); 9711 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9712 9713 for (int i=list.size()-1; i>=0; i--) { 9714 ProcessRecord r = list.get(i).first; 9715 String oomAdj; 9716 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9717 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9718 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9719 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9720 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9721 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9722 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9723 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9724 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9725 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9726 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9727 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9728 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9729 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9730 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9731 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9732 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9733 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9734 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9735 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9736 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9737 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9738 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9739 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9740 } else { 9741 oomAdj = Integer.toString(r.setAdj); 9742 } 9743 String schedGroup; 9744 switch (r.setSchedGroup) { 9745 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9746 schedGroup = "B"; 9747 break; 9748 case Process.THREAD_GROUP_DEFAULT: 9749 schedGroup = "F"; 9750 break; 9751 default: 9752 schedGroup = Integer.toString(r.setSchedGroup); 9753 break; 9754 } 9755 String foreground; 9756 if (r.foregroundActivities) { 9757 foreground = "A"; 9758 } else if (r.foregroundServices) { 9759 foreground = "S"; 9760 } else { 9761 foreground = " "; 9762 } 9763 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9764 prefix, (r.persistent ? persistentLabel : normalLabel), 9765 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9766 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9767 if (r.adjSource != null || r.adjTarget != null) { 9768 pw.print(prefix); 9769 pw.print(" "); 9770 if (r.adjTarget instanceof ComponentName) { 9771 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9772 } else if (r.adjTarget != null) { 9773 pw.print(r.adjTarget.toString()); 9774 } else { 9775 pw.print("{null}"); 9776 } 9777 pw.print("<="); 9778 if (r.adjSource instanceof ProcessRecord) { 9779 pw.print("Proc{"); 9780 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9781 pw.println("}"); 9782 } else if (r.adjSource != null) { 9783 pw.println(r.adjSource.toString()); 9784 } else { 9785 pw.println("{null}"); 9786 } 9787 } 9788 if (inclDetails) { 9789 pw.print(prefix); 9790 pw.print(" "); 9791 pw.print("oom: max="); pw.print(r.maxAdj); 9792 pw.print(" hidden="); pw.print(r.hiddenAdj); 9793 pw.print(" empty="); pw.print(r.emptyAdj); 9794 pw.print(" curRaw="); pw.print(r.curRawAdj); 9795 pw.print(" setRaw="); pw.print(r.setRawAdj); 9796 pw.print(" cur="); pw.print(r.curAdj); 9797 pw.print(" set="); pw.println(r.setAdj); 9798 pw.print(prefix); 9799 pw.print(" "); 9800 pw.print("keeping="); pw.print(r.keeping); 9801 pw.print(" hidden="); pw.print(r.hidden); 9802 pw.print(" empty="); pw.print(r.empty); 9803 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9804 9805 if (!r.keeping) { 9806 if (r.lastWakeTime != 0) { 9807 long wtime; 9808 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9809 synchronized (stats) { 9810 wtime = stats.getProcessWakeTime(r.info.uid, 9811 r.pid, curRealtime); 9812 } 9813 long timeUsed = wtime - r.lastWakeTime; 9814 pw.print(prefix); 9815 pw.print(" "); 9816 pw.print("keep awake over "); 9817 TimeUtils.formatDuration(realtimeSince, pw); 9818 pw.print(" used "); 9819 TimeUtils.formatDuration(timeUsed, pw); 9820 pw.print(" ("); 9821 pw.print((timeUsed*100)/realtimeSince); 9822 pw.println("%)"); 9823 } 9824 if (r.lastCpuTime != 0) { 9825 long timeUsed = r.curCpuTime - r.lastCpuTime; 9826 pw.print(prefix); 9827 pw.print(" "); 9828 pw.print("run cpu over "); 9829 TimeUtils.formatDuration(uptimeSince, pw); 9830 pw.print(" used "); 9831 TimeUtils.formatDuration(timeUsed, pw); 9832 pw.print(" ("); 9833 pw.print((timeUsed*100)/uptimeSince); 9834 pw.println("%)"); 9835 } 9836 } 9837 } 9838 } 9839 return true; 9840 } 9841 9842 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9843 ArrayList<ProcessRecord> procs; 9844 synchronized (this) { 9845 if (args != null && args.length > start 9846 && args[start].charAt(0) != '-') { 9847 procs = new ArrayList<ProcessRecord>(); 9848 int pid = -1; 9849 try { 9850 pid = Integer.parseInt(args[start]); 9851 } catch (NumberFormatException e) { 9852 9853 } 9854 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9855 ProcessRecord proc = mLruProcesses.get(i); 9856 if (proc.pid == pid) { 9857 procs.add(proc); 9858 } else if (proc.processName.equals(args[start])) { 9859 procs.add(proc); 9860 } 9861 } 9862 if (procs.size() <= 0) { 9863 pw.println("No process found for: " + args[start]); 9864 return null; 9865 } 9866 } else { 9867 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9868 } 9869 } 9870 return procs; 9871 } 9872 9873 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9874 PrintWriter pw, String[] args) { 9875 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9876 if (procs == null) { 9877 return; 9878 } 9879 9880 long uptime = SystemClock.uptimeMillis(); 9881 long realtime = SystemClock.elapsedRealtime(); 9882 pw.println("Applications Graphics Acceleration Info:"); 9883 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9884 9885 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9886 ProcessRecord r = procs.get(i); 9887 if (r.thread != null) { 9888 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9889 pw.flush(); 9890 try { 9891 TransferPipe tp = new TransferPipe(); 9892 try { 9893 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9894 tp.go(fd); 9895 } finally { 9896 tp.kill(); 9897 } 9898 } catch (IOException e) { 9899 pw.println("Failure while dumping the app: " + r); 9900 pw.flush(); 9901 } catch (RemoteException e) { 9902 pw.println("Got a RemoteException while dumping the app " + r); 9903 pw.flush(); 9904 } 9905 } 9906 } 9907 } 9908 9909 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9910 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9911 if (procs == null) { 9912 return; 9913 } 9914 9915 pw.println("Applications Database Info:"); 9916 9917 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9918 ProcessRecord r = procs.get(i); 9919 if (r.thread != null) { 9920 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9921 pw.flush(); 9922 try { 9923 TransferPipe tp = new TransferPipe(); 9924 try { 9925 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9926 tp.go(fd); 9927 } finally { 9928 tp.kill(); 9929 } 9930 } catch (IOException e) { 9931 pw.println("Failure while dumping the app: " + r); 9932 pw.flush(); 9933 } catch (RemoteException e) { 9934 pw.println("Got a RemoteException while dumping the app " + r); 9935 pw.flush(); 9936 } 9937 } 9938 } 9939 } 9940 9941 final static class MemItem { 9942 final String label; 9943 final String shortLabel; 9944 final long pss; 9945 final int id; 9946 ArrayList<MemItem> subitems; 9947 9948 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9949 label = _label; 9950 shortLabel = _shortLabel; 9951 pss = _pss; 9952 id = _id; 9953 } 9954 } 9955 9956 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9957 boolean sort) { 9958 if (sort) { 9959 Collections.sort(items, new Comparator<MemItem>() { 9960 @Override 9961 public int compare(MemItem lhs, MemItem rhs) { 9962 if (lhs.pss < rhs.pss) { 9963 return 1; 9964 } else if (lhs.pss > rhs.pss) { 9965 return -1; 9966 } 9967 return 0; 9968 } 9969 }); 9970 } 9971 9972 for (int i=0; i<items.size(); i++) { 9973 MemItem mi = items.get(i); 9974 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9975 if (mi.subitems != null) { 9976 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9977 } 9978 } 9979 } 9980 9981 // These are in KB. 9982 static final long[] DUMP_MEM_BUCKETS = new long[] { 9983 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9984 120*1024, 160*1024, 200*1024, 9985 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9986 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9987 }; 9988 9989 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9990 boolean stackLike) { 9991 int start = label.lastIndexOf('.'); 9992 if (start >= 0) start++; 9993 else start = 0; 9994 int end = label.length(); 9995 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9996 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9997 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9998 out.append(bucket); 9999 out.append(stackLike ? "MB." : "MB "); 10000 out.append(label, start, end); 10001 return; 10002 } 10003 } 10004 out.append(memKB/1024); 10005 out.append(stackLike ? "MB." : "MB "); 10006 out.append(label, start, end); 10007 } 10008 10009 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10010 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10011 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10012 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10013 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10014 }; 10015 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10016 "System", "Persistent", "Foreground", 10017 "Visible", "Perceptible", "Heavy Weight", 10018 "Backup", "A Services", "Home", "Previous", 10019 "B Services", "Background" 10020 }; 10021 10022 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10023 PrintWriter pw, String prefix, String[] args, boolean brief, 10024 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10025 boolean dumpAll = false; 10026 boolean oomOnly = false; 10027 10028 int opti = 0; 10029 while (opti < args.length) { 10030 String opt = args[opti]; 10031 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10032 break; 10033 } 10034 opti++; 10035 if ("-a".equals(opt)) { 10036 dumpAll = true; 10037 } else if ("--oom".equals(opt)) { 10038 oomOnly = true; 10039 } else if ("-h".equals(opt)) { 10040 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10041 pw.println(" -a: include all available information for each process."); 10042 pw.println(" --oom: only show processes organized by oom adj."); 10043 pw.println("If [process] is specified it can be the name or "); 10044 pw.println("pid of a specific process to dump."); 10045 return; 10046 } else { 10047 pw.println("Unknown argument: " + opt + "; use -h for help"); 10048 } 10049 } 10050 10051 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10052 if (procs == null) { 10053 return; 10054 } 10055 10056 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10057 long uptime = SystemClock.uptimeMillis(); 10058 long realtime = SystemClock.elapsedRealtime(); 10059 10060 if (procs.size() == 1 || isCheckinRequest) { 10061 dumpAll = true; 10062 } 10063 10064 if (isCheckinRequest) { 10065 // short checkin version 10066 pw.println(uptime + "," + realtime); 10067 pw.flush(); 10068 } else { 10069 pw.println("Applications Memory Usage (kB):"); 10070 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10071 } 10072 10073 String[] innerArgs = new String[args.length-opti]; 10074 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10075 10076 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10077 long nativePss=0, dalvikPss=0, otherPss=0; 10078 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10079 10080 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10081 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10082 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10083 10084 long totalPss = 0; 10085 10086 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10087 ProcessRecord r = procs.get(i); 10088 if (r.thread != null) { 10089 if (!isCheckinRequest && dumpAll) { 10090 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10091 pw.flush(); 10092 } 10093 Debug.MemoryInfo mi = null; 10094 if (dumpAll) { 10095 try { 10096 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10097 } catch (RemoteException e) { 10098 if (!isCheckinRequest) { 10099 pw.println("Got RemoteException!"); 10100 pw.flush(); 10101 } 10102 } 10103 } else { 10104 mi = new Debug.MemoryInfo(); 10105 Debug.getMemoryInfo(r.pid, mi); 10106 } 10107 10108 if (!isCheckinRequest && mi != null) { 10109 long myTotalPss = mi.getTotalPss(); 10110 totalPss += myTotalPss; 10111 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10112 r.processName, myTotalPss, 0); 10113 procMems.add(pssItem); 10114 10115 nativePss += mi.nativePss; 10116 dalvikPss += mi.dalvikPss; 10117 otherPss += mi.otherPss; 10118 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10119 long mem = mi.getOtherPss(j); 10120 miscPss[j] += mem; 10121 otherPss -= mem; 10122 } 10123 10124 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10125 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10126 || oomIndex == (oomPss.length-1)) { 10127 oomPss[oomIndex] += myTotalPss; 10128 if (oomProcs[oomIndex] == null) { 10129 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10130 } 10131 oomProcs[oomIndex].add(pssItem); 10132 break; 10133 } 10134 } 10135 } 10136 } 10137 } 10138 10139 if (!isCheckinRequest && procs.size() > 1) { 10140 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10141 10142 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10143 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10144 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10145 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10146 String label = Debug.MemoryInfo.getOtherLabel(j); 10147 catMems.add(new MemItem(label, label, miscPss[j], j)); 10148 } 10149 10150 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10151 for (int j=0; j<oomPss.length; j++) { 10152 if (oomPss[j] != 0) { 10153 String label = DUMP_MEM_OOM_LABEL[j]; 10154 MemItem item = new MemItem(label, label, oomPss[j], 10155 DUMP_MEM_OOM_ADJ[j]); 10156 item.subitems = oomProcs[j]; 10157 oomMems.add(item); 10158 } 10159 } 10160 10161 if (outTag != null || outStack != null) { 10162 if (outTag != null) { 10163 appendMemBucket(outTag, totalPss, "total", false); 10164 } 10165 if (outStack != null) { 10166 appendMemBucket(outStack, totalPss, "total", true); 10167 } 10168 boolean firstLine = true; 10169 for (int i=0; i<oomMems.size(); i++) { 10170 MemItem miCat = oomMems.get(i); 10171 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10172 continue; 10173 } 10174 if (miCat.id < ProcessList.SERVICE_ADJ 10175 || miCat.id == ProcessList.HOME_APP_ADJ 10176 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10177 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10178 outTag.append(" / "); 10179 } 10180 if (outStack != null) { 10181 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10182 if (firstLine) { 10183 outStack.append(":"); 10184 firstLine = false; 10185 } 10186 outStack.append("\n\t at "); 10187 } else { 10188 outStack.append("$"); 10189 } 10190 } 10191 for (int j=0; j<miCat.subitems.size(); j++) { 10192 MemItem mi = miCat.subitems.get(j); 10193 if (j > 0) { 10194 if (outTag != null) { 10195 outTag.append(" "); 10196 } 10197 if (outStack != null) { 10198 outStack.append("$"); 10199 } 10200 } 10201 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10202 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10203 } 10204 if (outStack != null) { 10205 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10206 } 10207 } 10208 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10209 outStack.append("("); 10210 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10211 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10212 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10213 outStack.append(":"); 10214 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10215 } 10216 } 10217 outStack.append(")"); 10218 } 10219 } 10220 } 10221 } 10222 10223 if (!brief && !oomOnly) { 10224 pw.println(); 10225 pw.println("Total PSS by process:"); 10226 dumpMemItems(pw, " ", procMems, true); 10227 pw.println(); 10228 } 10229 pw.println("Total PSS by OOM adjustment:"); 10230 dumpMemItems(pw, " ", oomMems, false); 10231 if (!oomOnly) { 10232 PrintWriter out = categoryPw != null ? categoryPw : pw; 10233 out.println(); 10234 out.println("Total PSS by category:"); 10235 dumpMemItems(out, " ", catMems, true); 10236 } 10237 pw.println(); 10238 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10239 final int[] SINGLE_LONG_FORMAT = new int[] { 10240 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10241 }; 10242 long[] longOut = new long[1]; 10243 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10244 SINGLE_LONG_FORMAT, null, longOut, null); 10245 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10246 longOut[0] = 0; 10247 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10248 SINGLE_LONG_FORMAT, null, longOut, null); 10249 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10250 longOut[0] = 0; 10251 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10252 SINGLE_LONG_FORMAT, null, longOut, null); 10253 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10254 longOut[0] = 0; 10255 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10256 SINGLE_LONG_FORMAT, null, longOut, null); 10257 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10258 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10259 pw.print(shared); pw.println(" kB"); 10260 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10261 pw.print(voltile); pw.println(" kB volatile"); 10262 } 10263 } 10264 10265 /** 10266 * Searches array of arguments for the specified string 10267 * @param args array of argument strings 10268 * @param value value to search for 10269 * @return true if the value is contained in the array 10270 */ 10271 private static boolean scanArgs(String[] args, String value) { 10272 if (args != null) { 10273 for (String arg : args) { 10274 if (value.equals(arg)) { 10275 return true; 10276 } 10277 } 10278 } 10279 return false; 10280 } 10281 10282 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10283 ContentProviderRecord cpr, boolean always) { 10284 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10285 10286 if (!inLaunching || always) { 10287 synchronized (cpr) { 10288 cpr.launchingApp = null; 10289 cpr.notifyAll(); 10290 } 10291 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10292 String names[] = cpr.info.authority.split(";"); 10293 for (int j = 0; j < names.length; j++) { 10294 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10295 } 10296 } 10297 10298 for (int i=0; i<cpr.connections.size(); i++) { 10299 ContentProviderConnection conn = cpr.connections.get(i); 10300 if (conn.waiting) { 10301 // If this connection is waiting for the provider, then we don't 10302 // need to mess with its process unless we are always removing 10303 // or for some reason the provider is not currently launching. 10304 if (inLaunching && !always) { 10305 continue; 10306 } 10307 } 10308 ProcessRecord capp = conn.client; 10309 conn.dead = true; 10310 if (conn.stableCount > 0) { 10311 if (!capp.persistent && capp.thread != null 10312 && capp.pid != 0 10313 && capp.pid != MY_PID) { 10314 Slog.i(TAG, "Kill " + capp.processName 10315 + " (pid " + capp.pid + "): provider " + cpr.info.name 10316 + " in dying process " + (proc != null ? proc.processName : "??")); 10317 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10318 capp.processName, capp.setAdj, "dying provider " 10319 + cpr.name.toShortString()); 10320 Process.killProcessQuiet(capp.pid); 10321 } 10322 } else if (capp.thread != null && conn.provider.provider != null) { 10323 try { 10324 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10325 } catch (RemoteException e) { 10326 } 10327 // In the protocol here, we don't expect the client to correctly 10328 // clean up this connection, we'll just remove it. 10329 cpr.connections.remove(i); 10330 conn.client.conProviders.remove(conn); 10331 } 10332 } 10333 10334 if (inLaunching && always) { 10335 mLaunchingProviders.remove(cpr); 10336 } 10337 return inLaunching; 10338 } 10339 10340 /** 10341 * Main code for cleaning up a process when it has gone away. This is 10342 * called both as a result of the process dying, or directly when stopping 10343 * a process when running in single process mode. 10344 */ 10345 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10346 boolean restarting, boolean allowRestart, int index) { 10347 if (index >= 0) { 10348 mLruProcesses.remove(index); 10349 } 10350 10351 mProcessesToGc.remove(app); 10352 10353 // Dismiss any open dialogs. 10354 if (app.crashDialog != null) { 10355 app.crashDialog.dismiss(); 10356 app.crashDialog = null; 10357 } 10358 if (app.anrDialog != null) { 10359 app.anrDialog.dismiss(); 10360 app.anrDialog = null; 10361 } 10362 if (app.waitDialog != null) { 10363 app.waitDialog.dismiss(); 10364 app.waitDialog = null; 10365 } 10366 10367 app.crashing = false; 10368 app.notResponding = false; 10369 10370 app.resetPackageList(); 10371 app.unlinkDeathRecipient(); 10372 app.thread = null; 10373 app.forcingToForeground = null; 10374 app.foregroundServices = false; 10375 app.foregroundActivities = false; 10376 app.hasShownUi = false; 10377 app.hasAboveClient = false; 10378 10379 mServices.killServicesLocked(app, allowRestart); 10380 10381 boolean restart = false; 10382 10383 // Remove published content providers. 10384 if (!app.pubProviders.isEmpty()) { 10385 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10386 while (it.hasNext()) { 10387 ContentProviderRecord cpr = it.next(); 10388 10389 final boolean always = app.bad || !allowRestart; 10390 if (removeDyingProviderLocked(app, cpr, always) || always) { 10391 // We left the provider in the launching list, need to 10392 // restart it. 10393 restart = true; 10394 } 10395 10396 cpr.provider = null; 10397 cpr.proc = null; 10398 } 10399 app.pubProviders.clear(); 10400 } 10401 10402 // Take care of any launching providers waiting for this process. 10403 if (checkAppInLaunchingProvidersLocked(app, false)) { 10404 restart = true; 10405 } 10406 10407 // Unregister from connected content providers. 10408 if (!app.conProviders.isEmpty()) { 10409 for (int i=0; i<app.conProviders.size(); i++) { 10410 ContentProviderConnection conn = app.conProviders.get(i); 10411 conn.provider.connections.remove(conn); 10412 } 10413 app.conProviders.clear(); 10414 } 10415 10416 // At this point there may be remaining entries in mLaunchingProviders 10417 // where we were the only one waiting, so they are no longer of use. 10418 // Look for these and clean up if found. 10419 // XXX Commented out for now. Trying to figure out a way to reproduce 10420 // the actual situation to identify what is actually going on. 10421 if (false) { 10422 for (int i=0; i<mLaunchingProviders.size(); i++) { 10423 ContentProviderRecord cpr = (ContentProviderRecord) 10424 mLaunchingProviders.get(i); 10425 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10426 synchronized (cpr) { 10427 cpr.launchingApp = null; 10428 cpr.notifyAll(); 10429 } 10430 } 10431 } 10432 } 10433 10434 skipCurrentReceiverLocked(app); 10435 10436 // Unregister any receivers. 10437 if (app.receivers.size() > 0) { 10438 Iterator<ReceiverList> it = app.receivers.iterator(); 10439 while (it.hasNext()) { 10440 removeReceiverLocked(it.next()); 10441 } 10442 app.receivers.clear(); 10443 } 10444 10445 // If the app is undergoing backup, tell the backup manager about it 10446 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10447 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10448 try { 10449 IBackupManager bm = IBackupManager.Stub.asInterface( 10450 ServiceManager.getService(Context.BACKUP_SERVICE)); 10451 bm.agentDisconnected(app.info.packageName); 10452 } catch (RemoteException e) { 10453 // can't happen; backup manager is local 10454 } 10455 } 10456 10457 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10458 ProcessChangeItem item = mPendingProcessChanges.get(i); 10459 if (item.pid == app.pid) { 10460 mPendingProcessChanges.remove(i); 10461 mAvailProcessChanges.add(item); 10462 } 10463 } 10464 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10465 10466 // If the caller is restarting this app, then leave it in its 10467 // current lists and let the caller take care of it. 10468 if (restarting) { 10469 return; 10470 } 10471 10472 if (!app.persistent || app.isolated) { 10473 if (DEBUG_PROCESSES) Slog.v(TAG, 10474 "Removing non-persistent process during cleanup: " + app); 10475 mProcessNames.remove(app.processName, app.uid); 10476 mIsolatedProcesses.remove(app.uid); 10477 if (mHeavyWeightProcess == app) { 10478 mHeavyWeightProcess = null; 10479 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10480 } 10481 } else if (!app.removed) { 10482 // This app is persistent, so we need to keep its record around. 10483 // If it is not already on the pending app list, add it there 10484 // and start a new process for it. 10485 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10486 mPersistentStartingProcesses.add(app); 10487 restart = true; 10488 } 10489 } 10490 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10491 "Clean-up removing on hold: " + app); 10492 mProcessesOnHold.remove(app); 10493 10494 if (app == mHomeProcess) { 10495 mHomeProcess = null; 10496 } 10497 if (app == mPreviousProcess) { 10498 mPreviousProcess = null; 10499 } 10500 10501 if (restart && !app.isolated) { 10502 // We have components that still need to be running in the 10503 // process, so re-launch it. 10504 mProcessNames.put(app.processName, app.uid, app); 10505 startProcessLocked(app, "restart", app.processName); 10506 } else if (app.pid > 0 && app.pid != MY_PID) { 10507 // Goodbye! 10508 synchronized (mPidsSelfLocked) { 10509 mPidsSelfLocked.remove(app.pid); 10510 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10511 } 10512 app.setPid(0); 10513 } 10514 } 10515 10516 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10517 // Look through the content providers we are waiting to have launched, 10518 // and if any run in this process then either schedule a restart of 10519 // the process or kill the client waiting for it if this process has 10520 // gone bad. 10521 int NL = mLaunchingProviders.size(); 10522 boolean restart = false; 10523 for (int i=0; i<NL; i++) { 10524 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10525 if (cpr.launchingApp == app) { 10526 if (!alwaysBad && !app.bad) { 10527 restart = true; 10528 } else { 10529 removeDyingProviderLocked(app, cpr, true); 10530 NL = mLaunchingProviders.size(); 10531 } 10532 } 10533 } 10534 return restart; 10535 } 10536 10537 // ========================================================= 10538 // SERVICES 10539 // ========================================================= 10540 10541 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10542 int flags) { 10543 enforceNotIsolatedCaller("getServices"); 10544 synchronized (this) { 10545 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10546 } 10547 } 10548 10549 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10550 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10551 synchronized (this) { 10552 return mServices.getRunningServiceControlPanelLocked(name); 10553 } 10554 } 10555 10556 public ComponentName startService(IApplicationThread caller, Intent service, 10557 String resolvedType, int userId) { 10558 enforceNotIsolatedCaller("startService"); 10559 // Refuse possible leaked file descriptors 10560 if (service != null && service.hasFileDescriptors() == true) { 10561 throw new IllegalArgumentException("File descriptors passed in Intent"); 10562 } 10563 10564 if (DEBUG_SERVICE) 10565 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10566 synchronized(this) { 10567 final int callingPid = Binder.getCallingPid(); 10568 final int callingUid = Binder.getCallingUid(); 10569 checkValidCaller(callingUid, userId); 10570 final long origId = Binder.clearCallingIdentity(); 10571 ComponentName res = mServices.startServiceLocked(caller, service, 10572 resolvedType, callingPid, callingUid, userId); 10573 Binder.restoreCallingIdentity(origId); 10574 return res; 10575 } 10576 } 10577 10578 ComponentName startServiceInPackage(int uid, 10579 Intent service, String resolvedType) { 10580 synchronized(this) { 10581 if (DEBUG_SERVICE) 10582 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10583 final long origId = Binder.clearCallingIdentity(); 10584 ComponentName res = mServices.startServiceLocked(null, service, 10585 resolvedType, -1, uid, UserHandle.getUserId(uid)); 10586 Binder.restoreCallingIdentity(origId); 10587 return res; 10588 } 10589 } 10590 10591 public int stopService(IApplicationThread caller, Intent service, 10592 String resolvedType, int userId) { 10593 enforceNotIsolatedCaller("stopService"); 10594 // Refuse possible leaked file descriptors 10595 if (service != null && service.hasFileDescriptors() == true) { 10596 throw new IllegalArgumentException("File descriptors passed in Intent"); 10597 } 10598 10599 checkValidCaller(Binder.getCallingUid(), userId); 10600 10601 synchronized(this) { 10602 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10603 } 10604 } 10605 10606 public IBinder peekService(Intent service, String resolvedType) { 10607 enforceNotIsolatedCaller("peekService"); 10608 // Refuse possible leaked file descriptors 10609 if (service != null && service.hasFileDescriptors() == true) { 10610 throw new IllegalArgumentException("File descriptors passed in Intent"); 10611 } 10612 synchronized(this) { 10613 return mServices.peekServiceLocked(service, resolvedType); 10614 } 10615 } 10616 10617 public boolean stopServiceToken(ComponentName className, IBinder token, 10618 int startId) { 10619 synchronized(this) { 10620 return mServices.stopServiceTokenLocked(className, token, startId); 10621 } 10622 } 10623 10624 public void setServiceForeground(ComponentName className, IBinder token, 10625 int id, Notification notification, boolean removeNotification) { 10626 synchronized(this) { 10627 mServices.setServiceForegroundLocked(className, token, id, notification, 10628 removeNotification); 10629 } 10630 } 10631 10632 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10633 String className, int flags) { 10634 boolean result = false; 10635 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10636 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10637 if (ActivityManager.checkUidPermission( 10638 android.Manifest.permission.INTERACT_ACROSS_USERS, 10639 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10640 ComponentName comp = new ComponentName(aInfo.packageName, className); 10641 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10642 + " requests FLAG_SINGLE_USER, but app does not hold " 10643 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10644 Slog.w(TAG, msg); 10645 throw new SecurityException(msg); 10646 } 10647 result = true; 10648 } 10649 } else if (componentProcessName == aInfo.packageName) { 10650 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10651 } else if ("system".equals(componentProcessName)) { 10652 result = true; 10653 } 10654 if (DEBUG_MU) { 10655 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10656 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10657 } 10658 return result; 10659 } 10660 10661 public int bindService(IApplicationThread caller, IBinder token, 10662 Intent service, String resolvedType, 10663 IServiceConnection connection, int flags, int userId) { 10664 enforceNotIsolatedCaller("bindService"); 10665 // Refuse possible leaked file descriptors 10666 if (service != null && service.hasFileDescriptors() == true) { 10667 throw new IllegalArgumentException("File descriptors passed in Intent"); 10668 } 10669 10670 checkValidCaller(Binder.getCallingUid(), userId); 10671 10672 synchronized(this) { 10673 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10674 connection, flags, userId); 10675 } 10676 } 10677 10678 public boolean unbindService(IServiceConnection connection) { 10679 synchronized (this) { 10680 return mServices.unbindServiceLocked(connection); 10681 } 10682 } 10683 10684 public void publishService(IBinder token, Intent intent, IBinder service) { 10685 // Refuse possible leaked file descriptors 10686 if (intent != null && intent.hasFileDescriptors() == true) { 10687 throw new IllegalArgumentException("File descriptors passed in Intent"); 10688 } 10689 10690 synchronized(this) { 10691 if (!(token instanceof ServiceRecord)) { 10692 throw new IllegalArgumentException("Invalid service token"); 10693 } 10694 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10695 } 10696 } 10697 10698 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10699 // Refuse possible leaked file descriptors 10700 if (intent != null && intent.hasFileDescriptors() == true) { 10701 throw new IllegalArgumentException("File descriptors passed in Intent"); 10702 } 10703 10704 synchronized(this) { 10705 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10706 } 10707 } 10708 10709 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10710 synchronized(this) { 10711 if (!(token instanceof ServiceRecord)) { 10712 throw new IllegalArgumentException("Invalid service token"); 10713 } 10714 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10715 } 10716 } 10717 10718 // ========================================================= 10719 // BACKUP AND RESTORE 10720 // ========================================================= 10721 10722 // Cause the target app to be launched if necessary and its backup agent 10723 // instantiated. The backup agent will invoke backupAgentCreated() on the 10724 // activity manager to announce its creation. 10725 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10726 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10727 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10728 10729 synchronized(this) { 10730 // !!! TODO: currently no check here that we're already bound 10731 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10732 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10733 synchronized (stats) { 10734 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10735 } 10736 10737 // Backup agent is now in use, its package can't be stopped. 10738 try { 10739 AppGlobals.getPackageManager().setPackageStoppedState( 10740 app.packageName, false, UserHandle.getUserId(app.uid)); 10741 } catch (RemoteException e) { 10742 } catch (IllegalArgumentException e) { 10743 Slog.w(TAG, "Failed trying to unstop package " 10744 + app.packageName + ": " + e); 10745 } 10746 10747 BackupRecord r = new BackupRecord(ss, app, backupMode); 10748 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10749 ? new ComponentName(app.packageName, app.backupAgentName) 10750 : new ComponentName("android", "FullBackupAgent"); 10751 // startProcessLocked() returns existing proc's record if it's already running 10752 ProcessRecord proc = startProcessLocked(app.processName, app, 10753 false, 0, "backup", hostingName, false, false); 10754 if (proc == null) { 10755 Slog.e(TAG, "Unable to start backup agent process " + r); 10756 return false; 10757 } 10758 10759 r.app = proc; 10760 mBackupTarget = r; 10761 mBackupAppName = app.packageName; 10762 10763 // Try not to kill the process during backup 10764 updateOomAdjLocked(proc); 10765 10766 // If the process is already attached, schedule the creation of the backup agent now. 10767 // If it is not yet live, this will be done when it attaches to the framework. 10768 if (proc.thread != null) { 10769 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10770 try { 10771 proc.thread.scheduleCreateBackupAgent(app, 10772 compatibilityInfoForPackageLocked(app), backupMode); 10773 } catch (RemoteException e) { 10774 // Will time out on the backup manager side 10775 } 10776 } else { 10777 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10778 } 10779 // Invariants: at this point, the target app process exists and the application 10780 // is either already running or in the process of coming up. mBackupTarget and 10781 // mBackupAppName describe the app, so that when it binds back to the AM we 10782 // know that it's scheduled for a backup-agent operation. 10783 } 10784 10785 return true; 10786 } 10787 10788 // A backup agent has just come up 10789 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10790 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10791 + " = " + agent); 10792 10793 synchronized(this) { 10794 if (!agentPackageName.equals(mBackupAppName)) { 10795 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10796 return; 10797 } 10798 } 10799 10800 long oldIdent = Binder.clearCallingIdentity(); 10801 try { 10802 IBackupManager bm = IBackupManager.Stub.asInterface( 10803 ServiceManager.getService(Context.BACKUP_SERVICE)); 10804 bm.agentConnected(agentPackageName, agent); 10805 } catch (RemoteException e) { 10806 // can't happen; the backup manager service is local 10807 } catch (Exception e) { 10808 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10809 e.printStackTrace(); 10810 } finally { 10811 Binder.restoreCallingIdentity(oldIdent); 10812 } 10813 } 10814 10815 // done with this agent 10816 public void unbindBackupAgent(ApplicationInfo appInfo) { 10817 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10818 if (appInfo == null) { 10819 Slog.w(TAG, "unbind backup agent for null app"); 10820 return; 10821 } 10822 10823 synchronized(this) { 10824 if (mBackupAppName == null) { 10825 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10826 return; 10827 } 10828 10829 if (!mBackupAppName.equals(appInfo.packageName)) { 10830 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10831 return; 10832 } 10833 10834 ProcessRecord proc = mBackupTarget.app; 10835 mBackupTarget = null; 10836 mBackupAppName = null; 10837 10838 // Not backing this app up any more; reset its OOM adjustment 10839 updateOomAdjLocked(proc); 10840 10841 // If the app crashed during backup, 'thread' will be null here 10842 if (proc.thread != null) { 10843 try { 10844 proc.thread.scheduleDestroyBackupAgent(appInfo, 10845 compatibilityInfoForPackageLocked(appInfo)); 10846 } catch (Exception e) { 10847 Slog.e(TAG, "Exception when unbinding backup agent:"); 10848 e.printStackTrace(); 10849 } 10850 } 10851 } 10852 } 10853 // ========================================================= 10854 // BROADCASTS 10855 // ========================================================= 10856 10857 private final List getStickiesLocked(String action, IntentFilter filter, 10858 List cur) { 10859 final ContentResolver resolver = mContext.getContentResolver(); 10860 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10861 if (list == null) { 10862 return cur; 10863 } 10864 int N = list.size(); 10865 for (int i=0; i<N; i++) { 10866 Intent intent = list.get(i); 10867 if (filter.match(resolver, intent, true, TAG) >= 0) { 10868 if (cur == null) { 10869 cur = new ArrayList<Intent>(); 10870 } 10871 cur.add(intent); 10872 } 10873 } 10874 return cur; 10875 } 10876 10877 boolean isPendingBroadcastProcessLocked(int pid) { 10878 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10879 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10880 } 10881 10882 void skipPendingBroadcastLocked(int pid) { 10883 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10884 for (BroadcastQueue queue : mBroadcastQueues) { 10885 queue.skipPendingBroadcastLocked(pid); 10886 } 10887 } 10888 10889 // The app just attached; send any pending broadcasts that it should receive 10890 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10891 boolean didSomething = false; 10892 for (BroadcastQueue queue : mBroadcastQueues) { 10893 didSomething |= queue.sendPendingBroadcastsLocked(app); 10894 } 10895 return didSomething; 10896 } 10897 10898 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10899 IIntentReceiver receiver, IntentFilter filter, String permission) { 10900 enforceNotIsolatedCaller("registerReceiver"); 10901 int callingUid; 10902 synchronized(this) { 10903 ProcessRecord callerApp = null; 10904 if (caller != null) { 10905 callerApp = getRecordForAppLocked(caller); 10906 if (callerApp == null) { 10907 throw new SecurityException( 10908 "Unable to find app for caller " + caller 10909 + " (pid=" + Binder.getCallingPid() 10910 + ") when registering receiver " + receiver); 10911 } 10912 if (callerApp.info.uid != Process.SYSTEM_UID && 10913 !callerApp.pkgList.contains(callerPackage)) { 10914 throw new SecurityException("Given caller package " + callerPackage 10915 + " is not running in process " + callerApp); 10916 } 10917 callingUid = callerApp.info.uid; 10918 } else { 10919 callerPackage = null; 10920 callingUid = Binder.getCallingUid(); 10921 } 10922 10923 List allSticky = null; 10924 10925 // Look for any matching sticky broadcasts... 10926 Iterator actions = filter.actionsIterator(); 10927 if (actions != null) { 10928 while (actions.hasNext()) { 10929 String action = (String)actions.next(); 10930 allSticky = getStickiesLocked(action, filter, allSticky); 10931 } 10932 } else { 10933 allSticky = getStickiesLocked(null, filter, allSticky); 10934 } 10935 10936 // The first sticky in the list is returned directly back to 10937 // the client. 10938 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10939 10940 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10941 + ": " + sticky); 10942 10943 if (receiver == null) { 10944 return sticky; 10945 } 10946 10947 ReceiverList rl 10948 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10949 if (rl == null) { 10950 rl = new ReceiverList(this, callerApp, 10951 Binder.getCallingPid(), 10952 Binder.getCallingUid(), receiver); 10953 if (rl.app != null) { 10954 rl.app.receivers.add(rl); 10955 } else { 10956 try { 10957 receiver.asBinder().linkToDeath(rl, 0); 10958 } catch (RemoteException e) { 10959 return sticky; 10960 } 10961 rl.linkedToDeath = true; 10962 } 10963 mRegisteredReceivers.put(receiver.asBinder(), rl); 10964 } 10965 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10966 permission, callingUid); 10967 rl.add(bf); 10968 if (!bf.debugCheck()) { 10969 Slog.w(TAG, "==> For Dynamic broadast"); 10970 } 10971 mReceiverResolver.addFilter(bf); 10972 10973 // Enqueue broadcasts for all existing stickies that match 10974 // this filter. 10975 if (allSticky != null) { 10976 ArrayList receivers = new ArrayList(); 10977 receivers.add(bf); 10978 10979 int N = allSticky.size(); 10980 for (int i=0; i<N; i++) { 10981 Intent intent = (Intent)allSticky.get(i); 10982 BroadcastQueue queue = broadcastQueueForIntent(intent); 10983 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10984 null, -1, -1, null, receivers, null, 0, null, null, 10985 false, true, true, false); 10986 queue.enqueueParallelBroadcastLocked(r); 10987 queue.scheduleBroadcastsLocked(); 10988 } 10989 } 10990 10991 return sticky; 10992 } 10993 } 10994 10995 public void unregisterReceiver(IIntentReceiver receiver) { 10996 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10997 10998 final long origId = Binder.clearCallingIdentity(); 10999 try { 11000 boolean doTrim = false; 11001 11002 synchronized(this) { 11003 ReceiverList rl 11004 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11005 if (rl != null) { 11006 if (rl.curBroadcast != null) { 11007 BroadcastRecord r = rl.curBroadcast; 11008 final boolean doNext = finishReceiverLocked( 11009 receiver.asBinder(), r.resultCode, r.resultData, 11010 r.resultExtras, r.resultAbort, true); 11011 if (doNext) { 11012 doTrim = true; 11013 r.queue.processNextBroadcast(false); 11014 } 11015 } 11016 11017 if (rl.app != null) { 11018 rl.app.receivers.remove(rl); 11019 } 11020 removeReceiverLocked(rl); 11021 if (rl.linkedToDeath) { 11022 rl.linkedToDeath = false; 11023 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11024 } 11025 } 11026 } 11027 11028 // If we actually concluded any broadcasts, we might now be able 11029 // to trim the recipients' apps from our working set 11030 if (doTrim) { 11031 trimApplications(); 11032 return; 11033 } 11034 11035 } finally { 11036 Binder.restoreCallingIdentity(origId); 11037 } 11038 } 11039 11040 void removeReceiverLocked(ReceiverList rl) { 11041 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11042 int N = rl.size(); 11043 for (int i=0; i<N; i++) { 11044 mReceiverResolver.removeFilter(rl.get(i)); 11045 } 11046 } 11047 11048 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11049 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11050 ProcessRecord r = mLruProcesses.get(i); 11051 if (r.thread != null) { 11052 try { 11053 r.thread.dispatchPackageBroadcast(cmd, packages); 11054 } catch (RemoteException ex) { 11055 } 11056 } 11057 } 11058 } 11059 11060 private final int broadcastIntentLocked(ProcessRecord callerApp, 11061 String callerPackage, Intent intent, String resolvedType, 11062 IIntentReceiver resultTo, int resultCode, String resultData, 11063 Bundle map, String requiredPermission, 11064 boolean ordered, boolean sticky, int callingPid, int callingUid, 11065 int userId) { 11066 intent = new Intent(intent); 11067 11068 // By default broadcasts do not go to stopped apps. 11069 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11070 11071 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11072 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11073 + " ordered=" + ordered + " userid=" + userId); 11074 if ((resultTo != null) && !ordered) { 11075 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11076 } 11077 11078 boolean onlySendToCaller = false; 11079 11080 // If the caller is trying to send this broadcast to a different 11081 // user, verify that is allowed. 11082 if (UserHandle.getUserId(callingUid) != userId) { 11083 if (checkComponentPermission( 11084 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11085 callingPid, callingUid, -1, true) 11086 != PackageManager.PERMISSION_GRANTED) { 11087 if (checkComponentPermission( 11088 android.Manifest.permission.INTERACT_ACROSS_USERS, 11089 callingPid, callingUid, -1, true) 11090 == PackageManager.PERMISSION_GRANTED) { 11091 onlySendToCaller = true; 11092 } else { 11093 String msg = "Permission Denial: " + intent.getAction() 11094 + " broadcast from " + callerPackage 11095 + " asks to send as user " + userId 11096 + " but is calling from user " + UserHandle.getUserId(callingUid) 11097 + "; this requires " 11098 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11099 Slog.w(TAG, msg); 11100 throw new SecurityException(msg); 11101 } 11102 } 11103 } 11104 11105 // Handle special intents: if this broadcast is from the package 11106 // manager about a package being removed, we need to remove all of 11107 // its activities from the history stack. 11108 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11109 intent.getAction()); 11110 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11111 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11112 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11113 || uidRemoved) { 11114 if (checkComponentPermission( 11115 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11116 callingPid, callingUid, -1, true) 11117 == PackageManager.PERMISSION_GRANTED) { 11118 if (uidRemoved) { 11119 final Bundle intentExtras = intent.getExtras(); 11120 final int uid = intentExtras != null 11121 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11122 if (uid >= 0) { 11123 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11124 synchronized (bs) { 11125 bs.removeUidStatsLocked(uid); 11126 } 11127 } 11128 } else { 11129 // If resources are unvailble just force stop all 11130 // those packages and flush the attribute cache as well. 11131 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11132 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11133 if (list != null && (list.length > 0)) { 11134 for (String pkg : list) { 11135 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11136 } 11137 sendPackageBroadcastLocked( 11138 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11139 } 11140 } else { 11141 Uri data = intent.getData(); 11142 String ssp; 11143 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11144 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11145 forceStopPackageLocked(ssp, 11146 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11147 false, userId); 11148 } 11149 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11150 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11151 new String[] {ssp}); 11152 } 11153 } 11154 } 11155 } 11156 } else { 11157 String msg = "Permission Denial: " + intent.getAction() 11158 + " broadcast from " + callerPackage + " (pid=" + callingPid 11159 + ", uid=" + callingUid + ")" 11160 + " requires " 11161 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11162 Slog.w(TAG, msg); 11163 throw new SecurityException(msg); 11164 } 11165 11166 // Special case for adding a package: by default turn on compatibility 11167 // mode. 11168 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11169 Uri data = intent.getData(); 11170 String ssp; 11171 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11172 mCompatModePackages.handlePackageAddedLocked(ssp, 11173 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11174 } 11175 } 11176 11177 /* 11178 * If this is the time zone changed action, queue up a message that will reset the timezone 11179 * of all currently running processes. This message will get queued up before the broadcast 11180 * happens. 11181 */ 11182 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11183 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11184 } 11185 11186 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11187 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11188 } 11189 11190 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11191 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11192 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11193 } 11194 11195 /* 11196 * Prevent non-system code (defined here to be non-persistent 11197 * processes) from sending protected broadcasts. 11198 */ 11199 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11200 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11201 callingUid == 0) { 11202 // Always okay. 11203 } else if (callerApp == null || !callerApp.persistent) { 11204 try { 11205 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11206 intent.getAction())) { 11207 String msg = "Permission Denial: not allowed to send broadcast " 11208 + intent.getAction() + " from pid=" 11209 + callingPid + ", uid=" + callingUid; 11210 Slog.w(TAG, msg); 11211 throw new SecurityException(msg); 11212 } 11213 } catch (RemoteException e) { 11214 Slog.w(TAG, "Remote exception", e); 11215 return ActivityManager.BROADCAST_SUCCESS; 11216 } 11217 } 11218 11219 // Add to the sticky list if requested. 11220 if (sticky) { 11221 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11222 callingPid, callingUid) 11223 != PackageManager.PERMISSION_GRANTED) { 11224 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11225 + callingPid + ", uid=" + callingUid 11226 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11227 Slog.w(TAG, msg); 11228 throw new SecurityException(msg); 11229 } 11230 if (requiredPermission != null) { 11231 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11232 + " and enforce permission " + requiredPermission); 11233 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11234 } 11235 if (intent.getComponent() != null) { 11236 throw new SecurityException( 11237 "Sticky broadcasts can't target a specific component"); 11238 } 11239 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11240 if (list == null) { 11241 list = new ArrayList<Intent>(); 11242 mStickyBroadcasts.put(intent.getAction(), list); 11243 } 11244 int N = list.size(); 11245 int i; 11246 for (i=0; i<N; i++) { 11247 if (intent.filterEquals(list.get(i))) { 11248 // This sticky already exists, replace it. 11249 list.set(i, new Intent(intent)); 11250 break; 11251 } 11252 } 11253 if (i >= N) { 11254 list.add(new Intent(intent)); 11255 } 11256 } 11257 11258 // Figure out who all will receive this broadcast. 11259 List receivers = null; 11260 List<BroadcastFilter> registeredReceivers = null; 11261 try { 11262 // Need to resolve the intent to interested receivers... 11263 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11264 == 0) { 11265 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11266 intent, resolvedType, STOCK_PM_FLAGS, userId); 11267 } 11268 if (intent.getComponent() == null) { 11269 registeredReceivers = mReceiverResolver.queryIntent(intent, 11270 resolvedType, false, userId); 11271 } 11272 } catch (RemoteException ex) { 11273 // pm is in same process, this will never happen. 11274 } 11275 11276 final boolean replacePending = 11277 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11278 11279 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11280 + " replacePending=" + replacePending); 11281 11282 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11283 if (!ordered && NR > 0) { 11284 // If we are not serializing this broadcast, then send the 11285 // registered receivers separately so they don't wait for the 11286 // components to be launched. 11287 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11288 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11289 callerPackage, callingPid, callingUid, requiredPermission, 11290 registeredReceivers, resultTo, resultCode, resultData, map, 11291 ordered, sticky, false, onlySendToCaller); 11292 if (DEBUG_BROADCAST) Slog.v( 11293 TAG, "Enqueueing parallel broadcast " + r); 11294 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11295 if (!replaced) { 11296 queue.enqueueParallelBroadcastLocked(r); 11297 queue.scheduleBroadcastsLocked(); 11298 } 11299 registeredReceivers = null; 11300 NR = 0; 11301 } 11302 11303 // Merge into one list. 11304 int ir = 0; 11305 if (receivers != null) { 11306 // A special case for PACKAGE_ADDED: do not allow the package 11307 // being added to see this broadcast. This prevents them from 11308 // using this as a back door to get run as soon as they are 11309 // installed. Maybe in the future we want to have a special install 11310 // broadcast or such for apps, but we'd like to deliberately make 11311 // this decision. 11312 String skipPackages[] = null; 11313 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11314 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11315 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11316 Uri data = intent.getData(); 11317 if (data != null) { 11318 String pkgName = data.getSchemeSpecificPart(); 11319 if (pkgName != null) { 11320 skipPackages = new String[] { pkgName }; 11321 } 11322 } 11323 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11324 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11325 } 11326 if (skipPackages != null && (skipPackages.length > 0)) { 11327 for (String skipPackage : skipPackages) { 11328 if (skipPackage != null) { 11329 int NT = receivers.size(); 11330 for (int it=0; it<NT; it++) { 11331 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11332 if (curt.activityInfo.packageName.equals(skipPackage)) { 11333 receivers.remove(it); 11334 it--; 11335 NT--; 11336 } 11337 } 11338 } 11339 } 11340 } 11341 11342 int NT = receivers != null ? receivers.size() : 0; 11343 int it = 0; 11344 ResolveInfo curt = null; 11345 BroadcastFilter curr = null; 11346 while (it < NT && ir < NR) { 11347 if (curt == null) { 11348 curt = (ResolveInfo)receivers.get(it); 11349 } 11350 if (curr == null) { 11351 curr = registeredReceivers.get(ir); 11352 } 11353 if (curr.getPriority() >= curt.priority) { 11354 // Insert this broadcast record into the final list. 11355 receivers.add(it, curr); 11356 ir++; 11357 curr = null; 11358 it++; 11359 NT++; 11360 } else { 11361 // Skip to the next ResolveInfo in the final list. 11362 it++; 11363 curt = null; 11364 } 11365 } 11366 } 11367 while (ir < NR) { 11368 if (receivers == null) { 11369 receivers = new ArrayList(); 11370 } 11371 receivers.add(registeredReceivers.get(ir)); 11372 ir++; 11373 } 11374 11375 if ((receivers != null && receivers.size() > 0) 11376 || resultTo != null) { 11377 BroadcastQueue queue = broadcastQueueForIntent(intent); 11378 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11379 callerPackage, callingPid, callingUid, requiredPermission, 11380 receivers, resultTo, resultCode, resultData, map, ordered, 11381 sticky, false, onlySendToCaller); 11382 if (DEBUG_BROADCAST) Slog.v( 11383 TAG, "Enqueueing ordered broadcast " + r 11384 + ": prev had " + queue.mOrderedBroadcasts.size()); 11385 if (DEBUG_BROADCAST) { 11386 int seq = r.intent.getIntExtra("seq", -1); 11387 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11388 } 11389 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11390 if (!replaced) { 11391 queue.enqueueOrderedBroadcastLocked(r); 11392 queue.scheduleBroadcastsLocked(); 11393 } 11394 } 11395 11396 return ActivityManager.BROADCAST_SUCCESS; 11397 } 11398 11399 final Intent verifyBroadcastLocked(Intent intent) { 11400 // Refuse possible leaked file descriptors 11401 if (intent != null && intent.hasFileDescriptors() == true) { 11402 throw new IllegalArgumentException("File descriptors passed in Intent"); 11403 } 11404 11405 int flags = intent.getFlags(); 11406 11407 if (!mProcessesReady) { 11408 // if the caller really truly claims to know what they're doing, go 11409 // ahead and allow the broadcast without launching any receivers 11410 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11411 intent = new Intent(intent); 11412 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11413 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11414 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11415 + " before boot completion"); 11416 throw new IllegalStateException("Cannot broadcast before boot completed"); 11417 } 11418 } 11419 11420 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11421 throw new IllegalArgumentException( 11422 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11423 } 11424 11425 return intent; 11426 } 11427 11428 public final int broadcastIntent(IApplicationThread caller, 11429 Intent intent, String resolvedType, IIntentReceiver resultTo, 11430 int resultCode, String resultData, Bundle map, 11431 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11432 enforceNotIsolatedCaller("broadcastIntent"); 11433 synchronized(this) { 11434 intent = verifyBroadcastLocked(intent); 11435 11436 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11437 final int callingPid = Binder.getCallingPid(); 11438 final int callingUid = Binder.getCallingUid(); 11439 final long origId = Binder.clearCallingIdentity(); 11440 int res = broadcastIntentLocked(callerApp, 11441 callerApp != null ? callerApp.info.packageName : null, 11442 intent, resolvedType, resultTo, 11443 resultCode, resultData, map, requiredPermission, serialized, sticky, 11444 callingPid, callingUid, userId); 11445 Binder.restoreCallingIdentity(origId); 11446 return res; 11447 } 11448 } 11449 11450 int broadcastIntentInPackage(String packageName, int uid, 11451 Intent intent, String resolvedType, IIntentReceiver resultTo, 11452 int resultCode, String resultData, Bundle map, 11453 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11454 synchronized(this) { 11455 intent = verifyBroadcastLocked(intent); 11456 11457 final long origId = Binder.clearCallingIdentity(); 11458 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11459 resultTo, resultCode, resultData, map, requiredPermission, 11460 serialized, sticky, -1, uid, userId); 11461 Binder.restoreCallingIdentity(origId); 11462 return res; 11463 } 11464 } 11465 11466 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11467 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11468 // Refuse possible leaked file descriptors 11469 if (intent != null && intent.hasFileDescriptors() == true) { 11470 throw new IllegalArgumentException("File descriptors passed in Intent"); 11471 } 11472 11473 synchronized(this) { 11474 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11475 != PackageManager.PERMISSION_GRANTED) { 11476 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11477 + Binder.getCallingPid() 11478 + ", uid=" + Binder.getCallingUid() 11479 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11480 Slog.w(TAG, msg); 11481 throw new SecurityException(msg); 11482 } 11483 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11484 if (list != null) { 11485 int N = list.size(); 11486 int i; 11487 for (i=0; i<N; i++) { 11488 if (intent.filterEquals(list.get(i))) { 11489 list.remove(i); 11490 break; 11491 } 11492 } 11493 } 11494 } 11495 } 11496 11497 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11498 String resultData, Bundle resultExtras, boolean resultAbort, 11499 boolean explicit) { 11500 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11501 if (r == null) { 11502 Slog.w(TAG, "finishReceiver called but not found on queue"); 11503 return false; 11504 } 11505 11506 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11507 explicit); 11508 } 11509 11510 public void finishReceiver(IBinder who, int resultCode, String resultData, 11511 Bundle resultExtras, boolean resultAbort) { 11512 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11513 11514 // Refuse possible leaked file descriptors 11515 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11516 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11517 } 11518 11519 final long origId = Binder.clearCallingIdentity(); 11520 try { 11521 boolean doNext = false; 11522 BroadcastRecord r = null; 11523 11524 synchronized(this) { 11525 r = broadcastRecordForReceiverLocked(who); 11526 if (r != null) { 11527 doNext = r.queue.finishReceiverLocked(r, resultCode, 11528 resultData, resultExtras, resultAbort, true); 11529 } 11530 } 11531 11532 if (doNext) { 11533 r.queue.processNextBroadcast(false); 11534 } 11535 trimApplications(); 11536 } finally { 11537 Binder.restoreCallingIdentity(origId); 11538 } 11539 } 11540 11541 // ========================================================= 11542 // INSTRUMENTATION 11543 // ========================================================= 11544 11545 public boolean startInstrumentation(ComponentName className, 11546 String profileFile, int flags, Bundle arguments, 11547 IInstrumentationWatcher watcher) { 11548 enforceNotIsolatedCaller("startInstrumentation"); 11549 // Refuse possible leaked file descriptors 11550 if (arguments != null && arguments.hasFileDescriptors()) { 11551 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11552 } 11553 11554 synchronized(this) { 11555 InstrumentationInfo ii = null; 11556 ApplicationInfo ai = null; 11557 try { 11558 ii = mContext.getPackageManager().getInstrumentationInfo( 11559 className, STOCK_PM_FLAGS); 11560 ai = mContext.getPackageManager().getApplicationInfo( 11561 ii.targetPackage, STOCK_PM_FLAGS); 11562 } catch (PackageManager.NameNotFoundException e) { 11563 } 11564 if (ii == null) { 11565 reportStartInstrumentationFailure(watcher, className, 11566 "Unable to find instrumentation info for: " + className); 11567 return false; 11568 } 11569 if (ai == null) { 11570 reportStartInstrumentationFailure(watcher, className, 11571 "Unable to find instrumentation target package: " + ii.targetPackage); 11572 return false; 11573 } 11574 11575 int match = mContext.getPackageManager().checkSignatures( 11576 ii.targetPackage, ii.packageName); 11577 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11578 String msg = "Permission Denial: starting instrumentation " 11579 + className + " from pid=" 11580 + Binder.getCallingPid() 11581 + ", uid=" + Binder.getCallingPid() 11582 + " not allowed because package " + ii.packageName 11583 + " does not have a signature matching the target " 11584 + ii.targetPackage; 11585 reportStartInstrumentationFailure(watcher, className, msg); 11586 throw new SecurityException(msg); 11587 } 11588 11589 int userId = UserHandle.getCallingUserId(); 11590 final long origId = Binder.clearCallingIdentity(); 11591 // Instrumentation can kill and relaunch even persistent processes 11592 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11593 ProcessRecord app = addAppLocked(ai, false); 11594 app.instrumentationClass = className; 11595 app.instrumentationInfo = ai; 11596 app.instrumentationProfileFile = profileFile; 11597 app.instrumentationArguments = arguments; 11598 app.instrumentationWatcher = watcher; 11599 app.instrumentationResultClass = className; 11600 Binder.restoreCallingIdentity(origId); 11601 } 11602 11603 return true; 11604 } 11605 11606 /** 11607 * Report errors that occur while attempting to start Instrumentation. Always writes the 11608 * error to the logs, but if somebody is watching, send the report there too. This enables 11609 * the "am" command to report errors with more information. 11610 * 11611 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11612 * @param cn The component name of the instrumentation. 11613 * @param report The error report. 11614 */ 11615 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11616 ComponentName cn, String report) { 11617 Slog.w(TAG, report); 11618 try { 11619 if (watcher != null) { 11620 Bundle results = new Bundle(); 11621 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11622 results.putString("Error", report); 11623 watcher.instrumentationStatus(cn, -1, results); 11624 } 11625 } catch (RemoteException e) { 11626 Slog.w(TAG, e); 11627 } 11628 } 11629 11630 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11631 if (app.instrumentationWatcher != null) { 11632 try { 11633 // NOTE: IInstrumentationWatcher *must* be oneway here 11634 app.instrumentationWatcher.instrumentationFinished( 11635 app.instrumentationClass, 11636 resultCode, 11637 results); 11638 } catch (RemoteException e) { 11639 } 11640 } 11641 app.instrumentationWatcher = null; 11642 app.instrumentationClass = null; 11643 app.instrumentationInfo = null; 11644 app.instrumentationProfileFile = null; 11645 app.instrumentationArguments = null; 11646 11647 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11648 } 11649 11650 public void finishInstrumentation(IApplicationThread target, 11651 int resultCode, Bundle results) { 11652 int userId = UserHandle.getCallingUserId(); 11653 // Refuse possible leaked file descriptors 11654 if (results != null && results.hasFileDescriptors()) { 11655 throw new IllegalArgumentException("File descriptors passed in Intent"); 11656 } 11657 11658 synchronized(this) { 11659 ProcessRecord app = getRecordForAppLocked(target); 11660 if (app == null) { 11661 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11662 return; 11663 } 11664 final long origId = Binder.clearCallingIdentity(); 11665 finishInstrumentationLocked(app, resultCode, results); 11666 Binder.restoreCallingIdentity(origId); 11667 } 11668 } 11669 11670 // ========================================================= 11671 // CONFIGURATION 11672 // ========================================================= 11673 11674 public ConfigurationInfo getDeviceConfigurationInfo() { 11675 ConfigurationInfo config = new ConfigurationInfo(); 11676 synchronized (this) { 11677 config.reqTouchScreen = mConfiguration.touchscreen; 11678 config.reqKeyboardType = mConfiguration.keyboard; 11679 config.reqNavigation = mConfiguration.navigation; 11680 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11681 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11682 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11683 } 11684 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11685 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11686 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11687 } 11688 config.reqGlEsVersion = GL_ES_VERSION; 11689 } 11690 return config; 11691 } 11692 11693 public Configuration getConfiguration() { 11694 Configuration ci; 11695 synchronized(this) { 11696 ci = new Configuration(mConfiguration); 11697 } 11698 return ci; 11699 } 11700 11701 public void updatePersistentConfiguration(Configuration values) { 11702 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11703 "updateConfiguration()"); 11704 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11705 "updateConfiguration()"); 11706 if (values == null) { 11707 throw new NullPointerException("Configuration must not be null"); 11708 } 11709 11710 synchronized(this) { 11711 final long origId = Binder.clearCallingIdentity(); 11712 updateConfigurationLocked(values, null, true, false); 11713 Binder.restoreCallingIdentity(origId); 11714 } 11715 } 11716 11717 public void updateConfiguration(Configuration values) { 11718 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11719 "updateConfiguration()"); 11720 11721 synchronized(this) { 11722 if (values == null && mWindowManager != null) { 11723 // sentinel: fetch the current configuration from the window manager 11724 values = mWindowManager.computeNewConfiguration(); 11725 } 11726 11727 if (mWindowManager != null) { 11728 mProcessList.applyDisplaySize(mWindowManager); 11729 } 11730 11731 final long origId = Binder.clearCallingIdentity(); 11732 if (values != null) { 11733 Settings.System.clearConfiguration(values); 11734 } 11735 updateConfigurationLocked(values, null, false, false); 11736 Binder.restoreCallingIdentity(origId); 11737 } 11738 } 11739 11740 /** 11741 * Do either or both things: (1) change the current configuration, and (2) 11742 * make sure the given activity is running with the (now) current 11743 * configuration. Returns true if the activity has been left running, or 11744 * false if <var>starting</var> is being destroyed to match the new 11745 * configuration. 11746 * @param persistent TODO 11747 */ 11748 boolean updateConfigurationLocked(Configuration values, 11749 ActivityRecord starting, boolean persistent, boolean initLocale) { 11750 // do nothing if we are headless 11751 if (mHeadless) return true; 11752 11753 int changes = 0; 11754 11755 boolean kept = true; 11756 11757 if (values != null) { 11758 Configuration newConfig = new Configuration(mConfiguration); 11759 changes = newConfig.updateFrom(values); 11760 if (changes != 0) { 11761 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11762 Slog.i(TAG, "Updating configuration to: " + values); 11763 } 11764 11765 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11766 11767 if (values.locale != null && !initLocale) { 11768 saveLocaleLocked(values.locale, 11769 !values.locale.equals(mConfiguration.locale), 11770 values.userSetLocale); 11771 } 11772 11773 mConfigurationSeq++; 11774 if (mConfigurationSeq <= 0) { 11775 mConfigurationSeq = 1; 11776 } 11777 newConfig.seq = mConfigurationSeq; 11778 mConfiguration = newConfig; 11779 Slog.i(TAG, "Config changed: " + newConfig); 11780 11781 final Configuration configCopy = new Configuration(mConfiguration); 11782 11783 // TODO: If our config changes, should we auto dismiss any currently 11784 // showing dialogs? 11785 mShowDialogs = shouldShowDialogs(newConfig); 11786 11787 AttributeCache ac = AttributeCache.instance(); 11788 if (ac != null) { 11789 ac.updateConfiguration(configCopy); 11790 } 11791 11792 // Make sure all resources in our process are updated 11793 // right now, so that anyone who is going to retrieve 11794 // resource values after we return will be sure to get 11795 // the new ones. This is especially important during 11796 // boot, where the first config change needs to guarantee 11797 // all resources have that config before following boot 11798 // code is executed. 11799 mSystemThread.applyConfigurationToResources(configCopy); 11800 11801 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11802 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11803 msg.obj = new Configuration(configCopy); 11804 mHandler.sendMessage(msg); 11805 } 11806 11807 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11808 ProcessRecord app = mLruProcesses.get(i); 11809 try { 11810 if (app.thread != null) { 11811 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11812 + app.processName + " new config " + mConfiguration); 11813 app.thread.scheduleConfigurationChanged(configCopy); 11814 } 11815 } catch (Exception e) { 11816 } 11817 } 11818 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11819 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11820 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11821 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11822 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11823 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11824 broadcastIntentLocked(null, null, 11825 new Intent(Intent.ACTION_LOCALE_CHANGED), 11826 null, null, 0, null, null, 11827 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11828 } 11829 } 11830 } 11831 11832 if (changes != 0 && starting == null) { 11833 // If the configuration changed, and the caller is not already 11834 // in the process of starting an activity, then find the top 11835 // activity to check if its configuration needs to change. 11836 starting = mMainStack.topRunningActivityLocked(null); 11837 } 11838 11839 if (starting != null) { 11840 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11841 // And we need to make sure at this point that all other activities 11842 // are made visible with the correct configuration. 11843 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11844 } 11845 11846 if (values != null && mWindowManager != null) { 11847 mWindowManager.setNewConfiguration(mConfiguration); 11848 } 11849 11850 return kept; 11851 } 11852 11853 /** 11854 * Decide based on the configuration whether we should shouw the ANR, 11855 * crash, etc dialogs. The idea is that if there is no affordnace to 11856 * press the on-screen buttons, we shouldn't show the dialog. 11857 * 11858 * A thought: SystemUI might also want to get told about this, the Power 11859 * dialog / global actions also might want different behaviors. 11860 */ 11861 private static final boolean shouldShowDialogs(Configuration config) { 11862 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11863 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11864 } 11865 11866 /** 11867 * Save the locale. You must be inside a synchronized (this) block. 11868 */ 11869 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11870 if(isDiff) { 11871 SystemProperties.set("user.language", l.getLanguage()); 11872 SystemProperties.set("user.region", l.getCountry()); 11873 } 11874 11875 if(isPersist) { 11876 SystemProperties.set("persist.sys.language", l.getLanguage()); 11877 SystemProperties.set("persist.sys.country", l.getCountry()); 11878 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11879 } 11880 } 11881 11882 @Override 11883 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11884 ActivityRecord srec = ActivityRecord.forToken(token); 11885 return srec != null && srec.task.affinity != null && 11886 srec.task.affinity.equals(destAffinity); 11887 } 11888 11889 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11890 Intent resultData) { 11891 ComponentName dest = destIntent.getComponent(); 11892 11893 synchronized (this) { 11894 ActivityRecord srec = ActivityRecord.forToken(token); 11895 if (srec == null) { 11896 return false; 11897 } 11898 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11899 final int start = history.indexOf(srec); 11900 if (start < 0) { 11901 // Current activity is not in history stack; do nothing. 11902 return false; 11903 } 11904 int finishTo = start - 1; 11905 ActivityRecord parent = null; 11906 boolean foundParentInTask = false; 11907 if (dest != null) { 11908 TaskRecord tr = srec.task; 11909 for (int i = start - 1; i >= 0; i--) { 11910 ActivityRecord r = history.get(i); 11911 if (tr != r.task) { 11912 // Couldn't find parent in the same task; stop at the one above this. 11913 // (Root of current task; in-app "home" behavior) 11914 // Always at least finish the current activity. 11915 finishTo = Math.min(start - 1, i + 1); 11916 parent = history.get(finishTo); 11917 break; 11918 } else if (r.info.packageName.equals(dest.getPackageName()) && 11919 r.info.name.equals(dest.getClassName())) { 11920 finishTo = i; 11921 parent = r; 11922 foundParentInTask = true; 11923 break; 11924 } 11925 } 11926 } 11927 11928 if (mController != null) { 11929 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11930 if (next != null) { 11931 // ask watcher if this is allowed 11932 boolean resumeOK = true; 11933 try { 11934 resumeOK = mController.activityResuming(next.packageName); 11935 } catch (RemoteException e) { 11936 mController = null; 11937 } 11938 11939 if (!resumeOK) { 11940 return false; 11941 } 11942 } 11943 } 11944 final long origId = Binder.clearCallingIdentity(); 11945 for (int i = start; i > finishTo; i--) { 11946 ActivityRecord r = history.get(i); 11947 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11948 "navigate-up"); 11949 // Only return the supplied result for the first activity finished 11950 resultCode = Activity.RESULT_CANCELED; 11951 resultData = null; 11952 } 11953 11954 if (parent != null && foundParentInTask) { 11955 final int parentLaunchMode = parent.info.launchMode; 11956 final int destIntentFlags = destIntent.getFlags(); 11957 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11958 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11959 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11960 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11961 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11962 } else { 11963 try { 11964 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11965 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 11966 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11967 null, aInfo, parent.appToken, null, 11968 0, -1, parent.launchedFromUid, 0, null, true, null); 11969 foundParentInTask = res == ActivityManager.START_SUCCESS; 11970 } catch (RemoteException e) { 11971 foundParentInTask = false; 11972 } 11973 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11974 resultData, "navigate-up"); 11975 } 11976 } 11977 Binder.restoreCallingIdentity(origId); 11978 return foundParentInTask; 11979 } 11980 } 11981 11982 public int getLaunchedFromUid(IBinder activityToken) { 11983 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11984 if (srec == null) { 11985 return -1; 11986 } 11987 return srec.launchedFromUid; 11988 } 11989 11990 // ========================================================= 11991 // LIFETIME MANAGEMENT 11992 // ========================================================= 11993 11994 // Returns which broadcast queue the app is the current [or imminent] receiver 11995 // on, or 'null' if the app is not an active broadcast recipient. 11996 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11997 BroadcastRecord r = app.curReceiver; 11998 if (r != null) { 11999 return r.queue; 12000 } 12001 12002 // It's not the current receiver, but it might be starting up to become one 12003 synchronized (this) { 12004 for (BroadcastQueue queue : mBroadcastQueues) { 12005 r = queue.mPendingBroadcast; 12006 if (r != null && r.curApp == app) { 12007 // found it; report which queue it's in 12008 return queue; 12009 } 12010 } 12011 } 12012 12013 return null; 12014 } 12015 12016 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12017 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12018 if (mAdjSeq == app.adjSeq) { 12019 // This adjustment has already been computed. If we are calling 12020 // from the top, we may have already computed our adjustment with 12021 // an earlier hidden adjustment that isn't really for us... if 12022 // so, use the new hidden adjustment. 12023 if (!recursed && app.hidden) { 12024 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12025 app.hasActivities ? hiddenAdj : emptyAdj; 12026 } 12027 return app.curRawAdj; 12028 } 12029 12030 if (app.thread == null) { 12031 app.adjSeq = mAdjSeq; 12032 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12033 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12034 } 12035 12036 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12037 app.adjSource = null; 12038 app.adjTarget = null; 12039 app.empty = false; 12040 app.hidden = false; 12041 12042 final int activitiesSize = app.activities.size(); 12043 12044 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12045 // The max adjustment doesn't allow this app to be anything 12046 // below foreground, so it is not worth doing work for it. 12047 app.adjType = "fixed"; 12048 app.adjSeq = mAdjSeq; 12049 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12050 app.hasActivities = false; 12051 app.foregroundActivities = false; 12052 app.keeping = true; 12053 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12054 // System process can do UI, and when they do we want to have 12055 // them trim their memory after the user leaves the UI. To 12056 // facilitate this, here we need to determine whether or not it 12057 // is currently showing UI. 12058 app.systemNoUi = true; 12059 if (app == TOP_APP) { 12060 app.systemNoUi = false; 12061 app.hasActivities = true; 12062 } else if (activitiesSize > 0) { 12063 for (int j = 0; j < activitiesSize; j++) { 12064 final ActivityRecord r = app.activities.get(j); 12065 if (r.visible) { 12066 app.systemNoUi = false; 12067 } 12068 if (r.app == app) { 12069 app.hasActivities = true; 12070 } 12071 } 12072 } 12073 return (app.curAdj=app.maxAdj); 12074 } 12075 12076 app.keeping = false; 12077 app.systemNoUi = false; 12078 app.hasActivities = false; 12079 12080 // Determine the importance of the process, starting with most 12081 // important to least, and assign an appropriate OOM adjustment. 12082 int adj; 12083 int schedGroup; 12084 boolean foregroundActivities = false; 12085 boolean interesting = false; 12086 BroadcastQueue queue; 12087 if (app == TOP_APP) { 12088 // The last app on the list is the foreground app. 12089 adj = ProcessList.FOREGROUND_APP_ADJ; 12090 schedGroup = Process.THREAD_GROUP_DEFAULT; 12091 app.adjType = "top-activity"; 12092 foregroundActivities = true; 12093 interesting = true; 12094 app.hasActivities = true; 12095 } else if (app.instrumentationClass != null) { 12096 // Don't want to kill running instrumentation. 12097 adj = ProcessList.FOREGROUND_APP_ADJ; 12098 schedGroup = Process.THREAD_GROUP_DEFAULT; 12099 app.adjType = "instrumentation"; 12100 interesting = true; 12101 } else if ((queue = isReceivingBroadcast(app)) != null) { 12102 // An app that is currently receiving a broadcast also 12103 // counts as being in the foreground for OOM killer purposes. 12104 // It's placed in a sched group based on the nature of the 12105 // broadcast as reflected by which queue it's active in. 12106 adj = ProcessList.FOREGROUND_APP_ADJ; 12107 schedGroup = (queue == mFgBroadcastQueue) 12108 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12109 app.adjType = "broadcast"; 12110 } else if (app.executingServices.size() > 0) { 12111 // An app that is currently executing a service callback also 12112 // counts as being in the foreground. 12113 adj = ProcessList.FOREGROUND_APP_ADJ; 12114 schedGroup = Process.THREAD_GROUP_DEFAULT; 12115 app.adjType = "exec-service"; 12116 } else { 12117 // Assume process is hidden (has activities); we will correct 12118 // later if this is not the case. 12119 adj = hiddenAdj; 12120 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12121 app.hidden = true; 12122 app.adjType = "bg-activities"; 12123 } 12124 12125 boolean hasStoppingActivities = false; 12126 12127 // Examine all activities if not already foreground. 12128 if (!foregroundActivities && activitiesSize > 0) { 12129 for (int j = 0; j < activitiesSize; j++) { 12130 final ActivityRecord r = app.activities.get(j); 12131 if (r.visible) { 12132 // App has a visible activity; only upgrade adjustment. 12133 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12134 adj = ProcessList.VISIBLE_APP_ADJ; 12135 app.adjType = "visible"; 12136 } 12137 schedGroup = Process.THREAD_GROUP_DEFAULT; 12138 app.hidden = false; 12139 app.hasActivities = true; 12140 foregroundActivities = true; 12141 break; 12142 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12143 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12144 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12145 app.adjType = "pausing"; 12146 } 12147 app.hidden = false; 12148 foregroundActivities = true; 12149 } else if (r.state == ActivityState.STOPPING) { 12150 // We will apply the actual adjustment later, because 12151 // we want to allow this process to immediately go through 12152 // any memory trimming that is in effect. 12153 app.hidden = false; 12154 foregroundActivities = true; 12155 hasStoppingActivities = true; 12156 } 12157 if (r.app == app) { 12158 app.hasActivities = true; 12159 } 12160 } 12161 } 12162 12163 if (adj == hiddenAdj && !app.hasActivities) { 12164 // Whoops, this process is completely empty as far as we know 12165 // at this point. 12166 adj = emptyAdj; 12167 app.empty = true; 12168 app.adjType = "bg-empty"; 12169 } 12170 12171 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12172 if (app.foregroundServices) { 12173 // The user is aware of this app, so make it visible. 12174 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12175 app.hidden = false; 12176 app.adjType = "foreground-service"; 12177 schedGroup = Process.THREAD_GROUP_DEFAULT; 12178 } else if (app.forcingToForeground != null) { 12179 // The user is aware of this app, so make it visible. 12180 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12181 app.hidden = false; 12182 app.adjType = "force-foreground"; 12183 app.adjSource = app.forcingToForeground; 12184 schedGroup = Process.THREAD_GROUP_DEFAULT; 12185 } 12186 } 12187 12188 if (app.foregroundServices) { 12189 interesting = true; 12190 } 12191 12192 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12193 // We don't want to kill the current heavy-weight process. 12194 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12195 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12196 app.hidden = false; 12197 app.adjType = "heavy"; 12198 } 12199 12200 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12201 // This process is hosting what we currently consider to be the 12202 // home app, so we don't want to let it go into the background. 12203 adj = ProcessList.HOME_APP_ADJ; 12204 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12205 app.hidden = false; 12206 app.adjType = "home"; 12207 } 12208 12209 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12210 && app.activities.size() > 0) { 12211 // This was the previous process that showed UI to the user. 12212 // We want to try to keep it around more aggressively, to give 12213 // a good experience around switching between two apps. 12214 adj = ProcessList.PREVIOUS_APP_ADJ; 12215 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12216 app.hidden = false; 12217 app.adjType = "previous"; 12218 } 12219 12220 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12221 + " reason=" + app.adjType); 12222 12223 // By default, we use the computed adjustment. It may be changed if 12224 // there are applications dependent on our services or providers, but 12225 // this gives us a baseline and makes sure we don't get into an 12226 // infinite recursion. 12227 app.adjSeq = mAdjSeq; 12228 app.curRawAdj = app.nonStoppingAdj = adj; 12229 12230 if (mBackupTarget != null && app == mBackupTarget.app) { 12231 // If possible we want to avoid killing apps while they're being backed up 12232 if (adj > ProcessList.BACKUP_APP_ADJ) { 12233 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12234 adj = ProcessList.BACKUP_APP_ADJ; 12235 app.adjType = "backup"; 12236 app.hidden = false; 12237 } 12238 } 12239 12240 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12241 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12242 final long now = SystemClock.uptimeMillis(); 12243 // This process is more important if the top activity is 12244 // bound to the service. 12245 Iterator<ServiceRecord> jt = app.services.iterator(); 12246 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12247 ServiceRecord s = jt.next(); 12248 if (s.startRequested) { 12249 if (app.hasShownUi && app != mHomeProcess) { 12250 // If this process has shown some UI, let it immediately 12251 // go to the LRU list because it may be pretty heavy with 12252 // UI stuff. We'll tag it with a label just to help 12253 // debug and understand what is going on. 12254 if (adj > ProcessList.SERVICE_ADJ) { 12255 app.adjType = "started-bg-ui-services"; 12256 } 12257 } else { 12258 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12259 // This service has seen some activity within 12260 // recent memory, so we will keep its process ahead 12261 // of the background processes. 12262 if (adj > ProcessList.SERVICE_ADJ) { 12263 adj = ProcessList.SERVICE_ADJ; 12264 app.adjType = "started-services"; 12265 app.hidden = false; 12266 } 12267 } 12268 // If we have let the service slide into the background 12269 // state, still have some text describing what it is doing 12270 // even though the service no longer has an impact. 12271 if (adj > ProcessList.SERVICE_ADJ) { 12272 app.adjType = "started-bg-services"; 12273 } 12274 } 12275 // Don't kill this process because it is doing work; it 12276 // has said it is doing work. 12277 app.keeping = true; 12278 } 12279 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12280 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12281 Iterator<ArrayList<ConnectionRecord>> kt 12282 = s.connections.values().iterator(); 12283 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12284 ArrayList<ConnectionRecord> clist = kt.next(); 12285 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12286 // XXX should compute this based on the max of 12287 // all connected clients. 12288 ConnectionRecord cr = clist.get(i); 12289 if (cr.binding.client == app) { 12290 // Binding to ourself is not interesting. 12291 continue; 12292 } 12293 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12294 ProcessRecord client = cr.binding.client; 12295 int clientAdj = adj; 12296 int myHiddenAdj = hiddenAdj; 12297 if (myHiddenAdj > client.hiddenAdj) { 12298 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12299 myHiddenAdj = client.hiddenAdj; 12300 } else { 12301 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12302 } 12303 } 12304 int myEmptyAdj = emptyAdj; 12305 if (myEmptyAdj > client.emptyAdj) { 12306 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12307 myEmptyAdj = client.emptyAdj; 12308 } else { 12309 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12310 } 12311 } 12312 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12313 myEmptyAdj, TOP_APP, true, doingAll); 12314 String adjType = null; 12315 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12316 // Not doing bind OOM management, so treat 12317 // this guy more like a started service. 12318 if (app.hasShownUi && app != mHomeProcess) { 12319 // If this process has shown some UI, let it immediately 12320 // go to the LRU list because it may be pretty heavy with 12321 // UI stuff. We'll tag it with a label just to help 12322 // debug and understand what is going on. 12323 if (adj > clientAdj) { 12324 adjType = "bound-bg-ui-services"; 12325 } 12326 app.hidden = false; 12327 clientAdj = adj; 12328 } else { 12329 if (now >= (s.lastActivity 12330 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12331 // This service has not seen activity within 12332 // recent memory, so allow it to drop to the 12333 // LRU list if there is no other reason to keep 12334 // it around. We'll also tag it with a label just 12335 // to help debug and undertand what is going on. 12336 if (adj > clientAdj) { 12337 adjType = "bound-bg-services"; 12338 } 12339 clientAdj = adj; 12340 } 12341 } 12342 } 12343 if (adj > clientAdj) { 12344 // If this process has recently shown UI, and 12345 // the process that is binding to it is less 12346 // important than being visible, then we don't 12347 // care about the binding as much as we care 12348 // about letting this process get into the LRU 12349 // list to be killed and restarted if needed for 12350 // memory. 12351 if (app.hasShownUi && app != mHomeProcess 12352 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12353 adjType = "bound-bg-ui-services"; 12354 } else { 12355 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12356 |Context.BIND_IMPORTANT)) != 0) { 12357 adj = clientAdj; 12358 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12359 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12360 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12361 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12362 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12363 adj = clientAdj; 12364 } else { 12365 app.pendingUiClean = true; 12366 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12367 adj = ProcessList.VISIBLE_APP_ADJ; 12368 } 12369 } 12370 if (!client.hidden) { 12371 app.hidden = false; 12372 } 12373 if (client.keeping) { 12374 app.keeping = true; 12375 } 12376 adjType = "service"; 12377 } 12378 } 12379 if (adjType != null) { 12380 app.adjType = adjType; 12381 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12382 .REASON_SERVICE_IN_USE; 12383 app.adjSource = cr.binding.client; 12384 app.adjSourceOom = clientAdj; 12385 app.adjTarget = s.name; 12386 } 12387 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12388 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12389 schedGroup = Process.THREAD_GROUP_DEFAULT; 12390 } 12391 } 12392 } 12393 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12394 ActivityRecord a = cr.activity; 12395 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12396 (a.visible || a.state == ActivityState.RESUMED 12397 || a.state == ActivityState.PAUSING)) { 12398 adj = ProcessList.FOREGROUND_APP_ADJ; 12399 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12400 schedGroup = Process.THREAD_GROUP_DEFAULT; 12401 } 12402 app.hidden = false; 12403 app.adjType = "service"; 12404 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12405 .REASON_SERVICE_IN_USE; 12406 app.adjSource = a; 12407 app.adjSourceOom = adj; 12408 app.adjTarget = s.name; 12409 } 12410 } 12411 } 12412 } 12413 } 12414 } 12415 12416 // Finally, if this process has active services running in it, we 12417 // would like to avoid killing it unless it would prevent the current 12418 // application from running. By default we put the process in 12419 // with the rest of the background processes; as we scan through 12420 // its services we may bump it up from there. 12421 if (adj > hiddenAdj) { 12422 adj = hiddenAdj; 12423 app.hidden = false; 12424 app.adjType = "bg-services"; 12425 } 12426 } 12427 12428 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12429 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12430 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12431 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12432 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12433 ContentProviderRecord cpr = jt.next(); 12434 for (int i = cpr.connections.size()-1; 12435 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12436 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12437 i--) { 12438 ContentProviderConnection conn = cpr.connections.get(i); 12439 ProcessRecord client = conn.client; 12440 if (client == app) { 12441 // Being our own client is not interesting. 12442 continue; 12443 } 12444 int myHiddenAdj = hiddenAdj; 12445 if (myHiddenAdj > client.hiddenAdj) { 12446 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12447 myHiddenAdj = client.hiddenAdj; 12448 } else { 12449 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12450 } 12451 } 12452 int myEmptyAdj = emptyAdj; 12453 if (myEmptyAdj > client.emptyAdj) { 12454 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12455 myEmptyAdj = client.emptyAdj; 12456 } else { 12457 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12458 } 12459 } 12460 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12461 myEmptyAdj, TOP_APP, true, doingAll); 12462 if (adj > clientAdj) { 12463 if (app.hasShownUi && app != mHomeProcess 12464 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12465 app.adjType = "bg-ui-provider"; 12466 } else { 12467 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12468 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12469 app.adjType = "provider"; 12470 } 12471 if (!client.hidden) { 12472 app.hidden = false; 12473 } 12474 if (client.keeping) { 12475 app.keeping = true; 12476 } 12477 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12478 .REASON_PROVIDER_IN_USE; 12479 app.adjSource = client; 12480 app.adjSourceOom = clientAdj; 12481 app.adjTarget = cpr.name; 12482 } 12483 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12484 schedGroup = Process.THREAD_GROUP_DEFAULT; 12485 } 12486 } 12487 // If the provider has external (non-framework) process 12488 // dependencies, ensure that its adjustment is at least 12489 // FOREGROUND_APP_ADJ. 12490 if (cpr.hasExternalProcessHandles()) { 12491 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12492 adj = ProcessList.FOREGROUND_APP_ADJ; 12493 schedGroup = Process.THREAD_GROUP_DEFAULT; 12494 app.hidden = false; 12495 app.keeping = true; 12496 app.adjType = "provider"; 12497 app.adjTarget = cpr.name; 12498 } 12499 } 12500 } 12501 } 12502 12503 if (adj == ProcessList.SERVICE_ADJ) { 12504 if (doingAll) { 12505 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12506 mNewNumServiceProcs++; 12507 } 12508 if (app.serviceb) { 12509 adj = ProcessList.SERVICE_B_ADJ; 12510 } 12511 } else { 12512 app.serviceb = false; 12513 } 12514 12515 app.nonStoppingAdj = adj; 12516 12517 if (hasStoppingActivities) { 12518 // Only upgrade adjustment. 12519 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12520 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12521 app.adjType = "stopping"; 12522 } 12523 } 12524 12525 app.curRawAdj = adj; 12526 12527 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12528 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12529 if (adj > app.maxAdj) { 12530 adj = app.maxAdj; 12531 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12532 schedGroup = Process.THREAD_GROUP_DEFAULT; 12533 } 12534 } 12535 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12536 app.keeping = true; 12537 } 12538 12539 if (app.hasAboveClient) { 12540 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12541 // then we need to drop its adjustment to be lower than the service's 12542 // in order to honor the request. We want to drop it by one adjustment 12543 // level... but there is special meaning applied to various levels so 12544 // we will skip some of them. 12545 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12546 // System process will not get dropped, ever 12547 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12548 adj = ProcessList.VISIBLE_APP_ADJ; 12549 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12550 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12551 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12552 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12553 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12554 adj++; 12555 } 12556 } 12557 12558 int importance = app.memImportance; 12559 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12560 app.curAdj = adj; 12561 app.curSchedGroup = schedGroup; 12562 if (!interesting) { 12563 // For this reporting, if there is not something explicitly 12564 // interesting in this process then we will push it to the 12565 // background importance. 12566 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12567 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12568 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12569 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12570 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12571 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12572 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12573 } else if (adj >= ProcessList.SERVICE_ADJ) { 12574 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12575 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12576 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12577 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12578 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12579 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12580 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12581 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12582 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12583 } else { 12584 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12585 } 12586 } 12587 12588 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12589 if (foregroundActivities != app.foregroundActivities) { 12590 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12591 } 12592 if (changes != 0) { 12593 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12594 app.memImportance = importance; 12595 app.foregroundActivities = foregroundActivities; 12596 int i = mPendingProcessChanges.size()-1; 12597 ProcessChangeItem item = null; 12598 while (i >= 0) { 12599 item = mPendingProcessChanges.get(i); 12600 if (item.pid == app.pid) { 12601 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12602 break; 12603 } 12604 i--; 12605 } 12606 if (i < 0) { 12607 // No existing item in pending changes; need a new one. 12608 final int NA = mAvailProcessChanges.size(); 12609 if (NA > 0) { 12610 item = mAvailProcessChanges.remove(NA-1); 12611 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12612 } else { 12613 item = new ProcessChangeItem(); 12614 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12615 } 12616 item.changes = 0; 12617 item.pid = app.pid; 12618 item.uid = app.info.uid; 12619 if (mPendingProcessChanges.size() == 0) { 12620 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12621 "*** Enqueueing dispatch processes changed!"); 12622 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12623 } 12624 mPendingProcessChanges.add(item); 12625 } 12626 item.changes |= changes; 12627 item.importance = importance; 12628 item.foregroundActivities = foregroundActivities; 12629 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12630 + Integer.toHexString(System.identityHashCode(item)) 12631 + " " + app.toShortString() + ": changes=" + item.changes 12632 + " importance=" + item.importance 12633 + " foreground=" + item.foregroundActivities 12634 + " type=" + app.adjType + " source=" + app.adjSource 12635 + " target=" + app.adjTarget); 12636 } 12637 12638 return app.curRawAdj; 12639 } 12640 12641 /** 12642 * Ask a given process to GC right now. 12643 */ 12644 final void performAppGcLocked(ProcessRecord app) { 12645 try { 12646 app.lastRequestedGc = SystemClock.uptimeMillis(); 12647 if (app.thread != null) { 12648 if (app.reportLowMemory) { 12649 app.reportLowMemory = false; 12650 app.thread.scheduleLowMemory(); 12651 } else { 12652 app.thread.processInBackground(); 12653 } 12654 } 12655 } catch (Exception e) { 12656 // whatever. 12657 } 12658 } 12659 12660 /** 12661 * Returns true if things are idle enough to perform GCs. 12662 */ 12663 private final boolean canGcNowLocked() { 12664 boolean processingBroadcasts = false; 12665 for (BroadcastQueue q : mBroadcastQueues) { 12666 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12667 processingBroadcasts = true; 12668 } 12669 } 12670 return !processingBroadcasts 12671 && (mSleeping || (mMainStack.mResumedActivity != null && 12672 mMainStack.mResumedActivity.idle)); 12673 } 12674 12675 /** 12676 * Perform GCs on all processes that are waiting for it, but only 12677 * if things are idle. 12678 */ 12679 final void performAppGcsLocked() { 12680 final int N = mProcessesToGc.size(); 12681 if (N <= 0) { 12682 return; 12683 } 12684 if (canGcNowLocked()) { 12685 while (mProcessesToGc.size() > 0) { 12686 ProcessRecord proc = mProcessesToGc.remove(0); 12687 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12688 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12689 <= SystemClock.uptimeMillis()) { 12690 // To avoid spamming the system, we will GC processes one 12691 // at a time, waiting a few seconds between each. 12692 performAppGcLocked(proc); 12693 scheduleAppGcsLocked(); 12694 return; 12695 } else { 12696 // It hasn't been long enough since we last GCed this 12697 // process... put it in the list to wait for its time. 12698 addProcessToGcListLocked(proc); 12699 break; 12700 } 12701 } 12702 } 12703 12704 scheduleAppGcsLocked(); 12705 } 12706 } 12707 12708 /** 12709 * If all looks good, perform GCs on all processes waiting for them. 12710 */ 12711 final void performAppGcsIfAppropriateLocked() { 12712 if (canGcNowLocked()) { 12713 performAppGcsLocked(); 12714 return; 12715 } 12716 // Still not idle, wait some more. 12717 scheduleAppGcsLocked(); 12718 } 12719 12720 /** 12721 * Schedule the execution of all pending app GCs. 12722 */ 12723 final void scheduleAppGcsLocked() { 12724 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12725 12726 if (mProcessesToGc.size() > 0) { 12727 // Schedule a GC for the time to the next process. 12728 ProcessRecord proc = mProcessesToGc.get(0); 12729 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12730 12731 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12732 long now = SystemClock.uptimeMillis(); 12733 if (when < (now+GC_TIMEOUT)) { 12734 when = now + GC_TIMEOUT; 12735 } 12736 mHandler.sendMessageAtTime(msg, when); 12737 } 12738 } 12739 12740 /** 12741 * Add a process to the array of processes waiting to be GCed. Keeps the 12742 * list in sorted order by the last GC time. The process can't already be 12743 * on the list. 12744 */ 12745 final void addProcessToGcListLocked(ProcessRecord proc) { 12746 boolean added = false; 12747 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12748 if (mProcessesToGc.get(i).lastRequestedGc < 12749 proc.lastRequestedGc) { 12750 added = true; 12751 mProcessesToGc.add(i+1, proc); 12752 break; 12753 } 12754 } 12755 if (!added) { 12756 mProcessesToGc.add(0, proc); 12757 } 12758 } 12759 12760 /** 12761 * Set up to ask a process to GC itself. This will either do it 12762 * immediately, or put it on the list of processes to gc the next 12763 * time things are idle. 12764 */ 12765 final void scheduleAppGcLocked(ProcessRecord app) { 12766 long now = SystemClock.uptimeMillis(); 12767 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12768 return; 12769 } 12770 if (!mProcessesToGc.contains(app)) { 12771 addProcessToGcListLocked(app); 12772 scheduleAppGcsLocked(); 12773 } 12774 } 12775 12776 final void checkExcessivePowerUsageLocked(boolean doKills) { 12777 updateCpuStatsNow(); 12778 12779 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12780 boolean doWakeKills = doKills; 12781 boolean doCpuKills = doKills; 12782 if (mLastPowerCheckRealtime == 0) { 12783 doWakeKills = false; 12784 } 12785 if (mLastPowerCheckUptime == 0) { 12786 doCpuKills = false; 12787 } 12788 if (stats.isScreenOn()) { 12789 doWakeKills = false; 12790 } 12791 final long curRealtime = SystemClock.elapsedRealtime(); 12792 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12793 final long curUptime = SystemClock.uptimeMillis(); 12794 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12795 mLastPowerCheckRealtime = curRealtime; 12796 mLastPowerCheckUptime = curUptime; 12797 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12798 doWakeKills = false; 12799 } 12800 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12801 doCpuKills = false; 12802 } 12803 int i = mLruProcesses.size(); 12804 while (i > 0) { 12805 i--; 12806 ProcessRecord app = mLruProcesses.get(i); 12807 if (!app.keeping) { 12808 long wtime; 12809 synchronized (stats) { 12810 wtime = stats.getProcessWakeTime(app.info.uid, 12811 app.pid, curRealtime); 12812 } 12813 long wtimeUsed = wtime - app.lastWakeTime; 12814 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12815 if (DEBUG_POWER) { 12816 StringBuilder sb = new StringBuilder(128); 12817 sb.append("Wake for "); 12818 app.toShortString(sb); 12819 sb.append(": over "); 12820 TimeUtils.formatDuration(realtimeSince, sb); 12821 sb.append(" used "); 12822 TimeUtils.formatDuration(wtimeUsed, sb); 12823 sb.append(" ("); 12824 sb.append((wtimeUsed*100)/realtimeSince); 12825 sb.append("%)"); 12826 Slog.i(TAG, sb.toString()); 12827 sb.setLength(0); 12828 sb.append("CPU for "); 12829 app.toShortString(sb); 12830 sb.append(": over "); 12831 TimeUtils.formatDuration(uptimeSince, sb); 12832 sb.append(" used "); 12833 TimeUtils.formatDuration(cputimeUsed, sb); 12834 sb.append(" ("); 12835 sb.append((cputimeUsed*100)/uptimeSince); 12836 sb.append("%)"); 12837 Slog.i(TAG, sb.toString()); 12838 } 12839 // If a process has held a wake lock for more 12840 // than 50% of the time during this period, 12841 // that sounds bad. Kill! 12842 if (doWakeKills && realtimeSince > 0 12843 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12844 synchronized (stats) { 12845 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12846 realtimeSince, wtimeUsed); 12847 } 12848 Slog.w(TAG, "Excessive wake lock in " + app.processName 12849 + " (pid " + app.pid + "): held " + wtimeUsed 12850 + " during " + realtimeSince); 12851 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12852 app.processName, app.setAdj, "excessive wake lock"); 12853 Process.killProcessQuiet(app.pid); 12854 } else if (doCpuKills && uptimeSince > 0 12855 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12856 synchronized (stats) { 12857 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12858 uptimeSince, cputimeUsed); 12859 } 12860 Slog.w(TAG, "Excessive CPU in " + app.processName 12861 + " (pid " + app.pid + "): used " + cputimeUsed 12862 + " during " + uptimeSince); 12863 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12864 app.processName, app.setAdj, "excessive cpu"); 12865 Process.killProcessQuiet(app.pid); 12866 } else { 12867 app.lastWakeTime = wtime; 12868 app.lastCpuTime = app.curCpuTime; 12869 } 12870 } 12871 } 12872 } 12873 12874 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12875 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12876 app.hiddenAdj = hiddenAdj; 12877 app.emptyAdj = emptyAdj; 12878 12879 if (app.thread == null) { 12880 return false; 12881 } 12882 12883 final boolean wasKeeping = app.keeping; 12884 12885 boolean success = true; 12886 12887 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12888 12889 if (app.curRawAdj != app.setRawAdj) { 12890 if (wasKeeping && !app.keeping) { 12891 // This app is no longer something we want to keep. Note 12892 // its current wake lock time to later know to kill it if 12893 // it is not behaving well. 12894 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12895 synchronized (stats) { 12896 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12897 app.pid, SystemClock.elapsedRealtime()); 12898 } 12899 app.lastCpuTime = app.curCpuTime; 12900 } 12901 12902 app.setRawAdj = app.curRawAdj; 12903 } 12904 12905 if (app.curAdj != app.setAdj) { 12906 if (Process.setOomAdj(app.pid, app.curAdj)) { 12907 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12908 TAG, "Set " + app.pid + " " + app.processName + 12909 " adj " + app.curAdj + ": " + app.adjType); 12910 app.setAdj = app.curAdj; 12911 } else { 12912 success = false; 12913 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12914 } 12915 } 12916 if (app.setSchedGroup != app.curSchedGroup) { 12917 app.setSchedGroup = app.curSchedGroup; 12918 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12919 "Setting process group of " + app.processName 12920 + " to " + app.curSchedGroup); 12921 if (app.waitingToKill != null && 12922 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12923 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12924 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12925 app.processName, app.setAdj, app.waitingToKill); 12926 app.killedBackground = true; 12927 Process.killProcessQuiet(app.pid); 12928 success = false; 12929 } else { 12930 if (true) { 12931 long oldId = Binder.clearCallingIdentity(); 12932 try { 12933 Process.setProcessGroup(app.pid, app.curSchedGroup); 12934 } catch (Exception e) { 12935 Slog.w(TAG, "Failed setting process group of " + app.pid 12936 + " to " + app.curSchedGroup); 12937 e.printStackTrace(); 12938 } finally { 12939 Binder.restoreCallingIdentity(oldId); 12940 } 12941 } else { 12942 if (app.thread != null) { 12943 try { 12944 app.thread.setSchedulingGroup(app.curSchedGroup); 12945 } catch (RemoteException e) { 12946 } 12947 } 12948 } 12949 } 12950 } 12951 return success; 12952 } 12953 12954 private final ActivityRecord resumedAppLocked() { 12955 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12956 if (resumedActivity == null || resumedActivity.app == null) { 12957 resumedActivity = mMainStack.mPausingActivity; 12958 if (resumedActivity == null || resumedActivity.app == null) { 12959 resumedActivity = mMainStack.topRunningActivityLocked(null); 12960 } 12961 } 12962 return resumedActivity; 12963 } 12964 12965 final boolean updateOomAdjLocked(ProcessRecord app) { 12966 final ActivityRecord TOP_ACT = resumedAppLocked(); 12967 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12968 int curAdj = app.curAdj; 12969 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12970 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12971 12972 mAdjSeq++; 12973 12974 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 12975 TOP_APP, false); 12976 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12977 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12978 if (nowHidden != wasHidden) { 12979 // Changed to/from hidden state, so apps after it in the LRU 12980 // list may also be changed. 12981 updateOomAdjLocked(); 12982 } 12983 return success; 12984 } 12985 12986 final void updateOomAdjLocked() { 12987 final ActivityRecord TOP_ACT = resumedAppLocked(); 12988 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12989 12990 if (false) { 12991 RuntimeException e = new RuntimeException(); 12992 e.fillInStackTrace(); 12993 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12994 } 12995 12996 mAdjSeq++; 12997 mNewNumServiceProcs = 0; 12998 12999 // Let's determine how many processes we have running vs. 13000 // how many slots we have for background processes; we may want 13001 // to put multiple processes in a slot of there are enough of 13002 // them. 13003 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13004 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13005 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13006 if (emptyFactor < 1) emptyFactor = 1; 13007 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13008 if (hiddenFactor < 1) hiddenFactor = 1; 13009 int stepHidden = 0; 13010 int stepEmpty = 0; 13011 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13012 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13013 int numHidden = 0; 13014 int numEmpty = 0; 13015 int numTrimming = 0; 13016 13017 mNumNonHiddenProcs = 0; 13018 mNumHiddenProcs = 0; 13019 13020 // First update the OOM adjustment for each of the 13021 // application processes based on their current state. 13022 int i = mLruProcesses.size(); 13023 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13024 int nextHiddenAdj = curHiddenAdj+1; 13025 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13026 int nextEmptyAdj = curEmptyAdj+2; 13027 while (i > 0) { 13028 i--; 13029 ProcessRecord app = mLruProcesses.get(i); 13030 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13031 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13032 if (!app.killedBackground) { 13033 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13034 // This process was assigned as a hidden process... step the 13035 // hidden level. 13036 mNumHiddenProcs++; 13037 if (curHiddenAdj != nextHiddenAdj) { 13038 stepHidden++; 13039 if (stepHidden >= hiddenFactor) { 13040 stepHidden = 0; 13041 curHiddenAdj = nextHiddenAdj; 13042 nextHiddenAdj += 2; 13043 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13044 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13045 } 13046 } 13047 } 13048 numHidden++; 13049 if (numHidden > hiddenProcessLimit) { 13050 Slog.i(TAG, "No longer want " + app.processName 13051 + " (pid " + app.pid + "): hidden #" + numHidden); 13052 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13053 app.processName, app.setAdj, "too many background"); 13054 app.killedBackground = true; 13055 Process.killProcessQuiet(app.pid); 13056 } 13057 } else { 13058 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13059 // This process was assigned as an empty process... step the 13060 // empty level. 13061 if (curEmptyAdj != nextEmptyAdj) { 13062 stepEmpty++; 13063 if (stepEmpty >= emptyFactor) { 13064 stepEmpty = 0; 13065 curEmptyAdj = nextEmptyAdj; 13066 nextEmptyAdj += 2; 13067 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13068 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13069 } 13070 } 13071 } 13072 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13073 mNumNonHiddenProcs++; 13074 } 13075 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13076 numEmpty++; 13077 if (numEmpty > emptyProcessLimit) { 13078 Slog.i(TAG, "No longer want " + app.processName 13079 + " (pid " + app.pid + "): empty #" + numEmpty); 13080 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13081 app.processName, app.setAdj, "too many background"); 13082 app.killedBackground = true; 13083 Process.killProcessQuiet(app.pid); 13084 } 13085 } 13086 } 13087 if (app.isolated && app.services.size() <= 0) { 13088 // If this is an isolated process, and there are no 13089 // services running in it, then the process is no longer 13090 // needed. We agressively kill these because we can by 13091 // definition not re-use the same process again, and it is 13092 // good to avoid having whatever code was running in them 13093 // left sitting around after no longer needed. 13094 Slog.i(TAG, "Isolated process " + app.processName 13095 + " (pid " + app.pid + ") no longer needed"); 13096 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13097 app.processName, app.setAdj, "isolated not needed"); 13098 app.killedBackground = true; 13099 Process.killProcessQuiet(app.pid); 13100 } 13101 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13102 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13103 && !app.killedBackground) { 13104 numTrimming++; 13105 } 13106 } 13107 } 13108 13109 mNumServiceProcs = mNewNumServiceProcs; 13110 13111 // Now determine the memory trimming level of background processes. 13112 // Unfortunately we need to start at the back of the list to do this 13113 // properly. We only do this if the number of background apps we 13114 // are managing to keep around is less than half the maximum we desire; 13115 // if we are keeping a good number around, we'll let them use whatever 13116 // memory they want. 13117 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13118 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13119 final int numHiddenAndEmpty = numHidden + numEmpty; 13120 final int N = mLruProcesses.size(); 13121 int factor = numTrimming/3; 13122 int minFactor = 2; 13123 if (mHomeProcess != null) minFactor++; 13124 if (mPreviousProcess != null) minFactor++; 13125 if (factor < minFactor) factor = minFactor; 13126 int step = 0; 13127 int fgTrimLevel; 13128 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13129 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13130 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13131 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13132 } else { 13133 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13134 } 13135 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13136 for (i=0; i<N; i++) { 13137 ProcessRecord app = mLruProcesses.get(i); 13138 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13139 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13140 && !app.killedBackground) { 13141 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13142 try { 13143 app.thread.scheduleTrimMemory(curLevel); 13144 } catch (RemoteException e) { 13145 } 13146 if (false) { 13147 // For now we won't do this; our memory trimming seems 13148 // to be good enough at this point that destroying 13149 // activities causes more harm than good. 13150 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13151 && app != mHomeProcess && app != mPreviousProcess) { 13152 // Need to do this on its own message because the stack may not 13153 // be in a consistent state at this point. 13154 // For these apps we will also finish their activities 13155 // to help them free memory. 13156 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13157 } 13158 } 13159 } 13160 app.trimMemoryLevel = curLevel; 13161 step++; 13162 if (step >= factor) { 13163 step = 0; 13164 switch (curLevel) { 13165 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13166 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13167 break; 13168 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13169 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13170 break; 13171 } 13172 } 13173 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13174 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13175 && app.thread != null) { 13176 try { 13177 app.thread.scheduleTrimMemory( 13178 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13179 } catch (RemoteException e) { 13180 } 13181 } 13182 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13183 } else { 13184 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13185 && app.pendingUiClean) { 13186 // If this application is now in the background and it 13187 // had done UI, then give it the special trim level to 13188 // have it free UI resources. 13189 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13190 if (app.trimMemoryLevel < level && app.thread != null) { 13191 try { 13192 app.thread.scheduleTrimMemory(level); 13193 } catch (RemoteException e) { 13194 } 13195 } 13196 app.pendingUiClean = false; 13197 } 13198 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13199 try { 13200 app.thread.scheduleTrimMemory(fgTrimLevel); 13201 } catch (RemoteException e) { 13202 } 13203 } 13204 app.trimMemoryLevel = fgTrimLevel; 13205 } 13206 } 13207 } else { 13208 final int N = mLruProcesses.size(); 13209 for (i=0; i<N; i++) { 13210 ProcessRecord app = mLruProcesses.get(i); 13211 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13212 && app.pendingUiClean) { 13213 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13214 && app.thread != null) { 13215 try { 13216 app.thread.scheduleTrimMemory( 13217 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13218 } catch (RemoteException e) { 13219 } 13220 } 13221 app.pendingUiClean = false; 13222 } 13223 app.trimMemoryLevel = 0; 13224 } 13225 } 13226 13227 if (mAlwaysFinishActivities) { 13228 // Need to do this on its own message because the stack may not 13229 // be in a consistent state at this point. 13230 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13231 } 13232 } 13233 13234 final void trimApplications() { 13235 synchronized (this) { 13236 int i; 13237 13238 // First remove any unused application processes whose package 13239 // has been removed. 13240 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13241 final ProcessRecord app = mRemovedProcesses.get(i); 13242 if (app.activities.size() == 0 13243 && app.curReceiver == null && app.services.size() == 0) { 13244 Slog.i( 13245 TAG, "Exiting empty application process " 13246 + app.processName + " (" 13247 + (app.thread != null ? app.thread.asBinder() : null) 13248 + ")\n"); 13249 if (app.pid > 0 && app.pid != MY_PID) { 13250 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13251 app.processName, app.setAdj, "empty"); 13252 Process.killProcessQuiet(app.pid); 13253 } else { 13254 try { 13255 app.thread.scheduleExit(); 13256 } catch (Exception e) { 13257 // Ignore exceptions. 13258 } 13259 } 13260 cleanUpApplicationRecordLocked(app, false, true, -1); 13261 mRemovedProcesses.remove(i); 13262 13263 if (app.persistent) { 13264 if (app.persistent) { 13265 addAppLocked(app.info, false); 13266 } 13267 } 13268 } 13269 } 13270 13271 // Now update the oom adj for all processes. 13272 updateOomAdjLocked(); 13273 } 13274 } 13275 13276 /** This method sends the specified signal to each of the persistent apps */ 13277 public void signalPersistentProcesses(int sig) throws RemoteException { 13278 if (sig != Process.SIGNAL_USR1) { 13279 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13280 } 13281 13282 synchronized (this) { 13283 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13284 != PackageManager.PERMISSION_GRANTED) { 13285 throw new SecurityException("Requires permission " 13286 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13287 } 13288 13289 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13290 ProcessRecord r = mLruProcesses.get(i); 13291 if (r.thread != null && r.persistent) { 13292 Process.sendSignal(r.pid, sig); 13293 } 13294 } 13295 } 13296 } 13297 13298 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13299 if (proc == null || proc == mProfileProc) { 13300 proc = mProfileProc; 13301 path = mProfileFile; 13302 profileType = mProfileType; 13303 clearProfilerLocked(); 13304 } 13305 if (proc == null) { 13306 return; 13307 } 13308 try { 13309 proc.thread.profilerControl(false, path, null, profileType); 13310 } catch (RemoteException e) { 13311 throw new IllegalStateException("Process disappeared"); 13312 } 13313 } 13314 13315 private void clearProfilerLocked() { 13316 if (mProfileFd != null) { 13317 try { 13318 mProfileFd.close(); 13319 } catch (IOException e) { 13320 } 13321 } 13322 mProfileApp = null; 13323 mProfileProc = null; 13324 mProfileFile = null; 13325 mProfileType = 0; 13326 mAutoStopProfiler = false; 13327 } 13328 13329 public boolean profileControl(String process, boolean start, 13330 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13331 13332 try { 13333 synchronized (this) { 13334 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13335 // its own permission. 13336 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13337 != PackageManager.PERMISSION_GRANTED) { 13338 throw new SecurityException("Requires permission " 13339 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13340 } 13341 13342 if (start && fd == null) { 13343 throw new IllegalArgumentException("null fd"); 13344 } 13345 13346 ProcessRecord proc = null; 13347 if (process != null) { 13348 try { 13349 int pid = Integer.parseInt(process); 13350 synchronized (mPidsSelfLocked) { 13351 proc = mPidsSelfLocked.get(pid); 13352 } 13353 } catch (NumberFormatException e) { 13354 } 13355 13356 if (proc == null) { 13357 HashMap<String, SparseArray<ProcessRecord>> all 13358 = mProcessNames.getMap(); 13359 SparseArray<ProcessRecord> procs = all.get(process); 13360 if (procs != null && procs.size() > 0) { 13361 proc = procs.valueAt(0); 13362 } 13363 } 13364 } 13365 13366 if (start && (proc == null || proc.thread == null)) { 13367 throw new IllegalArgumentException("Unknown process: " + process); 13368 } 13369 13370 if (start) { 13371 stopProfilerLocked(null, null, 0); 13372 setProfileApp(proc.info, proc.processName, path, fd, false); 13373 mProfileProc = proc; 13374 mProfileType = profileType; 13375 try { 13376 fd = fd.dup(); 13377 } catch (IOException e) { 13378 fd = null; 13379 } 13380 proc.thread.profilerControl(start, path, fd, profileType); 13381 fd = null; 13382 mProfileFd = null; 13383 } else { 13384 stopProfilerLocked(proc, path, profileType); 13385 if (fd != null) { 13386 try { 13387 fd.close(); 13388 } catch (IOException e) { 13389 } 13390 } 13391 } 13392 13393 return true; 13394 } 13395 } catch (RemoteException e) { 13396 throw new IllegalStateException("Process disappeared"); 13397 } finally { 13398 if (fd != null) { 13399 try { 13400 fd.close(); 13401 } catch (IOException e) { 13402 } 13403 } 13404 } 13405 } 13406 13407 public boolean dumpHeap(String process, boolean managed, 13408 String path, ParcelFileDescriptor fd) throws RemoteException { 13409 13410 try { 13411 synchronized (this) { 13412 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13413 // its own permission (same as profileControl). 13414 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13415 != PackageManager.PERMISSION_GRANTED) { 13416 throw new SecurityException("Requires permission " 13417 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13418 } 13419 13420 if (fd == null) { 13421 throw new IllegalArgumentException("null fd"); 13422 } 13423 13424 ProcessRecord proc = null; 13425 try { 13426 int pid = Integer.parseInt(process); 13427 synchronized (mPidsSelfLocked) { 13428 proc = mPidsSelfLocked.get(pid); 13429 } 13430 } catch (NumberFormatException e) { 13431 } 13432 13433 if (proc == null) { 13434 HashMap<String, SparseArray<ProcessRecord>> all 13435 = mProcessNames.getMap(); 13436 SparseArray<ProcessRecord> procs = all.get(process); 13437 if (procs != null && procs.size() > 0) { 13438 proc = procs.valueAt(0); 13439 } 13440 } 13441 13442 if (proc == null || proc.thread == null) { 13443 throw new IllegalArgumentException("Unknown process: " + process); 13444 } 13445 13446 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13447 if (!isDebuggable) { 13448 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13449 throw new SecurityException("Process not debuggable: " + proc); 13450 } 13451 } 13452 13453 proc.thread.dumpHeap(managed, path, fd); 13454 fd = null; 13455 return true; 13456 } 13457 } catch (RemoteException e) { 13458 throw new IllegalStateException("Process disappeared"); 13459 } finally { 13460 if (fd != null) { 13461 try { 13462 fd.close(); 13463 } catch (IOException e) { 13464 } 13465 } 13466 } 13467 } 13468 13469 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13470 public void monitor() { 13471 synchronized (this) { } 13472 } 13473 13474 void onCoreSettingsChange(Bundle settings) { 13475 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13476 ProcessRecord processRecord = mLruProcesses.get(i); 13477 try { 13478 if (processRecord.thread != null) { 13479 processRecord.thread.setCoreSettings(settings); 13480 } 13481 } catch (RemoteException re) { 13482 /* ignore */ 13483 } 13484 } 13485 } 13486 13487 // Multi-user methods 13488 13489 public boolean switchUser(int userId) { 13490 final int callingUid = Binder.getCallingUid(); 13491 if (callingUid != 0 && callingUid != Process.myUid()) { 13492 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13493 return false; 13494 } 13495 if (mCurrentUserId == userId) 13496 return true; 13497 13498 synchronized (this) { 13499 // Check if user is already logged in, otherwise check if user exists first before 13500 // adding to the list of logged in users. 13501 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13502 if (!userExists(userId)) { 13503 return false; 13504 } 13505 mLoggedInUsers.append(userId, userId); 13506 } 13507 13508 mCurrentUserId = userId; 13509 boolean haveActivities = mMainStack.switchUser(userId); 13510 if (!haveActivities) { 13511 startHomeActivityLocked(userId); 13512 } 13513 13514 } 13515 13516 // Inform of user switch 13517 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13518 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13519 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); 13520 13521 return true; 13522 } 13523 13524 @Override 13525 public UserInfo getCurrentUser() throws RemoteException { 13526 final int callingUid = Binder.getCallingUid(); 13527 if (callingUid != 0 && callingUid != Process.myUid()) { 13528 Slog.e(TAG, "Trying to get user from unauthorized app"); 13529 return null; 13530 } 13531 return getUserManager().getUserInfo(mCurrentUserId); 13532 } 13533 13534 private void onUserRemoved(Intent intent) { 13535 int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 13536 if (extraUserId < 1) return; 13537 13538 // Kill all the processes for the user 13539 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13540 synchronized (this) { 13541 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13542 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13543 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13544 for (int i = 0; i < uids.size(); i++) { 13545 if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) { 13546 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13547 } 13548 } 13549 } 13550 13551 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13552 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13553 false, false, true, true, extraUserId); 13554 } 13555 } 13556 } 13557 13558 private boolean userExists(int userId) { 13559 UserInfo user = getUserManager().getUserInfo(userId); 13560 return user != null; 13561 } 13562 13563 UserManager getUserManager() { 13564 if (mUserManager == null) { 13565 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13566 } 13567 return mUserManager; 13568 } 13569 13570 private void checkValidCaller(int uid, int userId) { 13571 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13572 13573 throw new SecurityException("Caller uid=" + uid 13574 + " is not privileged to communicate with user=" + userId); 13575 } 13576 13577 private int applyUserId(int uid, int userId) { 13578 return UserHandle.getUid(userId, uid); 13579 } 13580 13581 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13582 if (info == null) return null; 13583 ApplicationInfo newInfo = new ApplicationInfo(info); 13584 newInfo.uid = applyUserId(info.uid, userId); 13585 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13586 + info.packageName; 13587 return newInfo; 13588 } 13589 13590 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13591 if (aInfo == null 13592 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13593 return aInfo; 13594 } 13595 13596 ActivityInfo info = new ActivityInfo(aInfo); 13597 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13598 return info; 13599 } 13600} 13601