ActivityManagerService.java revision 2bca868361b41ff6a8228824cbecadc4c5deb44e
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.ServiceManager; 109import android.os.StrictMode; 110import android.os.SystemClock; 111import android.os.SystemProperties; 112import android.os.UserHandle; 113import android.os.UserManager; 114import android.provider.Settings; 115import android.text.format.Time; 116import android.util.EventLog; 117import android.util.Log; 118import android.util.Pair; 119import android.util.PrintWriterPrinter; 120import android.util.Slog; 121import android.util.SparseArray; 122import android.util.SparseIntArray; 123import android.util.TimeUtils; 124import android.view.Gravity; 125import android.view.LayoutInflater; 126import android.view.View; 127import android.view.WindowManager; 128import android.view.WindowManagerPolicy; 129 130import java.io.BufferedInputStream; 131import java.io.BufferedOutputStream; 132import java.io.BufferedReader; 133import java.io.DataInputStream; 134import java.io.DataOutputStream; 135import java.io.File; 136import java.io.FileDescriptor; 137import java.io.FileInputStream; 138import java.io.FileNotFoundException; 139import java.io.FileOutputStream; 140import java.io.IOException; 141import java.io.InputStreamReader; 142import java.io.PrintWriter; 143import java.io.StringWriter; 144import java.lang.ref.WeakReference; 145import java.util.ArrayList; 146import java.util.Collections; 147import java.util.Comparator; 148import java.util.HashMap; 149import java.util.HashSet; 150import java.util.Iterator; 151import java.util.List; 152import java.util.Locale; 153import java.util.Map; 154import java.util.Map.Entry; 155import java.util.Set; 156import java.util.concurrent.atomic.AtomicBoolean; 157import java.util.concurrent.atomic.AtomicLong; 158 159public final class ActivityManagerService extends ActivityManagerNative 160 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 161 private static final String USER_DATA_DIR = "/data/user/"; 162 static final String TAG = "ActivityManager"; 163 static final String TAG_MU = "ActivityManagerServiceMU"; 164 static final boolean DEBUG = false; 165 static final boolean localLOGV = DEBUG; 166 static final boolean DEBUG_SWITCH = localLOGV || false; 167 static final boolean DEBUG_TASKS = localLOGV || false; 168 static final boolean DEBUG_PAUSE = localLOGV || false; 169 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 170 static final boolean DEBUG_TRANSITION = localLOGV || false; 171 static final boolean DEBUG_BROADCAST = localLOGV || false; 172 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 173 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_SERVICE = localLOGV || false; 175 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 176 static final boolean DEBUG_VISBILITY = localLOGV || false; 177 static final boolean DEBUG_PROCESSES = localLOGV || false; 178 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 179 static final boolean DEBUG_PROVIDER = localLOGV || false; 180 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 181 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 182 static final boolean DEBUG_RESULTS = localLOGV || false; 183 static final boolean DEBUG_BACKUP = localLOGV || false; 184 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 185 static final boolean DEBUG_POWER = localLOGV || false; 186 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 187 static final boolean DEBUG_MU = localLOGV || false; 188 static final boolean VALIDATE_TOKENS = false; 189 static final boolean SHOW_ACTIVITY_START_TIME = true; 190 191 // Control over CPU and battery monitoring. 192 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 193 static final boolean MONITOR_CPU_USAGE = true; 194 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 195 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 196 static final boolean MONITOR_THREAD_CPU_USAGE = false; 197 198 // The flags that are set for all calls we make to the package manager. 199 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 200 201 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 202 203 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 204 205 // Maximum number of recent tasks that we can remember. 206 static final int MAX_RECENT_TASKS = 20; 207 208 // Amount of time after a call to stopAppSwitches() during which we will 209 // prevent further untrusted switches from happening. 210 static final long APP_SWITCH_DELAY_TIME = 5*1000; 211 212 // How long we wait for a launched process to attach to the activity manager 213 // before we decide it's never going to come up for real. 214 static final int PROC_START_TIMEOUT = 10*1000; 215 216 // How long we wait for a launched process to attach to the activity manager 217 // before we decide it's never going to come up for real, when the process was 218 // started with a wrapper for instrumentation (such as Valgrind) because it 219 // could take much longer than usual. 220 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 221 222 // How long to wait after going idle before forcing apps to GC. 223 static final int GC_TIMEOUT = 5*1000; 224 225 // The minimum amount of time between successive GC requests for a process. 226 static final int GC_MIN_INTERVAL = 60*1000; 227 228 // The rate at which we check for apps using excessive power -- 15 mins. 229 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 230 231 // The minimum sample duration we will allow before deciding we have 232 // enough data on wake locks to start killing things. 233 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 234 235 // The minimum sample duration we will allow before deciding we have 236 // enough data on CPU usage to start killing things. 237 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 238 239 // How long we allow a receiver to run before giving up on it. 240 static final int BROADCAST_FG_TIMEOUT = 10*1000; 241 static final int BROADCAST_BG_TIMEOUT = 60*1000; 242 243 // How long we wait until we timeout on key dispatching. 244 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 245 246 // How long we wait until we timeout on key dispatching during instrumentation. 247 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 248 249 static final int MY_PID = Process.myPid(); 250 251 static final String[] EMPTY_STRING_ARRAY = new String[0]; 252 253 public ActivityStack mMainStack; 254 255 private final boolean mHeadless; 256 257 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 258 // default actuion automatically. Important for devices without direct input 259 // devices. 260 private boolean mShowDialogs = true; 261 262 /** 263 * Description of a request to start a new activity, which has been held 264 * due to app switches being disabled. 265 */ 266 static class PendingActivityLaunch { 267 ActivityRecord r; 268 ActivityRecord sourceRecord; 269 int startFlags; 270 } 271 272 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 273 = new ArrayList<PendingActivityLaunch>(); 274 275 276 BroadcastQueue mFgBroadcastQueue; 277 BroadcastQueue mBgBroadcastQueue; 278 // Convenient for easy iteration over the queues. Foreground is first 279 // so that dispatch of foreground broadcasts gets precedence. 280 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 281 282 BroadcastQueue broadcastQueueForIntent(Intent intent) { 283 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 284 if (DEBUG_BACKGROUND_BROADCAST) { 285 Slog.i(TAG, "Broadcast intent " + intent + " on " 286 + (isFg ? "foreground" : "background") 287 + " queue"); 288 } 289 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 290 } 291 292 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 293 for (BroadcastQueue queue : mBroadcastQueues) { 294 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 295 if (r != null) { 296 return r; 297 } 298 } 299 return null; 300 } 301 302 /** 303 * Activity we have told the window manager to have key focus. 304 */ 305 ActivityRecord mFocusedActivity = null; 306 /** 307 * List of intents that were used to start the most recent tasks. 308 */ 309 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 310 311 /** 312 * Process management. 313 */ 314 final ProcessList mProcessList = new ProcessList(); 315 316 /** 317 * All of the applications we currently have running organized by name. 318 * The keys are strings of the application package name (as 319 * returned by the package manager), and the keys are ApplicationRecord 320 * objects. 321 */ 322 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 323 324 /** 325 * The currently running isolated processes. 326 */ 327 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 328 329 /** 330 * Counter for assigning isolated process uids, to avoid frequently reusing the 331 * same ones. 332 */ 333 int mNextIsolatedProcessUid = 0; 334 335 /** 336 * The currently running heavy-weight process, if any. 337 */ 338 ProcessRecord mHeavyWeightProcess = null; 339 340 /** 341 * The last time that various processes have crashed. 342 */ 343 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 344 345 /** 346 * Set of applications that we consider to be bad, and will reject 347 * incoming broadcasts from (which the user has no control over). 348 * Processes are added to this set when they have crashed twice within 349 * a minimum amount of time; they are removed from it when they are 350 * later restarted (hopefully due to some user action). The value is the 351 * time it was added to the list. 352 */ 353 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 354 355 /** 356 * All of the processes we currently have running organized by pid. 357 * The keys are the pid running the application. 358 * 359 * <p>NOTE: This object is protected by its own lock, NOT the global 360 * activity manager lock! 361 */ 362 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 363 364 /** 365 * All of the processes that have been forced to be foreground. The key 366 * is the pid of the caller who requested it (we hold a death 367 * link on it). 368 */ 369 abstract class ForegroundToken implements IBinder.DeathRecipient { 370 int pid; 371 IBinder token; 372 } 373 final SparseArray<ForegroundToken> mForegroundProcesses 374 = new SparseArray<ForegroundToken>(); 375 376 /** 377 * List of records for processes that someone had tried to start before the 378 * system was ready. We don't start them at that point, but ensure they 379 * are started by the time booting is complete. 380 */ 381 final ArrayList<ProcessRecord> mProcessesOnHold 382 = new ArrayList<ProcessRecord>(); 383 384 /** 385 * List of persistent applications that are in the process 386 * of being started. 387 */ 388 final ArrayList<ProcessRecord> mPersistentStartingProcesses 389 = new ArrayList<ProcessRecord>(); 390 391 /** 392 * Processes that are being forcibly torn down. 393 */ 394 final ArrayList<ProcessRecord> mRemovedProcesses 395 = new ArrayList<ProcessRecord>(); 396 397 /** 398 * List of running applications, sorted by recent usage. 399 * The first entry in the list is the least recently used. 400 * It contains ApplicationRecord objects. This list does NOT include 401 * any persistent application records (since we never want to exit them). 402 */ 403 final ArrayList<ProcessRecord> mLruProcesses 404 = new ArrayList<ProcessRecord>(); 405 406 /** 407 * List of processes that should gc as soon as things are idle. 408 */ 409 final ArrayList<ProcessRecord> mProcessesToGc 410 = new ArrayList<ProcessRecord>(); 411 412 /** 413 * This is the process holding what we currently consider to be 414 * the "home" activity. 415 */ 416 ProcessRecord mHomeProcess; 417 418 /** 419 * This is the process holding the activity the user last visited that 420 * is in a different process from the one they are currently in. 421 */ 422 ProcessRecord mPreviousProcess; 423 424 /** 425 * The time at which the previous process was last visible. 426 */ 427 long mPreviousProcessVisibleTime; 428 429 /** 430 * Packages that the user has asked to have run in screen size 431 * compatibility mode instead of filling the screen. 432 */ 433 final CompatModePackages mCompatModePackages; 434 435 /** 436 * Set of PendingResultRecord objects that are currently active. 437 */ 438 final HashSet mPendingResultRecords = new HashSet(); 439 440 /** 441 * Set of IntentSenderRecord objects that are currently active. 442 */ 443 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 444 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 445 446 /** 447 * Fingerprints (hashCode()) of stack traces that we've 448 * already logged DropBox entries for. Guarded by itself. If 449 * something (rogue user app) forces this over 450 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 451 */ 452 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 453 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 454 455 /** 456 * Strict Mode background batched logging state. 457 * 458 * The string buffer is guarded by itself, and its lock is also 459 * used to determine if another batched write is already 460 * in-flight. 461 */ 462 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 463 464 /** 465 * Keeps track of all IIntentReceivers that have been registered for 466 * broadcasts. Hash keys are the receiver IBinder, hash value is 467 * a ReceiverList. 468 */ 469 final HashMap mRegisteredReceivers = new HashMap(); 470 471 /** 472 * Resolver for broadcast intents to registered receivers. 473 * Holds BroadcastFilter (subclass of IntentFilter). 474 */ 475 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 476 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 477 @Override 478 protected boolean allowFilterResult( 479 BroadcastFilter filter, List<BroadcastFilter> dest) { 480 IBinder target = filter.receiverList.receiver.asBinder(); 481 for (int i=dest.size()-1; i>=0; i--) { 482 if (dest.get(i).receiverList.receiver.asBinder() == target) { 483 return false; 484 } 485 } 486 return true; 487 } 488 489 @Override 490 protected BroadcastFilter[] newArray(int size) { 491 return new BroadcastFilter[size]; 492 } 493 494 @Override 495 protected String packageForFilter(BroadcastFilter filter) { 496 return filter.packageName; 497 } 498 }; 499 500 /** 501 * State of all active sticky broadcasts. Keys are the action of the 502 * sticky Intent, values are an ArrayList of all broadcasted intents with 503 * that action (which should usually be one). 504 */ 505 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 506 new HashMap<String, ArrayList<Intent>>(); 507 508 final ActiveServices mServices; 509 510 /** 511 * Backup/restore process management 512 */ 513 String mBackupAppName = null; 514 BackupRecord mBackupTarget = null; 515 516 /** 517 * List of PendingThumbnailsRecord objects of clients who are still 518 * waiting to receive all of the thumbnails for a task. 519 */ 520 final ArrayList mPendingThumbnails = new ArrayList(); 521 522 /** 523 * List of HistoryRecord objects that have been finished and must 524 * still report back to a pending thumbnail receiver. 525 */ 526 final ArrayList mCancelledThumbnails = new ArrayList(); 527 528 final ProviderMap mProviderMap = new ProviderMap(); 529 530 /** 531 * List of content providers who have clients waiting for them. The 532 * application is currently being launched and the provider will be 533 * removed from this list once it is published. 534 */ 535 final ArrayList<ContentProviderRecord> mLaunchingProviders 536 = new ArrayList<ContentProviderRecord>(); 537 538 /** 539 * Global set of specific Uri permissions that have been granted. 540 */ 541 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 542 = new SparseArray<HashMap<Uri, UriPermission>>(); 543 544 CoreSettingsObserver mCoreSettingsObserver; 545 546 /** 547 * Thread-local storage used to carry caller permissions over through 548 * indirect content-provider access. 549 * @see #ActivityManagerService.openContentUri() 550 */ 551 private class Identity { 552 public int pid; 553 public int uid; 554 555 Identity(int _pid, int _uid) { 556 pid = _pid; 557 uid = _uid; 558 } 559 } 560 561 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 562 563 /** 564 * All information we have collected about the runtime performance of 565 * any user id that can impact battery performance. 566 */ 567 final BatteryStatsService mBatteryStatsService; 568 569 /** 570 * information about component usage 571 */ 572 final UsageStatsService mUsageStatsService; 573 574 /** 575 * Current configuration information. HistoryRecord objects are given 576 * a reference to this object to indicate which configuration they are 577 * currently running in, so this object must be kept immutable. 578 */ 579 Configuration mConfiguration = new Configuration(); 580 581 /** 582 * Current sequencing integer of the configuration, for skipping old 583 * configurations. 584 */ 585 int mConfigurationSeq = 0; 586 587 /** 588 * Hardware-reported OpenGLES version. 589 */ 590 final int GL_ES_VERSION; 591 592 /** 593 * List of initialization arguments to pass to all processes when binding applications to them. 594 * For example, references to the commonly used services. 595 */ 596 HashMap<String, IBinder> mAppBindArgs; 597 598 /** 599 * Temporary to avoid allocations. Protected by main lock. 600 */ 601 final StringBuilder mStringBuilder = new StringBuilder(256); 602 603 /** 604 * Used to control how we initialize the service. 605 */ 606 boolean mStartRunning = false; 607 ComponentName mTopComponent; 608 String mTopAction; 609 String mTopData; 610 boolean mProcessesReady = false; 611 boolean mSystemReady = false; 612 boolean mBooting = false; 613 boolean mWaitingUpdate = false; 614 boolean mDidUpdate = false; 615 boolean mOnBattery = false; 616 boolean mLaunchWarningShown = false; 617 618 Context mContext; 619 620 int mFactoryTest; 621 622 boolean mCheckedForSetup; 623 624 /** 625 * The time at which we will allow normal application switches again, 626 * after a call to {@link #stopAppSwitches()}. 627 */ 628 long mAppSwitchesAllowedTime; 629 630 /** 631 * This is set to true after the first switch after mAppSwitchesAllowedTime 632 * is set; any switches after that will clear the time. 633 */ 634 boolean mDidAppSwitch; 635 636 /** 637 * Last time (in realtime) at which we checked for power usage. 638 */ 639 long mLastPowerCheckRealtime; 640 641 /** 642 * Last time (in uptime) at which we checked for power usage. 643 */ 644 long mLastPowerCheckUptime; 645 646 /** 647 * Set while we are wanting to sleep, to prevent any 648 * activities from being started/resumed. 649 */ 650 boolean mSleeping = false; 651 652 /** 653 * State of external calls telling us if the device is asleep. 654 */ 655 boolean mWentToSleep = false; 656 657 /** 658 * State of external call telling us if the lock screen is shown. 659 */ 660 boolean mLockScreenShown = false; 661 662 /** 663 * Set if we are shutting down the system, similar to sleeping. 664 */ 665 boolean mShuttingDown = false; 666 667 /** 668 * Task identifier that activities are currently being started 669 * in. Incremented each time a new task is created. 670 * todo: Replace this with a TokenSpace class that generates non-repeating 671 * integers that won't wrap. 672 */ 673 int mCurTask = 1; 674 675 /** 676 * Current sequence id for oom_adj computation traversal. 677 */ 678 int mAdjSeq = 0; 679 680 /** 681 * Current sequence id for process LRU updating. 682 */ 683 int mLruSeq = 0; 684 685 /** 686 * Keep track of the non-hidden/empty process we last found, to help 687 * determine how to distribute hidden/empty processes next time. 688 */ 689 int mNumNonHiddenProcs = 0; 690 691 /** 692 * Keep track of the number of hidden procs, to balance oom adj 693 * distribution between those and empty procs. 694 */ 695 int mNumHiddenProcs = 0; 696 697 /** 698 * Keep track of the number of service processes we last found, to 699 * determine on the next iteration which should be B services. 700 */ 701 int mNumServiceProcs = 0; 702 int mNewNumServiceProcs = 0; 703 704 /** 705 * System monitoring: number of processes that died since the last 706 * N procs were started. 707 */ 708 int[] mProcDeaths = new int[20]; 709 710 /** 711 * This is set if we had to do a delayed dexopt of an app before launching 712 * it, to increasing the ANR timeouts in that case. 713 */ 714 boolean mDidDexOpt; 715 716 String mDebugApp = null; 717 boolean mWaitForDebugger = false; 718 boolean mDebugTransient = false; 719 String mOrigDebugApp = null; 720 boolean mOrigWaitForDebugger = false; 721 boolean mAlwaysFinishActivities = false; 722 IActivityController mController = null; 723 String mProfileApp = null; 724 ProcessRecord mProfileProc = null; 725 String mProfileFile; 726 ParcelFileDescriptor mProfileFd; 727 int mProfileType = 0; 728 boolean mAutoStopProfiler = false; 729 String mOpenGlTraceApp = null; 730 731 static class ProcessChangeItem { 732 static final int CHANGE_ACTIVITIES = 1<<0; 733 static final int CHANGE_IMPORTANCE= 1<<1; 734 int changes; 735 int uid; 736 int pid; 737 int importance; 738 boolean foregroundActivities; 739 } 740 741 final RemoteCallbackList<IProcessObserver> mProcessObservers 742 = new RemoteCallbackList<IProcessObserver>(); 743 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 744 745 final ArrayList<ProcessChangeItem> mPendingProcessChanges 746 = new ArrayList<ProcessChangeItem>(); 747 final ArrayList<ProcessChangeItem> mAvailProcessChanges 748 = new ArrayList<ProcessChangeItem>(); 749 750 /** 751 * Callback of last caller to {@link #requestPss}. 752 */ 753 Runnable mRequestPssCallback; 754 755 /** 756 * Remaining processes for which we are waiting results from the last 757 * call to {@link #requestPss}. 758 */ 759 final ArrayList<ProcessRecord> mRequestPssList 760 = new ArrayList<ProcessRecord>(); 761 762 /** 763 * Runtime statistics collection thread. This object's lock is used to 764 * protect all related state. 765 */ 766 final Thread mProcessStatsThread; 767 768 /** 769 * Used to collect process stats when showing not responding dialog. 770 * Protected by mProcessStatsThread. 771 */ 772 final ProcessStats mProcessStats = new ProcessStats( 773 MONITOR_THREAD_CPU_USAGE); 774 final AtomicLong mLastCpuTime = new AtomicLong(0); 775 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 776 777 long mLastWriteTime = 0; 778 779 /** 780 * Set to true after the system has finished booting. 781 */ 782 boolean mBooted = false; 783 784 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 785 int mProcessLimitOverride = -1; 786 787 WindowManagerService mWindowManager; 788 789 static ActivityManagerService mSelf; 790 static ActivityThread mSystemThread; 791 792 private int mCurrentUserId; 793 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 794 private UserManager mUserManager; 795 796 private final class AppDeathRecipient implements IBinder.DeathRecipient { 797 final ProcessRecord mApp; 798 final int mPid; 799 final IApplicationThread mAppThread; 800 801 AppDeathRecipient(ProcessRecord app, int pid, 802 IApplicationThread thread) { 803 if (localLOGV) Slog.v( 804 TAG, "New death recipient " + this 805 + " for thread " + thread.asBinder()); 806 mApp = app; 807 mPid = pid; 808 mAppThread = thread; 809 } 810 811 public void binderDied() { 812 if (localLOGV) Slog.v( 813 TAG, "Death received in " + this 814 + " for thread " + mAppThread.asBinder()); 815 synchronized(ActivityManagerService.this) { 816 appDiedLocked(mApp, mPid, mAppThread); 817 } 818 } 819 } 820 821 static final int SHOW_ERROR_MSG = 1; 822 static final int SHOW_NOT_RESPONDING_MSG = 2; 823 static final int SHOW_FACTORY_ERROR_MSG = 3; 824 static final int UPDATE_CONFIGURATION_MSG = 4; 825 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 826 static final int WAIT_FOR_DEBUGGER_MSG = 6; 827 static final int SERVICE_TIMEOUT_MSG = 12; 828 static final int UPDATE_TIME_ZONE = 13; 829 static final int SHOW_UID_ERROR_MSG = 14; 830 static final int IM_FEELING_LUCKY_MSG = 15; 831 static final int PROC_START_TIMEOUT_MSG = 20; 832 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 833 static final int KILL_APPLICATION_MSG = 22; 834 static final int FINALIZE_PENDING_INTENT_MSG = 23; 835 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 836 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 837 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 838 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 839 static final int CLEAR_DNS_CACHE = 28; 840 static final int UPDATE_HTTP_PROXY = 29; 841 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 842 static final int DISPATCH_PROCESSES_CHANGED = 31; 843 static final int DISPATCH_PROCESS_DIED = 32; 844 static final int REPORT_MEM_USAGE = 33; 845 846 static final int FIRST_ACTIVITY_STACK_MSG = 100; 847 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 848 static final int FIRST_COMPAT_MODE_MSG = 300; 849 850 AlertDialog mUidAlert; 851 CompatModeDialog mCompatModeDialog; 852 long mLastMemUsageReportTime = 0; 853 854 final Handler mHandler = new Handler() { 855 //public Handler() { 856 // if (localLOGV) Slog.v(TAG, "Handler started!"); 857 //} 858 859 public void handleMessage(Message msg) { 860 switch (msg.what) { 861 case SHOW_ERROR_MSG: { 862 HashMap data = (HashMap) msg.obj; 863 synchronized (ActivityManagerService.this) { 864 ProcessRecord proc = (ProcessRecord)data.get("app"); 865 if (proc != null && proc.crashDialog != null) { 866 Slog.e(TAG, "App already has crash dialog: " + proc); 867 return; 868 } 869 AppErrorResult res = (AppErrorResult) data.get("result"); 870 if (mShowDialogs && !mSleeping && !mShuttingDown) { 871 Dialog d = new AppErrorDialog(mContext, res, proc); 872 d.show(); 873 proc.crashDialog = d; 874 } else { 875 // The device is asleep, so just pretend that the user 876 // saw a crash dialog and hit "force quit". 877 res.set(0); 878 } 879 } 880 881 ensureBootCompleted(); 882 } break; 883 case SHOW_NOT_RESPONDING_MSG: { 884 synchronized (ActivityManagerService.this) { 885 HashMap data = (HashMap) msg.obj; 886 ProcessRecord proc = (ProcessRecord)data.get("app"); 887 if (proc != null && proc.anrDialog != null) { 888 Slog.e(TAG, "App already has anr dialog: " + proc); 889 return; 890 } 891 892 Intent intent = new Intent("android.intent.action.ANR"); 893 if (!mProcessesReady) { 894 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 895 | Intent.FLAG_RECEIVER_FOREGROUND); 896 } 897 broadcastIntentLocked(null, null, intent, 898 null, null, 0, null, null, null, 899 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 900 901 if (mShowDialogs) { 902 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 903 mContext, proc, (ActivityRecord)data.get("activity")); 904 d.show(); 905 proc.anrDialog = d; 906 } else { 907 // Just kill the app if there is no dialog to be shown. 908 killAppAtUsersRequest(proc, null); 909 } 910 } 911 912 ensureBootCompleted(); 913 } break; 914 case SHOW_STRICT_MODE_VIOLATION_MSG: { 915 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 916 synchronized (ActivityManagerService.this) { 917 ProcessRecord proc = (ProcessRecord) data.get("app"); 918 if (proc == null) { 919 Slog.e(TAG, "App not found when showing strict mode dialog."); 920 break; 921 } 922 if (proc.crashDialog != null) { 923 Slog.e(TAG, "App already has strict mode dialog: " + proc); 924 return; 925 } 926 AppErrorResult res = (AppErrorResult) data.get("result"); 927 if (mShowDialogs && !mSleeping && !mShuttingDown) { 928 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 929 d.show(); 930 proc.crashDialog = d; 931 } else { 932 // The device is asleep, so just pretend that the user 933 // saw a crash dialog and hit "force quit". 934 res.set(0); 935 } 936 } 937 ensureBootCompleted(); 938 } break; 939 case SHOW_FACTORY_ERROR_MSG: { 940 Dialog d = new FactoryErrorDialog( 941 mContext, msg.getData().getCharSequence("msg")); 942 d.show(); 943 ensureBootCompleted(); 944 } break; 945 case UPDATE_CONFIGURATION_MSG: { 946 final ContentResolver resolver = mContext.getContentResolver(); 947 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 948 } break; 949 case GC_BACKGROUND_PROCESSES_MSG: { 950 synchronized (ActivityManagerService.this) { 951 performAppGcsIfAppropriateLocked(); 952 } 953 } break; 954 case WAIT_FOR_DEBUGGER_MSG: { 955 synchronized (ActivityManagerService.this) { 956 ProcessRecord app = (ProcessRecord)msg.obj; 957 if (msg.arg1 != 0) { 958 if (!app.waitedForDebugger) { 959 Dialog d = new AppWaitingForDebuggerDialog( 960 ActivityManagerService.this, 961 mContext, app); 962 app.waitDialog = d; 963 app.waitedForDebugger = true; 964 d.show(); 965 } 966 } else { 967 if (app.waitDialog != null) { 968 app.waitDialog.dismiss(); 969 app.waitDialog = null; 970 } 971 } 972 } 973 } break; 974 case SERVICE_TIMEOUT_MSG: { 975 if (mDidDexOpt) { 976 mDidDexOpt = false; 977 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 978 nmsg.obj = msg.obj; 979 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 980 return; 981 } 982 mServices.serviceTimeout((ProcessRecord)msg.obj); 983 } break; 984 case UPDATE_TIME_ZONE: { 985 synchronized (ActivityManagerService.this) { 986 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 987 ProcessRecord r = mLruProcesses.get(i); 988 if (r.thread != null) { 989 try { 990 r.thread.updateTimeZone(); 991 } catch (RemoteException ex) { 992 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 993 } 994 } 995 } 996 } 997 } break; 998 case CLEAR_DNS_CACHE: { 999 synchronized (ActivityManagerService.this) { 1000 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1001 ProcessRecord r = mLruProcesses.get(i); 1002 if (r.thread != null) { 1003 try { 1004 r.thread.clearDnsCache(); 1005 } catch (RemoteException ex) { 1006 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1007 } 1008 } 1009 } 1010 } 1011 } break; 1012 case UPDATE_HTTP_PROXY: { 1013 ProxyProperties proxy = (ProxyProperties)msg.obj; 1014 String host = ""; 1015 String port = ""; 1016 String exclList = ""; 1017 if (proxy != null) { 1018 host = proxy.getHost(); 1019 port = Integer.toString(proxy.getPort()); 1020 exclList = proxy.getExclusionList(); 1021 } 1022 synchronized (ActivityManagerService.this) { 1023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1024 ProcessRecord r = mLruProcesses.get(i); 1025 if (r.thread != null) { 1026 try { 1027 r.thread.setHttpProxy(host, port, exclList); 1028 } catch (RemoteException ex) { 1029 Slog.w(TAG, "Failed to update http proxy for: " + 1030 r.info.processName); 1031 } 1032 } 1033 } 1034 } 1035 } break; 1036 case SHOW_UID_ERROR_MSG: { 1037 String title = "System UIDs Inconsistent"; 1038 String text = "UIDs on the system are inconsistent, you need to wipe your" 1039 + " data partition or your device will be unstable."; 1040 Log.e(TAG, title + ": " + text); 1041 if (mShowDialogs) { 1042 // XXX This is a temporary dialog, no need to localize. 1043 AlertDialog d = new BaseErrorDialog(mContext); 1044 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1045 d.setCancelable(false); 1046 d.setTitle(title); 1047 d.setMessage(text); 1048 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1049 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1050 mUidAlert = d; 1051 d.show(); 1052 } 1053 } break; 1054 case IM_FEELING_LUCKY_MSG: { 1055 if (mUidAlert != null) { 1056 mUidAlert.dismiss(); 1057 mUidAlert = null; 1058 } 1059 } break; 1060 case PROC_START_TIMEOUT_MSG: { 1061 if (mDidDexOpt) { 1062 mDidDexOpt = false; 1063 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1064 nmsg.obj = msg.obj; 1065 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1066 return; 1067 } 1068 ProcessRecord app = (ProcessRecord)msg.obj; 1069 synchronized (ActivityManagerService.this) { 1070 processStartTimedOutLocked(app); 1071 } 1072 } break; 1073 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1074 synchronized (ActivityManagerService.this) { 1075 doPendingActivityLaunchesLocked(true); 1076 } 1077 } break; 1078 case KILL_APPLICATION_MSG: { 1079 synchronized (ActivityManagerService.this) { 1080 int uid = msg.arg1; 1081 boolean restart = (msg.arg2 == 1); 1082 String pkg = (String) msg.obj; 1083 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1084 UserHandle.getUserId(uid)); 1085 } 1086 } break; 1087 case FINALIZE_PENDING_INTENT_MSG: { 1088 ((PendingIntentRecord)msg.obj).completeFinalize(); 1089 } break; 1090 case POST_HEAVY_NOTIFICATION_MSG: { 1091 INotificationManager inm = NotificationManager.getService(); 1092 if (inm == null) { 1093 return; 1094 } 1095 1096 ActivityRecord root = (ActivityRecord)msg.obj; 1097 ProcessRecord process = root.app; 1098 if (process == null) { 1099 return; 1100 } 1101 1102 try { 1103 Context context = mContext.createPackageContext(process.info.packageName, 0); 1104 String text = mContext.getString(R.string.heavy_weight_notification, 1105 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1106 Notification notification = new Notification(); 1107 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1108 notification.when = 0; 1109 notification.flags = Notification.FLAG_ONGOING_EVENT; 1110 notification.tickerText = text; 1111 notification.defaults = 0; // please be quiet 1112 notification.sound = null; 1113 notification.vibrate = null; 1114 notification.setLatestEventInfo(context, text, 1115 mContext.getText(R.string.heavy_weight_notification_detail), 1116 PendingIntent.getActivity(mContext, 0, root.intent, 1117 PendingIntent.FLAG_CANCEL_CURRENT)); 1118 1119 try { 1120 int[] outId = new int[1]; 1121 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1122 notification, outId); 1123 } catch (RuntimeException e) { 1124 Slog.w(ActivityManagerService.TAG, 1125 "Error showing notification for heavy-weight app", e); 1126 } catch (RemoteException e) { 1127 } 1128 } catch (NameNotFoundException e) { 1129 Slog.w(TAG, "Unable to create context for heavy notification", e); 1130 } 1131 } break; 1132 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1133 INotificationManager inm = NotificationManager.getService(); 1134 if (inm == null) { 1135 return; 1136 } 1137 try { 1138 inm.cancelNotification("android", 1139 R.string.heavy_weight_notification); 1140 } catch (RuntimeException e) { 1141 Slog.w(ActivityManagerService.TAG, 1142 "Error canceling notification for service", e); 1143 } catch (RemoteException e) { 1144 } 1145 } break; 1146 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1147 synchronized (ActivityManagerService.this) { 1148 checkExcessivePowerUsageLocked(true); 1149 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1150 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1151 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1152 } 1153 } break; 1154 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1155 synchronized (ActivityManagerService.this) { 1156 ActivityRecord ar = (ActivityRecord)msg.obj; 1157 if (mCompatModeDialog != null) { 1158 if (mCompatModeDialog.mAppInfo.packageName.equals( 1159 ar.info.applicationInfo.packageName)) { 1160 return; 1161 } 1162 mCompatModeDialog.dismiss(); 1163 mCompatModeDialog = null; 1164 } 1165 if (ar != null && false) { 1166 if (mCompatModePackages.getPackageAskCompatModeLocked( 1167 ar.packageName)) { 1168 int mode = mCompatModePackages.computeCompatModeLocked( 1169 ar.info.applicationInfo); 1170 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1171 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1172 mCompatModeDialog = new CompatModeDialog( 1173 ActivityManagerService.this, mContext, 1174 ar.info.applicationInfo); 1175 mCompatModeDialog.show(); 1176 } 1177 } 1178 } 1179 } 1180 break; 1181 } 1182 case DISPATCH_PROCESSES_CHANGED: { 1183 dispatchProcessesChanged(); 1184 break; 1185 } 1186 case DISPATCH_PROCESS_DIED: { 1187 final int pid = msg.arg1; 1188 final int uid = msg.arg2; 1189 dispatchProcessDied(pid, uid); 1190 break; 1191 } 1192 case REPORT_MEM_USAGE: { 1193 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1194 if (!isDebuggable) { 1195 return; 1196 } 1197 synchronized (ActivityManagerService.this) { 1198 long now = SystemClock.uptimeMillis(); 1199 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1200 // Don't report more than every 5 minutes to somewhat 1201 // avoid spamming. 1202 return; 1203 } 1204 mLastMemUsageReportTime = now; 1205 } 1206 Thread thread = new Thread() { 1207 @Override public void run() { 1208 StringBuilder dropBuilder = new StringBuilder(1024); 1209 StringBuilder logBuilder = new StringBuilder(1024); 1210 StringWriter oomSw = new StringWriter(); 1211 PrintWriter oomPw = new PrintWriter(oomSw); 1212 StringWriter catSw = new StringWriter(); 1213 PrintWriter catPw = new PrintWriter(catSw); 1214 String[] emptyArgs = new String[] { }; 1215 StringBuilder tag = new StringBuilder(128); 1216 StringBuilder stack = new StringBuilder(128); 1217 tag.append("Low on memory -- "); 1218 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1219 tag, stack); 1220 dropBuilder.append(stack); 1221 dropBuilder.append('\n'); 1222 dropBuilder.append('\n'); 1223 String oomString = oomSw.toString(); 1224 dropBuilder.append(oomString); 1225 dropBuilder.append('\n'); 1226 logBuilder.append(oomString); 1227 try { 1228 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1229 "procrank", }); 1230 final InputStreamReader converter = new InputStreamReader( 1231 proc.getInputStream()); 1232 BufferedReader in = new BufferedReader(converter); 1233 String line; 1234 while (true) { 1235 line = in.readLine(); 1236 if (line == null) { 1237 break; 1238 } 1239 if (line.length() > 0) { 1240 logBuilder.append(line); 1241 logBuilder.append('\n'); 1242 } 1243 dropBuilder.append(line); 1244 dropBuilder.append('\n'); 1245 } 1246 converter.close(); 1247 } catch (IOException e) { 1248 } 1249 synchronized (ActivityManagerService.this) { 1250 catPw.println(); 1251 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1252 catPw.println(); 1253 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1254 false, false, null); 1255 catPw.println(); 1256 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1257 } 1258 dropBuilder.append(catSw.toString()); 1259 addErrorToDropBox("lowmem", null, "system_server", null, 1260 null, tag.toString(), dropBuilder.toString(), null, null); 1261 Slog.i(TAG, logBuilder.toString()); 1262 synchronized (ActivityManagerService.this) { 1263 long now = SystemClock.uptimeMillis(); 1264 if (mLastMemUsageReportTime < now) { 1265 mLastMemUsageReportTime = now; 1266 } 1267 } 1268 } 1269 }; 1270 thread.start(); 1271 break; 1272 } 1273 } 1274 } 1275 }; 1276 1277 public static void setSystemProcess() { 1278 try { 1279 ActivityManagerService m = mSelf; 1280 1281 ServiceManager.addService("activity", m, true); 1282 ServiceManager.addService("meminfo", new MemBinder(m)); 1283 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1284 ServiceManager.addService("dbinfo", new DbBinder(m)); 1285 if (MONITOR_CPU_USAGE) { 1286 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1287 } 1288 ServiceManager.addService("permission", new PermissionController(m)); 1289 1290 ApplicationInfo info = 1291 mSelf.mContext.getPackageManager().getApplicationInfo( 1292 "android", STOCK_PM_FLAGS); 1293 mSystemThread.installSystemApplicationInfo(info); 1294 1295 synchronized (mSelf) { 1296 ProcessRecord app = mSelf.newProcessRecordLocked( 1297 mSystemThread.getApplicationThread(), info, 1298 info.processName, false); 1299 app.persistent = true; 1300 app.pid = MY_PID; 1301 app.maxAdj = ProcessList.SYSTEM_ADJ; 1302 mSelf.mProcessNames.put(app.processName, app.uid, app); 1303 synchronized (mSelf.mPidsSelfLocked) { 1304 mSelf.mPidsSelfLocked.put(app.pid, app); 1305 } 1306 mSelf.updateLruProcessLocked(app, true, true); 1307 } 1308 } catch (PackageManager.NameNotFoundException e) { 1309 throw new RuntimeException( 1310 "Unable to find android system package", e); 1311 } 1312 } 1313 1314 public void setWindowManager(WindowManagerService wm) { 1315 mWindowManager = wm; 1316 } 1317 1318 public static final Context main(int factoryTest) { 1319 AThread thr = new AThread(); 1320 thr.start(); 1321 1322 synchronized (thr) { 1323 while (thr.mService == null) { 1324 try { 1325 thr.wait(); 1326 } catch (InterruptedException e) { 1327 } 1328 } 1329 } 1330 1331 ActivityManagerService m = thr.mService; 1332 mSelf = m; 1333 ActivityThread at = ActivityThread.systemMain(); 1334 mSystemThread = at; 1335 Context context = at.getSystemContext(); 1336 context.setTheme(android.R.style.Theme_Holo); 1337 m.mContext = context; 1338 m.mFactoryTest = factoryTest; 1339 m.mMainStack = new ActivityStack(m, context, true); 1340 1341 m.mBatteryStatsService.publish(context); 1342 m.mUsageStatsService.publish(context); 1343 1344 synchronized (thr) { 1345 thr.mReady = true; 1346 thr.notifyAll(); 1347 } 1348 1349 m.startRunning(null, null, null, null); 1350 1351 return context; 1352 } 1353 1354 public static ActivityManagerService self() { 1355 return mSelf; 1356 } 1357 1358 static class AThread extends Thread { 1359 ActivityManagerService mService; 1360 boolean mReady = false; 1361 1362 public AThread() { 1363 super("ActivityManager"); 1364 } 1365 1366 public void run() { 1367 Looper.prepare(); 1368 1369 android.os.Process.setThreadPriority( 1370 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1371 android.os.Process.setCanSelfBackground(false); 1372 1373 ActivityManagerService m = new ActivityManagerService(); 1374 1375 synchronized (this) { 1376 mService = m; 1377 notifyAll(); 1378 } 1379 1380 synchronized (this) { 1381 while (!mReady) { 1382 try { 1383 wait(); 1384 } catch (InterruptedException e) { 1385 } 1386 } 1387 } 1388 1389 // For debug builds, log event loop stalls to dropbox for analysis. 1390 if (StrictMode.conditionallyEnableDebugLogging()) { 1391 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1392 } 1393 1394 Looper.loop(); 1395 } 1396 } 1397 1398 static class MemBinder extends Binder { 1399 ActivityManagerService mActivityManagerService; 1400 MemBinder(ActivityManagerService activityManagerService) { 1401 mActivityManagerService = activityManagerService; 1402 } 1403 1404 @Override 1405 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1406 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1407 != PackageManager.PERMISSION_GRANTED) { 1408 pw.println("Permission Denial: can't dump meminfo from from pid=" 1409 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1410 + " without permission " + android.Manifest.permission.DUMP); 1411 return; 1412 } 1413 1414 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1415 false, null, null, null); 1416 } 1417 } 1418 1419 static class GraphicsBinder extends Binder { 1420 ActivityManagerService mActivityManagerService; 1421 GraphicsBinder(ActivityManagerService activityManagerService) { 1422 mActivityManagerService = activityManagerService; 1423 } 1424 1425 @Override 1426 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1427 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1428 != PackageManager.PERMISSION_GRANTED) { 1429 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1430 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1431 + " without permission " + android.Manifest.permission.DUMP); 1432 return; 1433 } 1434 1435 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1436 } 1437 } 1438 1439 static class DbBinder extends Binder { 1440 ActivityManagerService mActivityManagerService; 1441 DbBinder(ActivityManagerService activityManagerService) { 1442 mActivityManagerService = activityManagerService; 1443 } 1444 1445 @Override 1446 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1447 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1448 != PackageManager.PERMISSION_GRANTED) { 1449 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1450 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1451 + " without permission " + android.Manifest.permission.DUMP); 1452 return; 1453 } 1454 1455 mActivityManagerService.dumpDbInfo(fd, pw, args); 1456 } 1457 } 1458 1459 static class CpuBinder extends Binder { 1460 ActivityManagerService mActivityManagerService; 1461 CpuBinder(ActivityManagerService activityManagerService) { 1462 mActivityManagerService = activityManagerService; 1463 } 1464 1465 @Override 1466 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1467 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1468 != PackageManager.PERMISSION_GRANTED) { 1469 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1470 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1471 + " without permission " + android.Manifest.permission.DUMP); 1472 return; 1473 } 1474 1475 synchronized (mActivityManagerService.mProcessStatsThread) { 1476 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1477 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1478 SystemClock.uptimeMillis())); 1479 } 1480 } 1481 } 1482 1483 private ActivityManagerService() { 1484 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1485 1486 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1487 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1488 mBroadcastQueues[0] = mFgBroadcastQueue; 1489 mBroadcastQueues[1] = mBgBroadcastQueue; 1490 1491 mServices = new ActiveServices(this); 1492 1493 File dataDir = Environment.getDataDirectory(); 1494 File systemDir = new File(dataDir, "system"); 1495 systemDir.mkdirs(); 1496 mBatteryStatsService = new BatteryStatsService(new File( 1497 systemDir, "batterystats.bin").toString()); 1498 mBatteryStatsService.getActiveStatistics().readLocked(); 1499 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1500 mOnBattery = DEBUG_POWER ? true 1501 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1502 mBatteryStatsService.getActiveStatistics().setCallback(this); 1503 1504 mUsageStatsService = new UsageStatsService(new File( 1505 systemDir, "usagestats").toString()); 1506 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1507 1508 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1509 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1510 1511 mConfiguration.setToDefaults(); 1512 mConfiguration.locale = Locale.getDefault(); 1513 mConfigurationSeq = mConfiguration.seq = 1; 1514 mProcessStats.init(); 1515 1516 mCompatModePackages = new CompatModePackages(this, systemDir); 1517 1518 // Add ourself to the Watchdog monitors. 1519 Watchdog.getInstance().addMonitor(this); 1520 1521 mProcessStatsThread = new Thread("ProcessStats") { 1522 public void run() { 1523 while (true) { 1524 try { 1525 try { 1526 synchronized(this) { 1527 final long now = SystemClock.uptimeMillis(); 1528 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1529 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1530 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1531 // + ", write delay=" + nextWriteDelay); 1532 if (nextWriteDelay < nextCpuDelay) { 1533 nextCpuDelay = nextWriteDelay; 1534 } 1535 if (nextCpuDelay > 0) { 1536 mProcessStatsMutexFree.set(true); 1537 this.wait(nextCpuDelay); 1538 } 1539 } 1540 } catch (InterruptedException e) { 1541 } 1542 updateCpuStatsNow(); 1543 } catch (Exception e) { 1544 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1545 } 1546 } 1547 } 1548 }; 1549 mProcessStatsThread.start(); 1550 } 1551 1552 @Override 1553 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1554 throws RemoteException { 1555 if (code == SYSPROPS_TRANSACTION) { 1556 // We need to tell all apps about the system property change. 1557 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1558 synchronized(this) { 1559 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1560 final int NA = apps.size(); 1561 for (int ia=0; ia<NA; ia++) { 1562 ProcessRecord app = apps.valueAt(ia); 1563 if (app.thread != null) { 1564 procs.add(app.thread.asBinder()); 1565 } 1566 } 1567 } 1568 } 1569 1570 int N = procs.size(); 1571 for (int i=0; i<N; i++) { 1572 Parcel data2 = Parcel.obtain(); 1573 try { 1574 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1575 } catch (RemoteException e) { 1576 } 1577 data2.recycle(); 1578 } 1579 } 1580 try { 1581 return super.onTransact(code, data, reply, flags); 1582 } catch (RuntimeException e) { 1583 // The activity manager only throws security exceptions, so let's 1584 // log all others. 1585 if (!(e instanceof SecurityException)) { 1586 Slog.e(TAG, "Activity Manager Crash", e); 1587 } 1588 throw e; 1589 } 1590 } 1591 1592 void updateCpuStats() { 1593 final long now = SystemClock.uptimeMillis(); 1594 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1595 return; 1596 } 1597 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1598 synchronized (mProcessStatsThread) { 1599 mProcessStatsThread.notify(); 1600 } 1601 } 1602 } 1603 1604 void updateCpuStatsNow() { 1605 synchronized (mProcessStatsThread) { 1606 mProcessStatsMutexFree.set(false); 1607 final long now = SystemClock.uptimeMillis(); 1608 boolean haveNewCpuStats = false; 1609 1610 if (MONITOR_CPU_USAGE && 1611 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1612 mLastCpuTime.set(now); 1613 haveNewCpuStats = true; 1614 mProcessStats.update(); 1615 //Slog.i(TAG, mProcessStats.printCurrentState()); 1616 //Slog.i(TAG, "Total CPU usage: " 1617 // + mProcessStats.getTotalCpuPercent() + "%"); 1618 1619 // Slog the cpu usage if the property is set. 1620 if ("true".equals(SystemProperties.get("events.cpu"))) { 1621 int user = mProcessStats.getLastUserTime(); 1622 int system = mProcessStats.getLastSystemTime(); 1623 int iowait = mProcessStats.getLastIoWaitTime(); 1624 int irq = mProcessStats.getLastIrqTime(); 1625 int softIrq = mProcessStats.getLastSoftIrqTime(); 1626 int idle = mProcessStats.getLastIdleTime(); 1627 1628 int total = user + system + iowait + irq + softIrq + idle; 1629 if (total == 0) total = 1; 1630 1631 EventLog.writeEvent(EventLogTags.CPU, 1632 ((user+system+iowait+irq+softIrq) * 100) / total, 1633 (user * 100) / total, 1634 (system * 100) / total, 1635 (iowait * 100) / total, 1636 (irq * 100) / total, 1637 (softIrq * 100) / total); 1638 } 1639 } 1640 1641 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1642 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1643 synchronized(bstats) { 1644 synchronized(mPidsSelfLocked) { 1645 if (haveNewCpuStats) { 1646 if (mOnBattery) { 1647 int perc = bstats.startAddingCpuLocked(); 1648 int totalUTime = 0; 1649 int totalSTime = 0; 1650 final int N = mProcessStats.countStats(); 1651 for (int i=0; i<N; i++) { 1652 ProcessStats.Stats st = mProcessStats.getStats(i); 1653 if (!st.working) { 1654 continue; 1655 } 1656 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1657 int otherUTime = (st.rel_utime*perc)/100; 1658 int otherSTime = (st.rel_stime*perc)/100; 1659 totalUTime += otherUTime; 1660 totalSTime += otherSTime; 1661 if (pr != null) { 1662 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1663 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1664 st.rel_stime-otherSTime); 1665 ps.addSpeedStepTimes(cpuSpeedTimes); 1666 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1667 } else { 1668 BatteryStatsImpl.Uid.Proc ps = 1669 bstats.getProcessStatsLocked(st.name, st.pid); 1670 if (ps != null) { 1671 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1672 st.rel_stime-otherSTime); 1673 ps.addSpeedStepTimes(cpuSpeedTimes); 1674 } 1675 } 1676 } 1677 bstats.finishAddingCpuLocked(perc, totalUTime, 1678 totalSTime, cpuSpeedTimes); 1679 } 1680 } 1681 } 1682 1683 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1684 mLastWriteTime = now; 1685 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1686 } 1687 } 1688 } 1689 } 1690 1691 @Override 1692 public void batteryNeedsCpuUpdate() { 1693 updateCpuStatsNow(); 1694 } 1695 1696 @Override 1697 public void batteryPowerChanged(boolean onBattery) { 1698 // When plugging in, update the CPU stats first before changing 1699 // the plug state. 1700 updateCpuStatsNow(); 1701 synchronized (this) { 1702 synchronized(mPidsSelfLocked) { 1703 mOnBattery = DEBUG_POWER ? true : onBattery; 1704 } 1705 } 1706 } 1707 1708 /** 1709 * Initialize the application bind args. These are passed to each 1710 * process when the bindApplication() IPC is sent to the process. They're 1711 * lazily setup to make sure the services are running when they're asked for. 1712 */ 1713 private HashMap<String, IBinder> getCommonServicesLocked() { 1714 if (mAppBindArgs == null) { 1715 mAppBindArgs = new HashMap<String, IBinder>(); 1716 1717 // Setup the application init args 1718 mAppBindArgs.put("package", ServiceManager.getService("package")); 1719 mAppBindArgs.put("window", ServiceManager.getService("window")); 1720 mAppBindArgs.put(Context.ALARM_SERVICE, 1721 ServiceManager.getService(Context.ALARM_SERVICE)); 1722 } 1723 return mAppBindArgs; 1724 } 1725 1726 final void setFocusedActivityLocked(ActivityRecord r) { 1727 if (mFocusedActivity != r) { 1728 mFocusedActivity = r; 1729 if (r != null) { 1730 mWindowManager.setFocusedApp(r.appToken, true); 1731 } 1732 } 1733 } 1734 1735 private final void updateLruProcessInternalLocked(ProcessRecord app, 1736 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1737 // put it on the LRU to keep track of when it should be exited. 1738 int lrui = mLruProcesses.indexOf(app); 1739 if (lrui >= 0) mLruProcesses.remove(lrui); 1740 1741 int i = mLruProcesses.size()-1; 1742 int skipTop = 0; 1743 1744 app.lruSeq = mLruSeq; 1745 1746 // compute the new weight for this process. 1747 if (updateActivityTime) { 1748 app.lastActivityTime = SystemClock.uptimeMillis(); 1749 } 1750 if (app.activities.size() > 0) { 1751 // If this process has activities, we more strongly want to keep 1752 // it around. 1753 app.lruWeight = app.lastActivityTime; 1754 } else if (app.pubProviders.size() > 0) { 1755 // If this process contains content providers, we want to keep 1756 // it a little more strongly. 1757 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1758 // Also don't let it kick out the first few "real" hidden processes. 1759 skipTop = ProcessList.MIN_HIDDEN_APPS; 1760 } else { 1761 // If this process doesn't have activities, we less strongly 1762 // want to keep it around, and generally want to avoid getting 1763 // in front of any very recently used activities. 1764 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1765 // Also don't let it kick out the first few "real" hidden processes. 1766 skipTop = ProcessList.MIN_HIDDEN_APPS; 1767 } 1768 1769 while (i >= 0) { 1770 ProcessRecord p = mLruProcesses.get(i); 1771 // If this app shouldn't be in front of the first N background 1772 // apps, then skip over that many that are currently hidden. 1773 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1774 skipTop--; 1775 } 1776 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1777 mLruProcesses.add(i+1, app); 1778 break; 1779 } 1780 i--; 1781 } 1782 if (i < 0) { 1783 mLruProcesses.add(0, app); 1784 } 1785 1786 // If the app is currently using a content provider or service, 1787 // bump those processes as well. 1788 if (app.connections.size() > 0) { 1789 for (ConnectionRecord cr : app.connections) { 1790 if (cr.binding != null && cr.binding.service != null 1791 && cr.binding.service.app != null 1792 && cr.binding.service.app.lruSeq != mLruSeq) { 1793 updateLruProcessInternalLocked(cr.binding.service.app, false, 1794 updateActivityTime, i+1); 1795 } 1796 } 1797 } 1798 for (int j=app.conProviders.size()-1; j>=0; j--) { 1799 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1800 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1801 updateLruProcessInternalLocked(cpr.proc, false, 1802 updateActivityTime, i+1); 1803 } 1804 } 1805 1806 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1807 if (oomAdj) { 1808 updateOomAdjLocked(); 1809 } 1810 } 1811 1812 final void updateLruProcessLocked(ProcessRecord app, 1813 boolean oomAdj, boolean updateActivityTime) { 1814 mLruSeq++; 1815 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1816 } 1817 1818 final ProcessRecord getProcessRecordLocked( 1819 String processName, int uid) { 1820 if (uid == Process.SYSTEM_UID) { 1821 // The system gets to run in any process. If there are multiple 1822 // processes with the same uid, just pick the first (this 1823 // should never happen). 1824 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1825 processName); 1826 if (procs == null) return null; 1827 final int N = procs.size(); 1828 for (int i = 0; i < N; i++) { 1829 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1830 } 1831 } 1832 ProcessRecord proc = mProcessNames.get(processName, uid); 1833 return proc; 1834 } 1835 1836 void ensurePackageDexOpt(String packageName) { 1837 IPackageManager pm = AppGlobals.getPackageManager(); 1838 try { 1839 if (pm.performDexOpt(packageName)) { 1840 mDidDexOpt = true; 1841 } 1842 } catch (RemoteException e) { 1843 } 1844 } 1845 1846 boolean isNextTransitionForward() { 1847 int transit = mWindowManager.getPendingAppTransition(); 1848 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1849 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1850 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1851 } 1852 1853 final ProcessRecord startProcessLocked(String processName, 1854 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1855 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1856 boolean isolated) { 1857 ProcessRecord app; 1858 if (!isolated) { 1859 app = getProcessRecordLocked(processName, info.uid); 1860 } else { 1861 // If this is an isolated process, it can't re-use an existing process. 1862 app = null; 1863 } 1864 // We don't have to do anything more if: 1865 // (1) There is an existing application record; and 1866 // (2) The caller doesn't think it is dead, OR there is no thread 1867 // object attached to it so we know it couldn't have crashed; and 1868 // (3) There is a pid assigned to it, so it is either starting or 1869 // already running. 1870 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1871 + " app=" + app + " knownToBeDead=" + knownToBeDead 1872 + " thread=" + (app != null ? app.thread : null) 1873 + " pid=" + (app != null ? app.pid : -1)); 1874 if (app != null && app.pid > 0) { 1875 if (!knownToBeDead || app.thread == null) { 1876 // We already have the app running, or are waiting for it to 1877 // come up (we have a pid but not yet its thread), so keep it. 1878 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1879 // If this is a new package in the process, add the package to the list 1880 app.addPackage(info.packageName); 1881 return app; 1882 } else { 1883 // An application record is attached to a previous process, 1884 // clean it up now. 1885 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1886 handleAppDiedLocked(app, true, true); 1887 } 1888 } 1889 1890 String hostingNameStr = hostingName != null 1891 ? hostingName.flattenToShortString() : null; 1892 1893 if (!isolated) { 1894 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1895 // If we are in the background, then check to see if this process 1896 // is bad. If so, we will just silently fail. 1897 if (mBadProcesses.get(info.processName, info.uid) != null) { 1898 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1899 + "/" + info.processName); 1900 return null; 1901 } 1902 } else { 1903 // When the user is explicitly starting a process, then clear its 1904 // crash count so that we won't make it bad until they see at 1905 // least one crash dialog again, and make the process good again 1906 // if it had been bad. 1907 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1908 + "/" + info.processName); 1909 mProcessCrashTimes.remove(info.processName, info.uid); 1910 if (mBadProcesses.get(info.processName, info.uid) != null) { 1911 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1912 info.processName); 1913 mBadProcesses.remove(info.processName, info.uid); 1914 if (app != null) { 1915 app.bad = false; 1916 } 1917 } 1918 } 1919 } 1920 1921 if (app == null) { 1922 app = newProcessRecordLocked(null, info, processName, isolated); 1923 if (app == null) { 1924 Slog.w(TAG, "Failed making new process record for " 1925 + processName + "/" + info.uid + " isolated=" + isolated); 1926 return null; 1927 } 1928 mProcessNames.put(processName, app.uid, app); 1929 if (isolated) { 1930 mIsolatedProcesses.put(app.uid, app); 1931 } 1932 } else { 1933 // If this is a new package in the process, add the package to the list 1934 app.addPackage(info.packageName); 1935 } 1936 1937 // If the system is not ready yet, then hold off on starting this 1938 // process until it is. 1939 if (!mProcessesReady 1940 && !isAllowedWhileBooting(info) 1941 && !allowWhileBooting) { 1942 if (!mProcessesOnHold.contains(app)) { 1943 mProcessesOnHold.add(app); 1944 } 1945 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1946 return app; 1947 } 1948 1949 startProcessLocked(app, hostingType, hostingNameStr); 1950 return (app.pid != 0) ? app : null; 1951 } 1952 1953 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1954 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1955 } 1956 1957 private final void startProcessLocked(ProcessRecord app, 1958 String hostingType, String hostingNameStr) { 1959 if (app.pid > 0 && app.pid != MY_PID) { 1960 synchronized (mPidsSelfLocked) { 1961 mPidsSelfLocked.remove(app.pid); 1962 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1963 } 1964 app.setPid(0); 1965 } 1966 1967 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1968 "startProcessLocked removing on hold: " + app); 1969 mProcessesOnHold.remove(app); 1970 1971 updateCpuStats(); 1972 1973 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1974 mProcDeaths[0] = 0; 1975 1976 try { 1977 int uid = app.uid; 1978 1979 int[] gids = null; 1980 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1981 if (!app.isolated) { 1982 try { 1983 final PackageManager pm = mContext.getPackageManager(); 1984 gids = pm.getPackageGids(app.info.packageName); 1985 } catch (PackageManager.NameNotFoundException e) { 1986 Slog.w(TAG, "Unable to retrieve gids", e); 1987 } 1988 1989 if (Environment.isExternalStorageEmulated()) { 1990 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 1991 } 1992 } 1993 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1994 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1995 && mTopComponent != null 1996 && app.processName.equals(mTopComponent.getPackageName())) { 1997 uid = 0; 1998 } 1999 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2000 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2001 uid = 0; 2002 } 2003 } 2004 int debugFlags = 0; 2005 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2006 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2007 // Also turn on CheckJNI for debuggable apps. It's quite 2008 // awkward to turn on otherwise. 2009 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2010 } 2011 // Run the app in safe mode if its manifest requests so or the 2012 // system is booted in safe mode. 2013 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2014 Zygote.systemInSafeMode == true) { 2015 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2016 } 2017 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2018 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2019 } 2020 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2021 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2022 } 2023 if ("1".equals(SystemProperties.get("debug.assert"))) { 2024 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2025 } 2026 2027 // Start the process. It will either succeed and return a result containing 2028 // the PID of the new process, or else throw a RuntimeException. 2029 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2030 app.processName, uid, uid, gids, debugFlags, mountExternal, 2031 app.info.targetSdkVersion, null, null); 2032 2033 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2034 synchronized (bs) { 2035 if (bs.isOnBattery()) { 2036 app.batteryStats.incStartsLocked(); 2037 } 2038 } 2039 2040 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2041 app.processName, hostingType, 2042 hostingNameStr != null ? hostingNameStr : ""); 2043 2044 if (app.persistent) { 2045 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2046 } 2047 2048 StringBuilder buf = mStringBuilder; 2049 buf.setLength(0); 2050 buf.append("Start proc "); 2051 buf.append(app.processName); 2052 buf.append(" for "); 2053 buf.append(hostingType); 2054 if (hostingNameStr != null) { 2055 buf.append(" "); 2056 buf.append(hostingNameStr); 2057 } 2058 buf.append(": pid="); 2059 buf.append(startResult.pid); 2060 buf.append(" uid="); 2061 buf.append(uid); 2062 buf.append(" gids={"); 2063 if (gids != null) { 2064 for (int gi=0; gi<gids.length; gi++) { 2065 if (gi != 0) buf.append(", "); 2066 buf.append(gids[gi]); 2067 2068 } 2069 } 2070 buf.append("}"); 2071 Slog.i(TAG, buf.toString()); 2072 app.setPid(startResult.pid); 2073 app.usingWrapper = startResult.usingWrapper; 2074 app.removed = false; 2075 synchronized (mPidsSelfLocked) { 2076 this.mPidsSelfLocked.put(startResult.pid, app); 2077 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2078 msg.obj = app; 2079 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2080 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2081 } 2082 } catch (RuntimeException e) { 2083 // XXX do better error recovery. 2084 app.setPid(0); 2085 Slog.e(TAG, "Failure starting process " + app.processName, e); 2086 } 2087 } 2088 2089 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2090 if (resumed) { 2091 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2092 } else { 2093 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2094 } 2095 } 2096 2097 boolean startHomeActivityLocked(int userId) { 2098 if (mHeadless) { 2099 // Added because none of the other calls to ensureBootCompleted seem to fire 2100 // when running headless. 2101 ensureBootCompleted(); 2102 return false; 2103 } 2104 2105 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2106 && mTopAction == null) { 2107 // We are running in factory test mode, but unable to find 2108 // the factory test app, so just sit around displaying the 2109 // error message and don't try to start anything. 2110 return false; 2111 } 2112 Intent intent = new Intent( 2113 mTopAction, 2114 mTopData != null ? Uri.parse(mTopData) : null); 2115 intent.setComponent(mTopComponent); 2116 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2117 intent.addCategory(Intent.CATEGORY_HOME); 2118 } 2119 ActivityInfo aInfo = 2120 intent.resolveActivityInfo(mContext.getPackageManager(), 2121 STOCK_PM_FLAGS); 2122 if (aInfo != null) { 2123 intent.setComponent(new ComponentName( 2124 aInfo.applicationInfo.packageName, aInfo.name)); 2125 // Don't do this if the home app is currently being 2126 // instrumented. 2127 aInfo = new ActivityInfo(aInfo); 2128 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2129 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2130 aInfo.applicationInfo.uid); 2131 if (app == null || app.instrumentationClass == null) { 2132 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2133 mMainStack.startActivityLocked(null, intent, null, aInfo, 2134 null, null, 0, 0, 0, 0, null, false, null); 2135 } 2136 } 2137 2138 return true; 2139 } 2140 2141 /** 2142 * Starts the "new version setup screen" if appropriate. 2143 */ 2144 void startSetupActivityLocked() { 2145 // Only do this once per boot. 2146 if (mCheckedForSetup) { 2147 return; 2148 } 2149 2150 // We will show this screen if the current one is a different 2151 // version than the last one shown, and we are not running in 2152 // low-level factory test mode. 2153 final ContentResolver resolver = mContext.getContentResolver(); 2154 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2155 Settings.Secure.getInt(resolver, 2156 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2157 mCheckedForSetup = true; 2158 2159 // See if we should be showing the platform update setup UI. 2160 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2161 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2162 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2163 2164 // We don't allow third party apps to replace this. 2165 ResolveInfo ri = null; 2166 for (int i=0; ris != null && i<ris.size(); i++) { 2167 if ((ris.get(i).activityInfo.applicationInfo.flags 2168 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2169 ri = ris.get(i); 2170 break; 2171 } 2172 } 2173 2174 if (ri != null) { 2175 String vers = ri.activityInfo.metaData != null 2176 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2177 : null; 2178 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2179 vers = ri.activityInfo.applicationInfo.metaData.getString( 2180 Intent.METADATA_SETUP_VERSION); 2181 } 2182 String lastVers = Settings.Secure.getString( 2183 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2184 if (vers != null && !vers.equals(lastVers)) { 2185 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2186 intent.setComponent(new ComponentName( 2187 ri.activityInfo.packageName, ri.activityInfo.name)); 2188 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2189 null, null, 0, 0, 0, 0, null, false, null); 2190 } 2191 } 2192 } 2193 } 2194 2195 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2196 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2197 } 2198 2199 void enforceNotIsolatedCaller(String caller) { 2200 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2201 throw new SecurityException("Isolated process not allowed to call " + caller); 2202 } 2203 } 2204 2205 public int getFrontActivityScreenCompatMode() { 2206 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2207 synchronized (this) { 2208 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2209 } 2210 } 2211 2212 public void setFrontActivityScreenCompatMode(int mode) { 2213 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2214 "setFrontActivityScreenCompatMode"); 2215 synchronized (this) { 2216 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2217 } 2218 } 2219 2220 public int getPackageScreenCompatMode(String packageName) { 2221 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2222 synchronized (this) { 2223 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2224 } 2225 } 2226 2227 public void setPackageScreenCompatMode(String packageName, int mode) { 2228 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2229 "setPackageScreenCompatMode"); 2230 synchronized (this) { 2231 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2232 } 2233 } 2234 2235 public boolean getPackageAskScreenCompat(String packageName) { 2236 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2237 synchronized (this) { 2238 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2239 } 2240 } 2241 2242 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2243 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2244 "setPackageAskScreenCompat"); 2245 synchronized (this) { 2246 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2247 } 2248 } 2249 2250 void reportResumedActivityLocked(ActivityRecord r) { 2251 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2252 updateUsageStats(r, true); 2253 } 2254 2255 private void dispatchProcessesChanged() { 2256 int N; 2257 synchronized (this) { 2258 N = mPendingProcessChanges.size(); 2259 if (mActiveProcessChanges.length < N) { 2260 mActiveProcessChanges = new ProcessChangeItem[N]; 2261 } 2262 mPendingProcessChanges.toArray(mActiveProcessChanges); 2263 mAvailProcessChanges.addAll(mPendingProcessChanges); 2264 mPendingProcessChanges.clear(); 2265 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2266 } 2267 int i = mProcessObservers.beginBroadcast(); 2268 while (i > 0) { 2269 i--; 2270 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2271 if (observer != null) { 2272 try { 2273 for (int j=0; j<N; j++) { 2274 ProcessChangeItem item = mActiveProcessChanges[j]; 2275 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2276 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2277 + item.pid + " uid=" + item.uid + ": " 2278 + item.foregroundActivities); 2279 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2280 item.foregroundActivities); 2281 } 2282 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2283 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2284 + item.pid + " uid=" + item.uid + ": " + item.importance); 2285 observer.onImportanceChanged(item.pid, item.uid, 2286 item.importance); 2287 } 2288 } 2289 } catch (RemoteException e) { 2290 } 2291 } 2292 } 2293 mProcessObservers.finishBroadcast(); 2294 } 2295 2296 private void dispatchProcessDied(int pid, int uid) { 2297 int i = mProcessObservers.beginBroadcast(); 2298 while (i > 0) { 2299 i--; 2300 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2301 if (observer != null) { 2302 try { 2303 observer.onProcessDied(pid, uid); 2304 } catch (RemoteException e) { 2305 } 2306 } 2307 } 2308 mProcessObservers.finishBroadcast(); 2309 } 2310 2311 final void doPendingActivityLaunchesLocked(boolean doResume) { 2312 final int N = mPendingActivityLaunches.size(); 2313 if (N <= 0) { 2314 return; 2315 } 2316 for (int i=0; i<N; i++) { 2317 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2318 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2319 pal.startFlags, doResume && i == (N-1), null); 2320 } 2321 mPendingActivityLaunches.clear(); 2322 } 2323 2324 public final int startActivity(IApplicationThread caller, 2325 Intent intent, String resolvedType, IBinder resultTo, 2326 String resultWho, int requestCode, int startFlags, 2327 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2328 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2329 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2330 } 2331 2332 public final int startActivityAsUser(IApplicationThread caller, 2333 Intent intent, String resolvedType, IBinder resultTo, 2334 String resultWho, int requestCode, int startFlags, 2335 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2336 enforceNotIsolatedCaller("startActivity"); 2337 if (userId != UserHandle.getCallingUserId()) { 2338 // Requesting a different user, make sure that they have the permission 2339 if (checkComponentPermission( 2340 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2341 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2342 == PackageManager.PERMISSION_GRANTED) { 2343 // Translate to the current user id, if caller wasn't aware 2344 if (userId == UserHandle.USER_CURRENT) { 2345 userId = mCurrentUserId; 2346 } 2347 } else { 2348 String msg = "Permission Denial: " 2349 + "Request to startActivity as user " + userId 2350 + " but is calling from user " + UserHandle.getCallingUserId() 2351 + "; this requires " 2352 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2353 Slog.w(TAG, msg); 2354 throw new SecurityException(msg); 2355 } 2356 } else { 2357 if (intent.getCategories() != null 2358 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2359 // Requesting home, set the identity to the current user 2360 // HACK! 2361 userId = mCurrentUserId; 2362 } else { 2363 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2364 // the current user's userId 2365 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2366 userId = 0; 2367 } else { 2368 userId = Binder.getOrigCallingUser(); 2369 } 2370 } 2371 } 2372 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2373 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2374 null, null, options, userId); 2375 } 2376 2377 public final WaitResult startActivityAndWait(IApplicationThread caller, 2378 Intent intent, String resolvedType, IBinder resultTo, 2379 String resultWho, int requestCode, int startFlags, String profileFile, 2380 ParcelFileDescriptor profileFd, Bundle options) { 2381 enforceNotIsolatedCaller("startActivityAndWait"); 2382 WaitResult res = new WaitResult(); 2383 int userId = Binder.getOrigCallingUser(); 2384 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2385 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2386 res, null, options, userId); 2387 return res; 2388 } 2389 2390 public final int startActivityWithConfig(IApplicationThread caller, 2391 Intent intent, String resolvedType, IBinder resultTo, 2392 String resultWho, int requestCode, int startFlags, Configuration config, 2393 Bundle options) { 2394 enforceNotIsolatedCaller("startActivityWithConfig"); 2395 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2396 resultTo, resultWho, requestCode, startFlags, 2397 null, null, null, config, options, Binder.getOrigCallingUser()); 2398 return ret; 2399 } 2400 2401 public int startActivityIntentSender(IApplicationThread caller, 2402 IntentSender intent, Intent fillInIntent, String resolvedType, 2403 IBinder resultTo, String resultWho, int requestCode, 2404 int flagsMask, int flagsValues, Bundle options) { 2405 enforceNotIsolatedCaller("startActivityIntentSender"); 2406 // Refuse possible leaked file descriptors 2407 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2408 throw new IllegalArgumentException("File descriptors passed in Intent"); 2409 } 2410 2411 IIntentSender sender = intent.getTarget(); 2412 if (!(sender instanceof PendingIntentRecord)) { 2413 throw new IllegalArgumentException("Bad PendingIntent object"); 2414 } 2415 2416 PendingIntentRecord pir = (PendingIntentRecord)sender; 2417 2418 synchronized (this) { 2419 // If this is coming from the currently resumed activity, it is 2420 // effectively saying that app switches are allowed at this point. 2421 if (mMainStack.mResumedActivity != null 2422 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2423 Binder.getCallingUid()) { 2424 mAppSwitchesAllowedTime = 0; 2425 } 2426 } 2427 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2428 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2429 return ret; 2430 } 2431 2432 public boolean startNextMatchingActivity(IBinder callingActivity, 2433 Intent intent, Bundle options) { 2434 // Refuse possible leaked file descriptors 2435 if (intent != null && intent.hasFileDescriptors() == true) { 2436 throw new IllegalArgumentException("File descriptors passed in Intent"); 2437 } 2438 2439 synchronized (this) { 2440 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2441 if (r == null) { 2442 ActivityOptions.abort(options); 2443 return false; 2444 } 2445 if (r.app == null || r.app.thread == null) { 2446 // The caller is not running... d'oh! 2447 ActivityOptions.abort(options); 2448 return false; 2449 } 2450 intent = new Intent(intent); 2451 // The caller is not allowed to change the data. 2452 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2453 // And we are resetting to find the next component... 2454 intent.setComponent(null); 2455 2456 ActivityInfo aInfo = null; 2457 try { 2458 List<ResolveInfo> resolves = 2459 AppGlobals.getPackageManager().queryIntentActivities( 2460 intent, r.resolvedType, 2461 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2462 UserHandle.getCallingUserId()); 2463 2464 // Look for the original activity in the list... 2465 final int N = resolves != null ? resolves.size() : 0; 2466 for (int i=0; i<N; i++) { 2467 ResolveInfo rInfo = resolves.get(i); 2468 if (rInfo.activityInfo.packageName.equals(r.packageName) 2469 && rInfo.activityInfo.name.equals(r.info.name)) { 2470 // We found the current one... the next matching is 2471 // after it. 2472 i++; 2473 if (i<N) { 2474 aInfo = resolves.get(i).activityInfo; 2475 } 2476 break; 2477 } 2478 } 2479 } catch (RemoteException e) { 2480 } 2481 2482 if (aInfo == null) { 2483 // Nobody who is next! 2484 ActivityOptions.abort(options); 2485 return false; 2486 } 2487 2488 intent.setComponent(new ComponentName( 2489 aInfo.applicationInfo.packageName, aInfo.name)); 2490 intent.setFlags(intent.getFlags()&~( 2491 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2492 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2493 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2494 Intent.FLAG_ACTIVITY_NEW_TASK)); 2495 2496 // Okay now we need to start the new activity, replacing the 2497 // currently running activity. This is a little tricky because 2498 // we want to start the new one as if the current one is finished, 2499 // but not finish the current one first so that there is no flicker. 2500 // And thus... 2501 final boolean wasFinishing = r.finishing; 2502 r.finishing = true; 2503 2504 // Propagate reply information over to the new activity. 2505 final ActivityRecord resultTo = r.resultTo; 2506 final String resultWho = r.resultWho; 2507 final int requestCode = r.requestCode; 2508 r.resultTo = null; 2509 if (resultTo != null) { 2510 resultTo.removeResultsLocked(r, resultWho, requestCode); 2511 } 2512 2513 final long origId = Binder.clearCallingIdentity(); 2514 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2515 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2516 resultWho, requestCode, -1, r.launchedFromUid, 0, 2517 options, false, null); 2518 Binder.restoreCallingIdentity(origId); 2519 2520 r.finishing = wasFinishing; 2521 if (res != ActivityManager.START_SUCCESS) { 2522 return false; 2523 } 2524 return true; 2525 } 2526 } 2527 2528 public final int startActivityInPackage(int uid, 2529 Intent intent, String resolvedType, IBinder resultTo, 2530 String resultWho, int requestCode, int startFlags, Bundle options) { 2531 2532 // This is so super not safe, that only the system (or okay root) 2533 // can do it. 2534 final int callingUid = Binder.getCallingUid(); 2535 if (callingUid != 0 && callingUid != Process.myUid()) { 2536 throw new SecurityException( 2537 "startActivityInPackage only available to the system"); 2538 } 2539 2540 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2541 resultTo, resultWho, requestCode, startFlags, 2542 null, null, null, null, options, UserHandle.getUserId(uid)); 2543 return ret; 2544 } 2545 2546 public final int startActivities(IApplicationThread caller, 2547 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2548 enforceNotIsolatedCaller("startActivities"); 2549 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2550 options, Binder.getOrigCallingUser()); 2551 return ret; 2552 } 2553 2554 public final int startActivitiesInPackage(int uid, 2555 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2556 Bundle options) { 2557 2558 // This is so super not safe, that only the system (or okay root) 2559 // can do it. 2560 final int callingUid = Binder.getCallingUid(); 2561 if (callingUid != 0 && callingUid != Process.myUid()) { 2562 throw new SecurityException( 2563 "startActivityInPackage only available to the system"); 2564 } 2565 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2566 options, UserHandle.getUserId(uid)); 2567 return ret; 2568 } 2569 2570 final void addRecentTaskLocked(TaskRecord task) { 2571 int N = mRecentTasks.size(); 2572 // Quick case: check if the top-most recent task is the same. 2573 if (N > 0 && mRecentTasks.get(0) == task) { 2574 return; 2575 } 2576 // Remove any existing entries that are the same kind of task. 2577 for (int i=0; i<N; i++) { 2578 TaskRecord tr = mRecentTasks.get(i); 2579 if (task.userId == tr.userId 2580 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2581 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2582 mRecentTasks.remove(i); 2583 i--; 2584 N--; 2585 if (task.intent == null) { 2586 // If the new recent task we are adding is not fully 2587 // specified, then replace it with the existing recent task. 2588 task = tr; 2589 } 2590 } 2591 } 2592 if (N >= MAX_RECENT_TASKS) { 2593 mRecentTasks.remove(N-1); 2594 } 2595 mRecentTasks.add(0, task); 2596 } 2597 2598 public void setRequestedOrientation(IBinder token, 2599 int requestedOrientation) { 2600 synchronized (this) { 2601 ActivityRecord r = mMainStack.isInStackLocked(token); 2602 if (r == null) { 2603 return; 2604 } 2605 final long origId = Binder.clearCallingIdentity(); 2606 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2607 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2608 mConfiguration, 2609 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2610 if (config != null) { 2611 r.frozenBeforeDestroy = true; 2612 if (!updateConfigurationLocked(config, r, false, false)) { 2613 mMainStack.resumeTopActivityLocked(null); 2614 } 2615 } 2616 Binder.restoreCallingIdentity(origId); 2617 } 2618 } 2619 2620 public int getRequestedOrientation(IBinder token) { 2621 synchronized (this) { 2622 ActivityRecord r = mMainStack.isInStackLocked(token); 2623 if (r == null) { 2624 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2625 } 2626 return mWindowManager.getAppOrientation(r.appToken); 2627 } 2628 } 2629 2630 /** 2631 * This is the internal entry point for handling Activity.finish(). 2632 * 2633 * @param token The Binder token referencing the Activity we want to finish. 2634 * @param resultCode Result code, if any, from this Activity. 2635 * @param resultData Result data (Intent), if any, from this Activity. 2636 * 2637 * @return Returns true if the activity successfully finished, or false if it is still running. 2638 */ 2639 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2640 // Refuse possible leaked file descriptors 2641 if (resultData != null && resultData.hasFileDescriptors() == true) { 2642 throw new IllegalArgumentException("File descriptors passed in Intent"); 2643 } 2644 2645 synchronized(this) { 2646 if (mController != null) { 2647 // Find the first activity that is not finishing. 2648 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2649 if (next != null) { 2650 // ask watcher if this is allowed 2651 boolean resumeOK = true; 2652 try { 2653 resumeOK = mController.activityResuming(next.packageName); 2654 } catch (RemoteException e) { 2655 mController = null; 2656 } 2657 2658 if (!resumeOK) { 2659 return false; 2660 } 2661 } 2662 } 2663 final long origId = Binder.clearCallingIdentity(); 2664 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2665 resultData, "app-request"); 2666 Binder.restoreCallingIdentity(origId); 2667 return res; 2668 } 2669 } 2670 2671 public final void finishHeavyWeightApp() { 2672 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2673 != PackageManager.PERMISSION_GRANTED) { 2674 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2675 + Binder.getCallingPid() 2676 + ", uid=" + Binder.getCallingUid() 2677 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2678 Slog.w(TAG, msg); 2679 throw new SecurityException(msg); 2680 } 2681 2682 synchronized(this) { 2683 if (mHeavyWeightProcess == null) { 2684 return; 2685 } 2686 2687 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2688 mHeavyWeightProcess.activities); 2689 for (int i=0; i<activities.size(); i++) { 2690 ActivityRecord r = activities.get(i); 2691 if (!r.finishing) { 2692 int index = mMainStack.indexOfTokenLocked(r.appToken); 2693 if (index >= 0) { 2694 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2695 null, "finish-heavy"); 2696 } 2697 } 2698 } 2699 2700 mHeavyWeightProcess = null; 2701 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2702 } 2703 } 2704 2705 public void crashApplication(int uid, int initialPid, String packageName, 2706 String message) { 2707 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2708 != PackageManager.PERMISSION_GRANTED) { 2709 String msg = "Permission Denial: crashApplication() from pid=" 2710 + Binder.getCallingPid() 2711 + ", uid=" + Binder.getCallingUid() 2712 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2713 Slog.w(TAG, msg); 2714 throw new SecurityException(msg); 2715 } 2716 2717 synchronized(this) { 2718 ProcessRecord proc = null; 2719 2720 // Figure out which process to kill. We don't trust that initialPid 2721 // still has any relation to current pids, so must scan through the 2722 // list. 2723 synchronized (mPidsSelfLocked) { 2724 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2725 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2726 if (p.uid != uid) { 2727 continue; 2728 } 2729 if (p.pid == initialPid) { 2730 proc = p; 2731 break; 2732 } 2733 for (String str : p.pkgList) { 2734 if (str.equals(packageName)) { 2735 proc = p; 2736 } 2737 } 2738 } 2739 } 2740 2741 if (proc == null) { 2742 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2743 + " initialPid=" + initialPid 2744 + " packageName=" + packageName); 2745 return; 2746 } 2747 2748 if (proc.thread != null) { 2749 if (proc.pid == Process.myPid()) { 2750 Log.w(TAG, "crashApplication: trying to crash self!"); 2751 return; 2752 } 2753 long ident = Binder.clearCallingIdentity(); 2754 try { 2755 proc.thread.scheduleCrash(message); 2756 } catch (RemoteException e) { 2757 } 2758 Binder.restoreCallingIdentity(ident); 2759 } 2760 } 2761 } 2762 2763 public final void finishSubActivity(IBinder token, String resultWho, 2764 int requestCode) { 2765 synchronized(this) { 2766 final long origId = Binder.clearCallingIdentity(); 2767 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2768 Binder.restoreCallingIdentity(origId); 2769 } 2770 } 2771 2772 public boolean finishActivityAffinity(IBinder token) { 2773 synchronized(this) { 2774 final long origId = Binder.clearCallingIdentity(); 2775 boolean res = mMainStack.finishActivityAffinityLocked(token); 2776 Binder.restoreCallingIdentity(origId); 2777 return res; 2778 } 2779 } 2780 2781 public boolean willActivityBeVisible(IBinder token) { 2782 synchronized(this) { 2783 int i; 2784 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2785 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2786 if (r.appToken == token) { 2787 return true; 2788 } 2789 if (r.fullscreen && !r.finishing) { 2790 return false; 2791 } 2792 } 2793 return true; 2794 } 2795 } 2796 2797 public void overridePendingTransition(IBinder token, String packageName, 2798 int enterAnim, int exitAnim) { 2799 synchronized(this) { 2800 ActivityRecord self = mMainStack.isInStackLocked(token); 2801 if (self == null) { 2802 return; 2803 } 2804 2805 final long origId = Binder.clearCallingIdentity(); 2806 2807 if (self.state == ActivityState.RESUMED 2808 || self.state == ActivityState.PAUSING) { 2809 mWindowManager.overridePendingAppTransition(packageName, 2810 enterAnim, exitAnim, null); 2811 } 2812 2813 Binder.restoreCallingIdentity(origId); 2814 } 2815 } 2816 2817 /** 2818 * Main function for removing an existing process from the activity manager 2819 * as a result of that process going away. Clears out all connections 2820 * to the process. 2821 */ 2822 private final void handleAppDiedLocked(ProcessRecord app, 2823 boolean restarting, boolean allowRestart) { 2824 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2825 if (!restarting) { 2826 mLruProcesses.remove(app); 2827 } 2828 2829 if (mProfileProc == app) { 2830 clearProfilerLocked(); 2831 } 2832 2833 // Just in case... 2834 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2835 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2836 mMainStack.mPausingActivity = null; 2837 } 2838 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2839 mMainStack.mLastPausedActivity = null; 2840 } 2841 2842 // Remove this application's activities from active lists. 2843 mMainStack.removeHistoryRecordsForAppLocked(app); 2844 2845 boolean atTop = true; 2846 boolean hasVisibleActivities = false; 2847 2848 // Clean out the history list. 2849 int i = mMainStack.mHistory.size(); 2850 if (localLOGV) Slog.v( 2851 TAG, "Removing app " + app + " from history with " + i + " entries"); 2852 while (i > 0) { 2853 i--; 2854 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2855 if (localLOGV) Slog.v( 2856 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2857 if (r.app == app) { 2858 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2859 if (ActivityStack.DEBUG_ADD_REMOVE) { 2860 RuntimeException here = new RuntimeException("here"); 2861 here.fillInStackTrace(); 2862 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2863 + ": haveState=" + r.haveState 2864 + " stateNotNeeded=" + r.stateNotNeeded 2865 + " finishing=" + r.finishing 2866 + " state=" + r.state, here); 2867 } 2868 if (!r.finishing) { 2869 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2870 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2871 System.identityHashCode(r), 2872 r.task.taskId, r.shortComponentName, 2873 "proc died without state saved"); 2874 } 2875 mMainStack.removeActivityFromHistoryLocked(r); 2876 2877 } else { 2878 // We have the current state for this activity, so 2879 // it can be restarted later when needed. 2880 if (localLOGV) Slog.v( 2881 TAG, "Keeping entry, setting app to null"); 2882 if (r.visible) { 2883 hasVisibleActivities = true; 2884 } 2885 r.app = null; 2886 r.nowVisible = false; 2887 if (!r.haveState) { 2888 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2889 "App died, clearing saved state of " + r); 2890 r.icicle = null; 2891 } 2892 } 2893 2894 r.stack.cleanUpActivityLocked(r, true, true); 2895 } 2896 atTop = false; 2897 } 2898 2899 app.activities.clear(); 2900 2901 if (app.instrumentationClass != null) { 2902 Slog.w(TAG, "Crash of app " + app.processName 2903 + " running instrumentation " + app.instrumentationClass); 2904 Bundle info = new Bundle(); 2905 info.putString("shortMsg", "Process crashed."); 2906 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2907 } 2908 2909 if (!restarting) { 2910 if (!mMainStack.resumeTopActivityLocked(null)) { 2911 // If there was nothing to resume, and we are not already 2912 // restarting this process, but there is a visible activity that 2913 // is hosted by the process... then make sure all visible 2914 // activities are running, taking care of restarting this 2915 // process. 2916 if (hasVisibleActivities) { 2917 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2918 } 2919 } 2920 } 2921 } 2922 2923 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2924 IBinder threadBinder = thread.asBinder(); 2925 // Find the application record. 2926 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2927 ProcessRecord rec = mLruProcesses.get(i); 2928 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2929 return i; 2930 } 2931 } 2932 return -1; 2933 } 2934 2935 final ProcessRecord getRecordForAppLocked( 2936 IApplicationThread thread) { 2937 if (thread == null) { 2938 return null; 2939 } 2940 2941 int appIndex = getLRURecordIndexForAppLocked(thread); 2942 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2943 } 2944 2945 final void appDiedLocked(ProcessRecord app, int pid, 2946 IApplicationThread thread) { 2947 2948 mProcDeaths[0]++; 2949 2950 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2951 synchronized (stats) { 2952 stats.noteProcessDiedLocked(app.info.uid, pid); 2953 } 2954 2955 // Clean up already done if the process has been re-started. 2956 if (app.pid == pid && app.thread != null && 2957 app.thread.asBinder() == thread.asBinder()) { 2958 if (!app.killedBackground) { 2959 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2960 + ") has died."); 2961 } 2962 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2963 if (localLOGV) Slog.v( 2964 TAG, "Dying app: " + app + ", pid: " + pid 2965 + ", thread: " + thread.asBinder()); 2966 boolean doLowMem = app.instrumentationClass == null; 2967 handleAppDiedLocked(app, false, true); 2968 2969 if (doLowMem) { 2970 // If there are no longer any background processes running, 2971 // and the app that died was not running instrumentation, 2972 // then tell everyone we are now low on memory. 2973 boolean haveBg = false; 2974 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2975 ProcessRecord rec = mLruProcesses.get(i); 2976 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2977 haveBg = true; 2978 break; 2979 } 2980 } 2981 2982 if (!haveBg) { 2983 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2984 long now = SystemClock.uptimeMillis(); 2985 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2986 ProcessRecord rec = mLruProcesses.get(i); 2987 if (rec != app && rec.thread != null && 2988 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2989 // The low memory report is overriding any current 2990 // state for a GC request. Make sure to do 2991 // heavy/important/visible/foreground processes first. 2992 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2993 rec.lastRequestedGc = 0; 2994 } else { 2995 rec.lastRequestedGc = rec.lastLowMemory; 2996 } 2997 rec.reportLowMemory = true; 2998 rec.lastLowMemory = now; 2999 mProcessesToGc.remove(rec); 3000 addProcessToGcListLocked(rec); 3001 } 3002 } 3003 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3004 scheduleAppGcsLocked(); 3005 } 3006 } 3007 } else if (app.pid != pid) { 3008 // A new process has already been started. 3009 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3010 + ") has died and restarted (pid " + app.pid + ")."); 3011 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3012 } else if (DEBUG_PROCESSES) { 3013 Slog.d(TAG, "Received spurious death notification for thread " 3014 + thread.asBinder()); 3015 } 3016 } 3017 3018 /** 3019 * If a stack trace dump file is configured, dump process stack traces. 3020 * @param clearTraces causes the dump file to be erased prior to the new 3021 * traces being written, if true; when false, the new traces will be 3022 * appended to any existing file content. 3023 * @param firstPids of dalvik VM processes to dump stack traces for first 3024 * @param lastPids of dalvik VM processes to dump stack traces for last 3025 * @param nativeProcs optional list of native process names to dump stack crawls 3026 * @return file containing stack traces, or null if no dump file is configured 3027 */ 3028 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3029 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3030 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3031 if (tracesPath == null || tracesPath.length() == 0) { 3032 return null; 3033 } 3034 3035 File tracesFile = new File(tracesPath); 3036 try { 3037 File tracesDir = tracesFile.getParentFile(); 3038 if (!tracesDir.exists()) tracesFile.mkdirs(); 3039 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3040 3041 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3042 tracesFile.createNewFile(); 3043 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3044 } catch (IOException e) { 3045 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3046 return null; 3047 } 3048 3049 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3050 return tracesFile; 3051 } 3052 3053 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3054 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3055 // Use a FileObserver to detect when traces finish writing. 3056 // The order of traces is considered important to maintain for legibility. 3057 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3058 public synchronized void onEvent(int event, String path) { notify(); } 3059 }; 3060 3061 try { 3062 observer.startWatching(); 3063 3064 // First collect all of the stacks of the most important pids. 3065 if (firstPids != null) { 3066 try { 3067 int num = firstPids.size(); 3068 for (int i = 0; i < num; i++) { 3069 synchronized (observer) { 3070 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3071 observer.wait(200); // Wait for write-close, give up after 200msec 3072 } 3073 } 3074 } catch (InterruptedException e) { 3075 Log.wtf(TAG, e); 3076 } 3077 } 3078 3079 // Next measure CPU usage. 3080 if (processStats != null) { 3081 processStats.init(); 3082 System.gc(); 3083 processStats.update(); 3084 try { 3085 synchronized (processStats) { 3086 processStats.wait(500); // measure over 1/2 second. 3087 } 3088 } catch (InterruptedException e) { 3089 } 3090 processStats.update(); 3091 3092 // We'll take the stack crawls of just the top apps using CPU. 3093 final int N = processStats.countWorkingStats(); 3094 int numProcs = 0; 3095 for (int i=0; i<N && numProcs<5; i++) { 3096 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3097 if (lastPids.indexOfKey(stats.pid) >= 0) { 3098 numProcs++; 3099 try { 3100 synchronized (observer) { 3101 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3102 observer.wait(200); // Wait for write-close, give up after 200msec 3103 } 3104 } catch (InterruptedException e) { 3105 Log.wtf(TAG, e); 3106 } 3107 3108 } 3109 } 3110 } 3111 3112 } finally { 3113 observer.stopWatching(); 3114 } 3115 3116 if (nativeProcs != null) { 3117 int[] pids = Process.getPidsForCommands(nativeProcs); 3118 if (pids != null) { 3119 for (int pid : pids) { 3120 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3121 } 3122 } 3123 } 3124 } 3125 3126 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3127 if (true || IS_USER_BUILD) { 3128 return; 3129 } 3130 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3131 if (tracesPath == null || tracesPath.length() == 0) { 3132 return; 3133 } 3134 3135 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3136 StrictMode.allowThreadDiskWrites(); 3137 try { 3138 final File tracesFile = new File(tracesPath); 3139 final File tracesDir = tracesFile.getParentFile(); 3140 final File tracesTmp = new File(tracesDir, "__tmp__"); 3141 try { 3142 if (!tracesDir.exists()) tracesFile.mkdirs(); 3143 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3144 3145 if (tracesFile.exists()) { 3146 tracesTmp.delete(); 3147 tracesFile.renameTo(tracesTmp); 3148 } 3149 StringBuilder sb = new StringBuilder(); 3150 Time tobj = new Time(); 3151 tobj.set(System.currentTimeMillis()); 3152 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3153 sb.append(": "); 3154 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3155 sb.append(" since "); 3156 sb.append(msg); 3157 FileOutputStream fos = new FileOutputStream(tracesFile); 3158 fos.write(sb.toString().getBytes()); 3159 if (app == null) { 3160 fos.write("\n*** No application process!".getBytes()); 3161 } 3162 fos.close(); 3163 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3164 } catch (IOException e) { 3165 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3166 return; 3167 } 3168 3169 if (app != null) { 3170 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3171 firstPids.add(app.pid); 3172 dumpStackTraces(tracesPath, firstPids, null, null, null); 3173 } 3174 3175 File lastTracesFile = null; 3176 File curTracesFile = null; 3177 for (int i=9; i>=0; i--) { 3178 String name = String.format("slow%02d.txt", i); 3179 curTracesFile = new File(tracesDir, name); 3180 if (curTracesFile.exists()) { 3181 if (lastTracesFile != null) { 3182 curTracesFile.renameTo(lastTracesFile); 3183 } else { 3184 curTracesFile.delete(); 3185 } 3186 } 3187 lastTracesFile = curTracesFile; 3188 } 3189 tracesFile.renameTo(curTracesFile); 3190 if (tracesTmp.exists()) { 3191 tracesTmp.renameTo(tracesFile); 3192 } 3193 } finally { 3194 StrictMode.setThreadPolicy(oldPolicy); 3195 } 3196 } 3197 3198 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3199 ActivityRecord parent, final String annotation) { 3200 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3201 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3202 3203 if (mController != null) { 3204 try { 3205 // 0 == continue, -1 = kill process immediately 3206 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3207 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3208 } catch (RemoteException e) { 3209 mController = null; 3210 } 3211 } 3212 3213 long anrTime = SystemClock.uptimeMillis(); 3214 if (MONITOR_CPU_USAGE) { 3215 updateCpuStatsNow(); 3216 } 3217 3218 synchronized (this) { 3219 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3220 if (mShuttingDown) { 3221 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3222 return; 3223 } else if (app.notResponding) { 3224 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3225 return; 3226 } else if (app.crashing) { 3227 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3228 return; 3229 } 3230 3231 // In case we come through here for the same app before completing 3232 // this one, mark as anring now so we will bail out. 3233 app.notResponding = true; 3234 3235 // Log the ANR to the event log. 3236 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3237 annotation); 3238 3239 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3240 firstPids.add(app.pid); 3241 3242 int parentPid = app.pid; 3243 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3244 if (parentPid != app.pid) firstPids.add(parentPid); 3245 3246 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3247 3248 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3249 ProcessRecord r = mLruProcesses.get(i); 3250 if (r != null && r.thread != null) { 3251 int pid = r.pid; 3252 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3253 if (r.persistent) { 3254 firstPids.add(pid); 3255 } else { 3256 lastPids.put(pid, Boolean.TRUE); 3257 } 3258 } 3259 } 3260 } 3261 } 3262 3263 // Log the ANR to the main log. 3264 StringBuilder info = new StringBuilder(); 3265 info.setLength(0); 3266 info.append("ANR in ").append(app.processName); 3267 if (activity != null && activity.shortComponentName != null) { 3268 info.append(" (").append(activity.shortComponentName).append(")"); 3269 } 3270 info.append("\n"); 3271 if (annotation != null) { 3272 info.append("Reason: ").append(annotation).append("\n"); 3273 } 3274 if (parent != null && parent != activity) { 3275 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3276 } 3277 3278 final ProcessStats processStats = new ProcessStats(true); 3279 3280 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3281 3282 String cpuInfo = null; 3283 if (MONITOR_CPU_USAGE) { 3284 updateCpuStatsNow(); 3285 synchronized (mProcessStatsThread) { 3286 cpuInfo = mProcessStats.printCurrentState(anrTime); 3287 } 3288 info.append(processStats.printCurrentLoad()); 3289 info.append(cpuInfo); 3290 } 3291 3292 info.append(processStats.printCurrentState(anrTime)); 3293 3294 Slog.e(TAG, info.toString()); 3295 if (tracesFile == null) { 3296 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3297 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3298 } 3299 3300 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3301 cpuInfo, tracesFile, null); 3302 3303 if (mController != null) { 3304 try { 3305 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3306 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3307 if (res != 0) { 3308 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3309 return; 3310 } 3311 } catch (RemoteException e) { 3312 mController = null; 3313 } 3314 } 3315 3316 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3317 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3318 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3319 3320 synchronized (this) { 3321 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3322 Slog.w(TAG, "Killing " + app + ": background ANR"); 3323 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3324 app.processName, app.setAdj, "background ANR"); 3325 Process.killProcessQuiet(app.pid); 3326 return; 3327 } 3328 3329 // Set the app's notResponding state, and look up the errorReportReceiver 3330 makeAppNotRespondingLocked(app, 3331 activity != null ? activity.shortComponentName : null, 3332 annotation != null ? "ANR " + annotation : "ANR", 3333 info.toString()); 3334 3335 // Bring up the infamous App Not Responding dialog 3336 Message msg = Message.obtain(); 3337 HashMap map = new HashMap(); 3338 msg.what = SHOW_NOT_RESPONDING_MSG; 3339 msg.obj = map; 3340 map.put("app", app); 3341 if (activity != null) { 3342 map.put("activity", activity); 3343 } 3344 3345 mHandler.sendMessage(msg); 3346 } 3347 } 3348 3349 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3350 if (!mLaunchWarningShown) { 3351 mLaunchWarningShown = true; 3352 mHandler.post(new Runnable() { 3353 @Override 3354 public void run() { 3355 synchronized (ActivityManagerService.this) { 3356 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3357 d.show(); 3358 mHandler.postDelayed(new Runnable() { 3359 @Override 3360 public void run() { 3361 synchronized (ActivityManagerService.this) { 3362 d.dismiss(); 3363 mLaunchWarningShown = false; 3364 } 3365 } 3366 }, 4000); 3367 } 3368 } 3369 }); 3370 } 3371 } 3372 3373 public boolean clearApplicationUserData(final String packageName, 3374 final IPackageDataObserver observer, final int userId) { 3375 enforceNotIsolatedCaller("clearApplicationUserData"); 3376 int uid = Binder.getCallingUid(); 3377 int pid = Binder.getCallingPid(); 3378 long callingId = Binder.clearCallingIdentity(); 3379 try { 3380 IPackageManager pm = AppGlobals.getPackageManager(); 3381 int pkgUid = -1; 3382 synchronized(this) { 3383 try { 3384 pkgUid = pm.getPackageUid(packageName, userId); 3385 } catch (RemoteException e) { 3386 } 3387 if (pkgUid == -1) { 3388 Slog.w(TAG, "Invalid packageName:" + packageName); 3389 return false; 3390 } 3391 if (uid == pkgUid || checkComponentPermission( 3392 android.Manifest.permission.CLEAR_APP_USER_DATA, 3393 pid, uid, -1, true) 3394 == PackageManager.PERMISSION_GRANTED) { 3395 forceStopPackageLocked(packageName, pkgUid); 3396 } else { 3397 throw new SecurityException(pid+" does not have permission:"+ 3398 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3399 "for process:"+packageName); 3400 } 3401 } 3402 3403 try { 3404 //clear application user data 3405 pm.clearApplicationUserData(packageName, observer, userId); 3406 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3407 Uri.fromParts("package", packageName, null)); 3408 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3409 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3410 null, null, 0, null, null, null, false, false, userId); 3411 } catch (RemoteException e) { 3412 } 3413 } finally { 3414 Binder.restoreCallingIdentity(callingId); 3415 } 3416 return true; 3417 } 3418 3419 public void killBackgroundProcesses(final String packageName) { 3420 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3421 != PackageManager.PERMISSION_GRANTED && 3422 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3423 != PackageManager.PERMISSION_GRANTED) { 3424 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3425 + Binder.getCallingPid() 3426 + ", uid=" + Binder.getCallingUid() 3427 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3428 Slog.w(TAG, msg); 3429 throw new SecurityException(msg); 3430 } 3431 3432 int userId = UserHandle.getCallingUserId(); 3433 long callingId = Binder.clearCallingIdentity(); 3434 try { 3435 IPackageManager pm = AppGlobals.getPackageManager(); 3436 int pkgUid = -1; 3437 synchronized(this) { 3438 try { 3439 pkgUid = pm.getPackageUid(packageName, userId); 3440 } catch (RemoteException e) { 3441 } 3442 if (pkgUid == -1) { 3443 Slog.w(TAG, "Invalid packageName: " + packageName); 3444 return; 3445 } 3446 killPackageProcessesLocked(packageName, pkgUid, 3447 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3448 } 3449 } finally { 3450 Binder.restoreCallingIdentity(callingId); 3451 } 3452 } 3453 3454 public void killAllBackgroundProcesses() { 3455 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3456 != PackageManager.PERMISSION_GRANTED) { 3457 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3458 + Binder.getCallingPid() 3459 + ", uid=" + Binder.getCallingUid() 3460 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3461 Slog.w(TAG, msg); 3462 throw new SecurityException(msg); 3463 } 3464 3465 long callingId = Binder.clearCallingIdentity(); 3466 try { 3467 synchronized(this) { 3468 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3469 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3470 final int NA = apps.size(); 3471 for (int ia=0; ia<NA; ia++) { 3472 ProcessRecord app = apps.valueAt(ia); 3473 if (app.persistent) { 3474 // we don't kill persistent processes 3475 continue; 3476 } 3477 if (app.removed) { 3478 procs.add(app); 3479 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3480 app.removed = true; 3481 procs.add(app); 3482 } 3483 } 3484 } 3485 3486 int N = procs.size(); 3487 for (int i=0; i<N; i++) { 3488 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3489 } 3490 } 3491 } finally { 3492 Binder.restoreCallingIdentity(callingId); 3493 } 3494 } 3495 3496 public void forceStopPackage(final String packageName) { 3497 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3498 != PackageManager.PERMISSION_GRANTED) { 3499 String msg = "Permission Denial: forceStopPackage() from pid=" 3500 + Binder.getCallingPid() 3501 + ", uid=" + Binder.getCallingUid() 3502 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3503 Slog.w(TAG, msg); 3504 throw new SecurityException(msg); 3505 } 3506 final int userId = UserHandle.getCallingUserId(); 3507 long callingId = Binder.clearCallingIdentity(); 3508 try { 3509 IPackageManager pm = AppGlobals.getPackageManager(); 3510 int pkgUid = -1; 3511 synchronized(this) { 3512 try { 3513 pkgUid = pm.getPackageUid(packageName, userId); 3514 } catch (RemoteException e) { 3515 } 3516 if (pkgUid == -1) { 3517 Slog.w(TAG, "Invalid packageName: " + packageName); 3518 return; 3519 } 3520 forceStopPackageLocked(packageName, pkgUid); 3521 try { 3522 pm.setPackageStoppedState(packageName, true, userId); 3523 } catch (RemoteException e) { 3524 } catch (IllegalArgumentException e) { 3525 Slog.w(TAG, "Failed trying to unstop package " 3526 + packageName + ": " + e); 3527 } 3528 } 3529 } finally { 3530 Binder.restoreCallingIdentity(callingId); 3531 } 3532 } 3533 3534 /* 3535 * The pkg name and uid have to be specified. 3536 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3537 */ 3538 public void killApplicationWithUid(String pkg, int uid) { 3539 if (pkg == null) { 3540 return; 3541 } 3542 // Make sure the uid is valid. 3543 if (uid < 0) { 3544 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3545 return; 3546 } 3547 int callerUid = Binder.getCallingUid(); 3548 // Only the system server can kill an application 3549 if (callerUid == Process.SYSTEM_UID) { 3550 // Post an aysnc message to kill the application 3551 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3552 msg.arg1 = uid; 3553 msg.arg2 = 0; 3554 msg.obj = pkg; 3555 mHandler.sendMessage(msg); 3556 } else { 3557 throw new SecurityException(callerUid + " cannot kill pkg: " + 3558 pkg); 3559 } 3560 } 3561 3562 public void closeSystemDialogs(String reason) { 3563 enforceNotIsolatedCaller("closeSystemDialogs"); 3564 3565 final int uid = Binder.getCallingUid(); 3566 final long origId = Binder.clearCallingIdentity(); 3567 synchronized (this) { 3568 closeSystemDialogsLocked(uid, reason); 3569 } 3570 Binder.restoreCallingIdentity(origId); 3571 } 3572 3573 void closeSystemDialogsLocked(int callingUid, String reason) { 3574 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3575 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3576 if (reason != null) { 3577 intent.putExtra("reason", reason); 3578 } 3579 mWindowManager.closeSystemDialogs(reason); 3580 3581 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3582 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3583 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3584 r.stack.finishActivityLocked(r, i, 3585 Activity.RESULT_CANCELED, null, "close-sys"); 3586 } 3587 } 3588 3589 broadcastIntentLocked(null, null, intent, null, 3590 null, 0, null, null, null, false, false, -1, 3591 callingUid, 0 /* TODO: Verify */); 3592 } 3593 3594 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3595 throws RemoteException { 3596 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3597 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3598 for (int i=pids.length-1; i>=0; i--) { 3599 infos[i] = new Debug.MemoryInfo(); 3600 Debug.getMemoryInfo(pids[i], infos[i]); 3601 } 3602 return infos; 3603 } 3604 3605 public long[] getProcessPss(int[] pids) throws RemoteException { 3606 enforceNotIsolatedCaller("getProcessPss"); 3607 long[] pss = new long[pids.length]; 3608 for (int i=pids.length-1; i>=0; i--) { 3609 pss[i] = Debug.getPss(pids[i]); 3610 } 3611 return pss; 3612 } 3613 3614 public void killApplicationProcess(String processName, int uid) { 3615 if (processName == null) { 3616 return; 3617 } 3618 3619 int callerUid = Binder.getCallingUid(); 3620 // Only the system server can kill an application 3621 if (callerUid == Process.SYSTEM_UID) { 3622 synchronized (this) { 3623 ProcessRecord app = getProcessRecordLocked(processName, uid); 3624 if (app != null && app.thread != null) { 3625 try { 3626 app.thread.scheduleSuicide(); 3627 } catch (RemoteException e) { 3628 // If the other end already died, then our work here is done. 3629 } 3630 } else { 3631 Slog.w(TAG, "Process/uid not found attempting kill of " 3632 + processName + " / " + uid); 3633 } 3634 } 3635 } else { 3636 throw new SecurityException(callerUid + " cannot kill app process: " + 3637 processName); 3638 } 3639 } 3640 3641 private void forceStopPackageLocked(final String packageName, int uid) { 3642 forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid)); 3643 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3644 Uri.fromParts("package", packageName, null)); 3645 if (!mProcessesReady) { 3646 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3647 } 3648 intent.putExtra(Intent.EXTRA_UID, uid); 3649 broadcastIntentLocked(null, null, intent, 3650 null, null, 0, null, null, null, 3651 false, false, 3652 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3653 } 3654 3655 private final boolean killPackageProcessesLocked(String packageName, int uid, 3656 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3657 boolean evenPersistent, String reason) { 3658 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3659 3660 // Remove all processes this package may have touched: all with the 3661 // same UID (except for the system or root user), and all whose name 3662 // matches the package name. 3663 final String procNamePrefix = packageName + ":"; 3664 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3665 final int NA = apps.size(); 3666 for (int ia=0; ia<NA; ia++) { 3667 ProcessRecord app = apps.valueAt(ia); 3668 if (app.persistent && !evenPersistent) { 3669 // we don't kill persistent processes 3670 continue; 3671 } 3672 if (app.removed) { 3673 if (doit) { 3674 procs.add(app); 3675 } 3676 // If uid is specified and the uid and process name match 3677 // Or, the uid is not specified and the process name matches 3678 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3679 || ((app.processName.equals(packageName) 3680 || app.processName.startsWith(procNamePrefix)) 3681 && uid < 0))) { 3682 if (app.setAdj >= minOomAdj) { 3683 if (!doit) { 3684 return true; 3685 } 3686 app.removed = true; 3687 procs.add(app); 3688 } 3689 } 3690 } 3691 } 3692 3693 int N = procs.size(); 3694 for (int i=0; i<N; i++) { 3695 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3696 } 3697 return N > 0; 3698 } 3699 3700 private final boolean forceStopPackageLocked(String name, int uid, 3701 boolean callerWillRestart, boolean purgeCache, boolean doit, 3702 boolean evenPersistent, int userId) { 3703 int i; 3704 int N; 3705 3706 if (uid < 0) { 3707 try { 3708 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3709 } catch (RemoteException e) { 3710 } 3711 } 3712 3713 if (doit) { 3714 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3715 3716 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3717 while (badApps.hasNext()) { 3718 SparseArray<Long> ba = badApps.next(); 3719 if (ba.get(uid) != null) { 3720 badApps.remove(); 3721 } 3722 } 3723 } 3724 3725 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3726 callerWillRestart, false, doit, evenPersistent, "force stop"); 3727 3728 TaskRecord lastTask = null; 3729 for (i=0; i<mMainStack.mHistory.size(); i++) { 3730 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3731 final boolean samePackage = r.packageName.equals(name); 3732 if (r.userId == userId 3733 && (samePackage || r.task == lastTask) 3734 && (r.app == null || evenPersistent || !r.app.persistent)) { 3735 if (!doit) { 3736 if (r.finishing) { 3737 // If this activity is just finishing, then it is not 3738 // interesting as far as something to stop. 3739 continue; 3740 } 3741 return true; 3742 } 3743 didSomething = true; 3744 Slog.i(TAG, " Force finishing activity " + r); 3745 if (samePackage) { 3746 if (r.app != null) { 3747 r.app.removed = true; 3748 } 3749 r.app = null; 3750 } 3751 lastTask = r.task; 3752 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3753 null, "force-stop", true)) { 3754 i--; 3755 } 3756 } 3757 } 3758 3759 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3760 if (!doit) { 3761 return true; 3762 } 3763 didSomething = true; 3764 } 3765 3766 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3767 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3768 if (provider.info.packageName.equals(name) 3769 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3770 if (!doit) { 3771 return true; 3772 } 3773 didSomething = true; 3774 providers.add(provider); 3775 } 3776 } 3777 3778 N = providers.size(); 3779 for (i=0; i<N; i++) { 3780 removeDyingProviderLocked(null, providers.get(i), true); 3781 } 3782 3783 if (doit) { 3784 if (purgeCache) { 3785 AttributeCache ac = AttributeCache.instance(); 3786 if (ac != null) { 3787 ac.removePackage(name); 3788 } 3789 } 3790 if (mBooted) { 3791 mMainStack.resumeTopActivityLocked(null); 3792 mMainStack.scheduleIdleLocked(); 3793 } 3794 } 3795 3796 return didSomething; 3797 } 3798 3799 private final boolean removeProcessLocked(ProcessRecord app, 3800 boolean callerWillRestart, boolean allowRestart, String reason) { 3801 final String name = app.processName; 3802 final int uid = app.uid; 3803 if (DEBUG_PROCESSES) Slog.d( 3804 TAG, "Force removing proc " + app.toShortString() + " (" + name 3805 + "/" + uid + ")"); 3806 3807 mProcessNames.remove(name, uid); 3808 mIsolatedProcesses.remove(app.uid); 3809 if (mHeavyWeightProcess == app) { 3810 mHeavyWeightProcess = null; 3811 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3812 } 3813 boolean needRestart = false; 3814 if (app.pid > 0 && app.pid != MY_PID) { 3815 int pid = app.pid; 3816 synchronized (mPidsSelfLocked) { 3817 mPidsSelfLocked.remove(pid); 3818 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3819 } 3820 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3821 handleAppDiedLocked(app, true, allowRestart); 3822 mLruProcesses.remove(app); 3823 Process.killProcessQuiet(pid); 3824 3825 if (app.persistent && !app.isolated) { 3826 if (!callerWillRestart) { 3827 addAppLocked(app.info, false); 3828 } else { 3829 needRestart = true; 3830 } 3831 } 3832 } else { 3833 mRemovedProcesses.add(app); 3834 } 3835 3836 return needRestart; 3837 } 3838 3839 private final void processStartTimedOutLocked(ProcessRecord app) { 3840 final int pid = app.pid; 3841 boolean gone = false; 3842 synchronized (mPidsSelfLocked) { 3843 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3844 if (knownApp != null && knownApp.thread == null) { 3845 mPidsSelfLocked.remove(pid); 3846 gone = true; 3847 } 3848 } 3849 3850 if (gone) { 3851 Slog.w(TAG, "Process " + app + " failed to attach"); 3852 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3853 app.processName); 3854 mProcessNames.remove(app.processName, app.uid); 3855 mIsolatedProcesses.remove(app.uid); 3856 if (mHeavyWeightProcess == app) { 3857 mHeavyWeightProcess = null; 3858 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3859 } 3860 // Take care of any launching providers waiting for this process. 3861 checkAppInLaunchingProvidersLocked(app, true); 3862 // Take care of any services that are waiting for the process. 3863 mServices.processStartTimedOutLocked(app); 3864 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3865 app.processName, app.setAdj, "start timeout"); 3866 Process.killProcessQuiet(pid); 3867 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3868 Slog.w(TAG, "Unattached app died before backup, skipping"); 3869 try { 3870 IBackupManager bm = IBackupManager.Stub.asInterface( 3871 ServiceManager.getService(Context.BACKUP_SERVICE)); 3872 bm.agentDisconnected(app.info.packageName); 3873 } catch (RemoteException e) { 3874 // Can't happen; the backup manager is local 3875 } 3876 } 3877 if (isPendingBroadcastProcessLocked(pid)) { 3878 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3879 skipPendingBroadcastLocked(pid); 3880 } 3881 } else { 3882 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3883 } 3884 } 3885 3886 private final boolean attachApplicationLocked(IApplicationThread thread, 3887 int pid) { 3888 3889 // Find the application record that is being attached... either via 3890 // the pid if we are running in multiple processes, or just pull the 3891 // next app record if we are emulating process with anonymous threads. 3892 ProcessRecord app; 3893 if (pid != MY_PID && pid >= 0) { 3894 synchronized (mPidsSelfLocked) { 3895 app = mPidsSelfLocked.get(pid); 3896 } 3897 } else { 3898 app = null; 3899 } 3900 3901 if (app == null) { 3902 Slog.w(TAG, "No pending application record for pid " + pid 3903 + " (IApplicationThread " + thread + "); dropping process"); 3904 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3905 if (pid > 0 && pid != MY_PID) { 3906 Process.killProcessQuiet(pid); 3907 } else { 3908 try { 3909 thread.scheduleExit(); 3910 } catch (Exception e) { 3911 // Ignore exceptions. 3912 } 3913 } 3914 return false; 3915 } 3916 3917 // If this application record is still attached to a previous 3918 // process, clean it up now. 3919 if (app.thread != null) { 3920 handleAppDiedLocked(app, true, true); 3921 } 3922 3923 // Tell the process all about itself. 3924 3925 if (localLOGV) Slog.v( 3926 TAG, "Binding process pid " + pid + " to record " + app); 3927 3928 String processName = app.processName; 3929 try { 3930 AppDeathRecipient adr = new AppDeathRecipient( 3931 app, pid, thread); 3932 thread.asBinder().linkToDeath(adr, 0); 3933 app.deathRecipient = adr; 3934 } catch (RemoteException e) { 3935 app.resetPackageList(); 3936 startProcessLocked(app, "link fail", processName); 3937 return false; 3938 } 3939 3940 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3941 3942 app.thread = thread; 3943 app.curAdj = app.setAdj = -100; 3944 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3945 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3946 app.forcingToForeground = null; 3947 app.foregroundServices = false; 3948 app.hasShownUi = false; 3949 app.debugging = false; 3950 3951 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3952 3953 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3954 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3955 3956 if (!normalMode) { 3957 Slog.i(TAG, "Launching preboot mode app: " + app); 3958 } 3959 3960 if (localLOGV) Slog.v( 3961 TAG, "New app record " + app 3962 + " thread=" + thread.asBinder() + " pid=" + pid); 3963 try { 3964 int testMode = IApplicationThread.DEBUG_OFF; 3965 if (mDebugApp != null && mDebugApp.equals(processName)) { 3966 testMode = mWaitForDebugger 3967 ? IApplicationThread.DEBUG_WAIT 3968 : IApplicationThread.DEBUG_ON; 3969 app.debugging = true; 3970 if (mDebugTransient) { 3971 mDebugApp = mOrigDebugApp; 3972 mWaitForDebugger = mOrigWaitForDebugger; 3973 } 3974 } 3975 String profileFile = app.instrumentationProfileFile; 3976 ParcelFileDescriptor profileFd = null; 3977 boolean profileAutoStop = false; 3978 if (mProfileApp != null && mProfileApp.equals(processName)) { 3979 mProfileProc = app; 3980 profileFile = mProfileFile; 3981 profileFd = mProfileFd; 3982 profileAutoStop = mAutoStopProfiler; 3983 } 3984 boolean enableOpenGlTrace = false; 3985 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3986 enableOpenGlTrace = true; 3987 mOpenGlTraceApp = null; 3988 } 3989 3990 // If the app is being launched for restore or full backup, set it up specially 3991 boolean isRestrictedBackupMode = false; 3992 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3993 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3994 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3995 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3996 } 3997 3998 ensurePackageDexOpt(app.instrumentationInfo != null 3999 ? app.instrumentationInfo.packageName 4000 : app.info.packageName); 4001 if (app.instrumentationClass != null) { 4002 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4003 } 4004 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4005 + processName + " with config " + mConfiguration); 4006 ApplicationInfo appInfo = app.instrumentationInfo != null 4007 ? app.instrumentationInfo : app.info; 4008 app.compat = compatibilityInfoForPackageLocked(appInfo); 4009 if (profileFd != null) { 4010 profileFd = profileFd.dup(); 4011 } 4012 thread.bindApplication(processName, appInfo, providers, 4013 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4014 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4015 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4016 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4017 mCoreSettingsObserver.getCoreSettingsLocked()); 4018 updateLruProcessLocked(app, false, true); 4019 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4020 } catch (Exception e) { 4021 // todo: Yikes! What should we do? For now we will try to 4022 // start another process, but that could easily get us in 4023 // an infinite loop of restarting processes... 4024 Slog.w(TAG, "Exception thrown during bind!", e); 4025 4026 app.resetPackageList(); 4027 app.unlinkDeathRecipient(); 4028 startProcessLocked(app, "bind fail", processName); 4029 return false; 4030 } 4031 4032 // Remove this record from the list of starting applications. 4033 mPersistentStartingProcesses.remove(app); 4034 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4035 "Attach application locked removing on hold: " + app); 4036 mProcessesOnHold.remove(app); 4037 4038 boolean badApp = false; 4039 boolean didSomething = false; 4040 4041 // See if the top visible activity is waiting to run in this process... 4042 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4043 if (hr != null && normalMode) { 4044 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4045 && processName.equals(hr.processName)) { 4046 try { 4047 if (mHeadless) { 4048 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4049 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4050 didSomething = true; 4051 } 4052 } catch (Exception e) { 4053 Slog.w(TAG, "Exception in new application when starting activity " 4054 + hr.intent.getComponent().flattenToShortString(), e); 4055 badApp = true; 4056 } 4057 } else { 4058 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4059 } 4060 } 4061 4062 // Find any services that should be running in this process... 4063 if (!badApp) { 4064 try { 4065 didSomething |= mServices.attachApplicationLocked(app, processName); 4066 } catch (Exception e) { 4067 badApp = true; 4068 } 4069 } 4070 4071 // Check if a next-broadcast receiver is in this process... 4072 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4073 try { 4074 didSomething = sendPendingBroadcastsLocked(app); 4075 } catch (Exception e) { 4076 // If the app died trying to launch the receiver we declare it 'bad' 4077 badApp = true; 4078 } 4079 } 4080 4081 // Check whether the next backup agent is in this process... 4082 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4083 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4084 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4085 try { 4086 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4087 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4088 mBackupTarget.backupMode); 4089 } catch (Exception e) { 4090 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4091 e.printStackTrace(); 4092 } 4093 } 4094 4095 if (badApp) { 4096 // todo: Also need to kill application to deal with all 4097 // kinds of exceptions. 4098 handleAppDiedLocked(app, false, true); 4099 return false; 4100 } 4101 4102 if (!didSomething) { 4103 updateOomAdjLocked(); 4104 } 4105 4106 return true; 4107 } 4108 4109 public final void attachApplication(IApplicationThread thread) { 4110 synchronized (this) { 4111 int callingPid = Binder.getCallingPid(); 4112 final long origId = Binder.clearCallingIdentity(); 4113 attachApplicationLocked(thread, callingPid); 4114 Binder.restoreCallingIdentity(origId); 4115 } 4116 } 4117 4118 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4119 final long origId = Binder.clearCallingIdentity(); 4120 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4121 if (stopProfiling) { 4122 synchronized (this) { 4123 if (mProfileProc == r.app) { 4124 if (mProfileFd != null) { 4125 try { 4126 mProfileFd.close(); 4127 } catch (IOException e) { 4128 } 4129 clearProfilerLocked(); 4130 } 4131 } 4132 } 4133 } 4134 Binder.restoreCallingIdentity(origId); 4135 } 4136 4137 void enableScreenAfterBoot() { 4138 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4139 SystemClock.uptimeMillis()); 4140 mWindowManager.enableScreenAfterBoot(); 4141 4142 synchronized (this) { 4143 updateEventDispatchingLocked(); 4144 } 4145 } 4146 4147 public void showBootMessage(final CharSequence msg, final boolean always) { 4148 enforceNotIsolatedCaller("showBootMessage"); 4149 mWindowManager.showBootMessage(msg, always); 4150 } 4151 4152 public void dismissKeyguardOnNextActivity() { 4153 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4154 final long token = Binder.clearCallingIdentity(); 4155 try { 4156 synchronized (this) { 4157 if (mLockScreenShown) { 4158 mLockScreenShown = false; 4159 comeOutOfSleepIfNeededLocked(); 4160 } 4161 mMainStack.dismissKeyguardOnNextActivityLocked(); 4162 } 4163 } finally { 4164 Binder.restoreCallingIdentity(token); 4165 } 4166 } 4167 4168 final void finishBooting() { 4169 IntentFilter pkgFilter = new IntentFilter(); 4170 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4171 pkgFilter.addDataScheme("package"); 4172 mContext.registerReceiver(new BroadcastReceiver() { 4173 @Override 4174 public void onReceive(Context context, Intent intent) { 4175 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4176 if (pkgs != null) { 4177 for (String pkg : pkgs) { 4178 synchronized (ActivityManagerService.this) { 4179 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4180 setResultCode(Activity.RESULT_OK); 4181 return; 4182 } 4183 } 4184 } 4185 } 4186 } 4187 }, pkgFilter); 4188 4189 IntentFilter userFilter = new IntentFilter(); 4190 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4191 mContext.registerReceiver(new BroadcastReceiver() { 4192 @Override 4193 public void onReceive(Context context, Intent intent) { 4194 onUserRemoved(intent); 4195 } 4196 }, userFilter); 4197 4198 synchronized (this) { 4199 // Ensure that any processes we had put on hold are now started 4200 // up. 4201 final int NP = mProcessesOnHold.size(); 4202 if (NP > 0) { 4203 ArrayList<ProcessRecord> procs = 4204 new ArrayList<ProcessRecord>(mProcessesOnHold); 4205 for (int ip=0; ip<NP; ip++) { 4206 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4207 + procs.get(ip)); 4208 startProcessLocked(procs.get(ip), "on-hold", null); 4209 } 4210 } 4211 4212 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4213 // Start looking for apps that are abusing wake locks. 4214 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4215 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4216 // Tell anyone interested that we are done booting! 4217 SystemProperties.set("sys.boot_completed", "1"); 4218 SystemProperties.set("dev.bootcomplete", "1"); 4219 List<UserInfo> users = getUserManager().getUsers(); 4220 for (UserInfo user : users) { 4221 broadcastIntentLocked(null, null, 4222 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4223 null, null, 0, null, null, 4224 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4225 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4226 } 4227 } 4228 } 4229 } 4230 4231 final void ensureBootCompleted() { 4232 boolean booting; 4233 boolean enableScreen; 4234 synchronized (this) { 4235 booting = mBooting; 4236 mBooting = false; 4237 enableScreen = !mBooted; 4238 mBooted = true; 4239 } 4240 4241 if (booting) { 4242 finishBooting(); 4243 } 4244 4245 if (enableScreen) { 4246 enableScreenAfterBoot(); 4247 } 4248 } 4249 4250 public final void activityPaused(IBinder token) { 4251 final long origId = Binder.clearCallingIdentity(); 4252 mMainStack.activityPaused(token, false); 4253 Binder.restoreCallingIdentity(origId); 4254 } 4255 4256 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4257 CharSequence description) { 4258 if (localLOGV) Slog.v( 4259 TAG, "Activity stopped: token=" + token); 4260 4261 // Refuse possible leaked file descriptors 4262 if (icicle != null && icicle.hasFileDescriptors()) { 4263 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4264 } 4265 4266 ActivityRecord r = null; 4267 4268 final long origId = Binder.clearCallingIdentity(); 4269 4270 synchronized (this) { 4271 r = mMainStack.isInStackLocked(token); 4272 if (r != null) { 4273 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4274 } 4275 } 4276 4277 if (r != null) { 4278 sendPendingThumbnail(r, null, null, null, false); 4279 } 4280 4281 trimApplications(); 4282 4283 Binder.restoreCallingIdentity(origId); 4284 } 4285 4286 public final void activityDestroyed(IBinder token) { 4287 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4288 mMainStack.activityDestroyed(token); 4289 } 4290 4291 public String getCallingPackage(IBinder token) { 4292 synchronized (this) { 4293 ActivityRecord r = getCallingRecordLocked(token); 4294 return r != null && r.app != null ? r.info.packageName : null; 4295 } 4296 } 4297 4298 public ComponentName getCallingActivity(IBinder token) { 4299 synchronized (this) { 4300 ActivityRecord r = getCallingRecordLocked(token); 4301 return r != null ? r.intent.getComponent() : null; 4302 } 4303 } 4304 4305 private ActivityRecord getCallingRecordLocked(IBinder token) { 4306 ActivityRecord r = mMainStack.isInStackLocked(token); 4307 if (r == null) { 4308 return null; 4309 } 4310 return r.resultTo; 4311 } 4312 4313 public ComponentName getActivityClassForToken(IBinder token) { 4314 synchronized(this) { 4315 ActivityRecord r = mMainStack.isInStackLocked(token); 4316 if (r == null) { 4317 return null; 4318 } 4319 return r.intent.getComponent(); 4320 } 4321 } 4322 4323 public String getPackageForToken(IBinder token) { 4324 synchronized(this) { 4325 ActivityRecord r = mMainStack.isInStackLocked(token); 4326 if (r == null) { 4327 return null; 4328 } 4329 return r.packageName; 4330 } 4331 } 4332 4333 public IIntentSender getIntentSender(int type, 4334 String packageName, IBinder token, String resultWho, 4335 int requestCode, Intent[] intents, String[] resolvedTypes, 4336 int flags, Bundle options) { 4337 enforceNotIsolatedCaller("getIntentSender"); 4338 // Refuse possible leaked file descriptors 4339 if (intents != null) { 4340 if (intents.length < 1) { 4341 throw new IllegalArgumentException("Intents array length must be >= 1"); 4342 } 4343 for (int i=0; i<intents.length; i++) { 4344 Intent intent = intents[i]; 4345 if (intent != null) { 4346 if (intent.hasFileDescriptors()) { 4347 throw new IllegalArgumentException("File descriptors passed in Intent"); 4348 } 4349 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4350 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4351 throw new IllegalArgumentException( 4352 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4353 } 4354 intents[i] = new Intent(intent); 4355 } 4356 } 4357 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4358 throw new IllegalArgumentException( 4359 "Intent array length does not match resolvedTypes length"); 4360 } 4361 } 4362 if (options != null) { 4363 if (options.hasFileDescriptors()) { 4364 throw new IllegalArgumentException("File descriptors passed in options"); 4365 } 4366 } 4367 4368 synchronized(this) { 4369 int callingUid = Binder.getCallingUid(); 4370 try { 4371 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4372 int uid = AppGlobals.getPackageManager() 4373 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4374 if (!UserHandle.isSameApp(callingUid, uid)) { 4375 String msg = "Permission Denial: getIntentSender() from pid=" 4376 + Binder.getCallingPid() 4377 + ", uid=" + Binder.getCallingUid() 4378 + ", (need uid=" + uid + ")" 4379 + " is not allowed to send as package " + packageName; 4380 Slog.w(TAG, msg); 4381 throw new SecurityException(msg); 4382 } 4383 } 4384 4385 if (DEBUG_MU) 4386 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4387 + Binder.getOrigCallingUid()); 4388 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4389 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4390 4391 } catch (RemoteException e) { 4392 throw new SecurityException(e); 4393 } 4394 } 4395 } 4396 4397 IIntentSender getIntentSenderLocked(int type, 4398 String packageName, int callingUid, IBinder token, String resultWho, 4399 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4400 Bundle options) { 4401 if (DEBUG_MU) 4402 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4403 ActivityRecord activity = null; 4404 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4405 activity = mMainStack.isInStackLocked(token); 4406 if (activity == null) { 4407 return null; 4408 } 4409 if (activity.finishing) { 4410 return null; 4411 } 4412 } 4413 4414 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4415 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4416 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4417 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4418 |PendingIntent.FLAG_UPDATE_CURRENT); 4419 4420 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4421 type, packageName, activity, resultWho, 4422 requestCode, intents, resolvedTypes, flags, options); 4423 WeakReference<PendingIntentRecord> ref; 4424 ref = mIntentSenderRecords.get(key); 4425 PendingIntentRecord rec = ref != null ? ref.get() : null; 4426 if (rec != null) { 4427 if (!cancelCurrent) { 4428 if (updateCurrent) { 4429 if (rec.key.requestIntent != null) { 4430 rec.key.requestIntent.replaceExtras(intents != null ? 4431 intents[intents.length - 1] : null); 4432 } 4433 if (intents != null) { 4434 intents[intents.length-1] = rec.key.requestIntent; 4435 rec.key.allIntents = intents; 4436 rec.key.allResolvedTypes = resolvedTypes; 4437 } else { 4438 rec.key.allIntents = null; 4439 rec.key.allResolvedTypes = null; 4440 } 4441 } 4442 return rec; 4443 } 4444 rec.canceled = true; 4445 mIntentSenderRecords.remove(key); 4446 } 4447 if (noCreate) { 4448 return rec; 4449 } 4450 rec = new PendingIntentRecord(this, key, callingUid); 4451 mIntentSenderRecords.put(key, rec.ref); 4452 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4453 if (activity.pendingResults == null) { 4454 activity.pendingResults 4455 = new HashSet<WeakReference<PendingIntentRecord>>(); 4456 } 4457 activity.pendingResults.add(rec.ref); 4458 } 4459 return rec; 4460 } 4461 4462 public void cancelIntentSender(IIntentSender sender) { 4463 if (!(sender instanceof PendingIntentRecord)) { 4464 return; 4465 } 4466 synchronized(this) { 4467 PendingIntentRecord rec = (PendingIntentRecord)sender; 4468 try { 4469 int uid = AppGlobals.getPackageManager() 4470 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4471 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4472 String msg = "Permission Denial: cancelIntentSender() from pid=" 4473 + Binder.getCallingPid() 4474 + ", uid=" + Binder.getCallingUid() 4475 + " is not allowed to cancel packges " 4476 + rec.key.packageName; 4477 Slog.w(TAG, msg); 4478 throw new SecurityException(msg); 4479 } 4480 } catch (RemoteException e) { 4481 throw new SecurityException(e); 4482 } 4483 cancelIntentSenderLocked(rec, true); 4484 } 4485 } 4486 4487 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4488 rec.canceled = true; 4489 mIntentSenderRecords.remove(rec.key); 4490 if (cleanActivity && rec.key.activity != null) { 4491 rec.key.activity.pendingResults.remove(rec.ref); 4492 } 4493 } 4494 4495 public String getPackageForIntentSender(IIntentSender pendingResult) { 4496 if (!(pendingResult instanceof PendingIntentRecord)) { 4497 return null; 4498 } 4499 try { 4500 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4501 return res.key.packageName; 4502 } catch (ClassCastException e) { 4503 } 4504 return null; 4505 } 4506 4507 public int getUidForIntentSender(IIntentSender sender) { 4508 if (sender instanceof PendingIntentRecord) { 4509 try { 4510 PendingIntentRecord res = (PendingIntentRecord)sender; 4511 return res.uid; 4512 } catch (ClassCastException e) { 4513 } 4514 } 4515 return -1; 4516 } 4517 4518 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4519 if (!(pendingResult instanceof PendingIntentRecord)) { 4520 return false; 4521 } 4522 try { 4523 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4524 if (res.key.allIntents == null) { 4525 return false; 4526 } 4527 for (int i=0; i<res.key.allIntents.length; i++) { 4528 Intent intent = res.key.allIntents[i]; 4529 if (intent.getPackage() != null && intent.getComponent() != null) { 4530 return false; 4531 } 4532 } 4533 return true; 4534 } catch (ClassCastException e) { 4535 } 4536 return false; 4537 } 4538 4539 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4540 if (!(pendingResult instanceof PendingIntentRecord)) { 4541 return false; 4542 } 4543 try { 4544 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4545 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4546 return true; 4547 } 4548 return false; 4549 } catch (ClassCastException e) { 4550 } 4551 return false; 4552 } 4553 4554 public void setProcessLimit(int max) { 4555 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4556 "setProcessLimit()"); 4557 synchronized (this) { 4558 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4559 mProcessLimitOverride = max; 4560 } 4561 trimApplications(); 4562 } 4563 4564 public int getProcessLimit() { 4565 synchronized (this) { 4566 return mProcessLimitOverride; 4567 } 4568 } 4569 4570 void foregroundTokenDied(ForegroundToken token) { 4571 synchronized (ActivityManagerService.this) { 4572 synchronized (mPidsSelfLocked) { 4573 ForegroundToken cur 4574 = mForegroundProcesses.get(token.pid); 4575 if (cur != token) { 4576 return; 4577 } 4578 mForegroundProcesses.remove(token.pid); 4579 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4580 if (pr == null) { 4581 return; 4582 } 4583 pr.forcingToForeground = null; 4584 pr.foregroundServices = false; 4585 } 4586 updateOomAdjLocked(); 4587 } 4588 } 4589 4590 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4591 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4592 "setProcessForeground()"); 4593 synchronized(this) { 4594 boolean changed = false; 4595 4596 synchronized (mPidsSelfLocked) { 4597 ProcessRecord pr = mPidsSelfLocked.get(pid); 4598 if (pr == null && isForeground) { 4599 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4600 return; 4601 } 4602 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4603 if (oldToken != null) { 4604 oldToken.token.unlinkToDeath(oldToken, 0); 4605 mForegroundProcesses.remove(pid); 4606 if (pr != null) { 4607 pr.forcingToForeground = null; 4608 } 4609 changed = true; 4610 } 4611 if (isForeground && token != null) { 4612 ForegroundToken newToken = new ForegroundToken() { 4613 public void binderDied() { 4614 foregroundTokenDied(this); 4615 } 4616 }; 4617 newToken.pid = pid; 4618 newToken.token = token; 4619 try { 4620 token.linkToDeath(newToken, 0); 4621 mForegroundProcesses.put(pid, newToken); 4622 pr.forcingToForeground = token; 4623 changed = true; 4624 } catch (RemoteException e) { 4625 // If the process died while doing this, we will later 4626 // do the cleanup with the process death link. 4627 } 4628 } 4629 } 4630 4631 if (changed) { 4632 updateOomAdjLocked(); 4633 } 4634 } 4635 } 4636 4637 // ========================================================= 4638 // PERMISSIONS 4639 // ========================================================= 4640 4641 static class PermissionController extends IPermissionController.Stub { 4642 ActivityManagerService mActivityManagerService; 4643 PermissionController(ActivityManagerService activityManagerService) { 4644 mActivityManagerService = activityManagerService; 4645 } 4646 4647 public boolean checkPermission(String permission, int pid, int uid) { 4648 return mActivityManagerService.checkPermission(permission, pid, 4649 uid) == PackageManager.PERMISSION_GRANTED; 4650 } 4651 } 4652 4653 /** 4654 * This can be called with or without the global lock held. 4655 */ 4656 int checkComponentPermission(String permission, int pid, int uid, 4657 int owningUid, boolean exported) { 4658 // We might be performing an operation on behalf of an indirect binder 4659 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4660 // client identity accordingly before proceeding. 4661 Identity tlsIdentity = sCallerIdentity.get(); 4662 if (tlsIdentity != null) { 4663 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4664 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4665 uid = tlsIdentity.uid; 4666 pid = tlsIdentity.pid; 4667 } 4668 4669 if (pid == MY_PID) { 4670 return PackageManager.PERMISSION_GRANTED; 4671 } 4672 4673 return ActivityManager.checkComponentPermission(permission, uid, 4674 owningUid, exported); 4675 } 4676 4677 /** 4678 * As the only public entry point for permissions checking, this method 4679 * can enforce the semantic that requesting a check on a null global 4680 * permission is automatically denied. (Internally a null permission 4681 * string is used when calling {@link #checkComponentPermission} in cases 4682 * when only uid-based security is needed.) 4683 * 4684 * This can be called with or without the global lock held. 4685 */ 4686 public int checkPermission(String permission, int pid, int uid) { 4687 if (permission == null) { 4688 return PackageManager.PERMISSION_DENIED; 4689 } 4690 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4691 } 4692 4693 /** 4694 * Binder IPC calls go through the public entry point. 4695 * This can be called with or without the global lock held. 4696 */ 4697 int checkCallingPermission(String permission) { 4698 return checkPermission(permission, 4699 Binder.getCallingPid(), 4700 UserHandle.getAppId(Binder.getCallingUid())); 4701 } 4702 4703 /** 4704 * This can be called with or without the global lock held. 4705 */ 4706 void enforceCallingPermission(String permission, String func) { 4707 if (checkCallingPermission(permission) 4708 == PackageManager.PERMISSION_GRANTED) { 4709 return; 4710 } 4711 4712 String msg = "Permission Denial: " + func + " from pid=" 4713 + Binder.getCallingPid() 4714 + ", uid=" + Binder.getCallingUid() 4715 + " requires " + permission; 4716 Slog.w(TAG, msg); 4717 throw new SecurityException(msg); 4718 } 4719 4720 /** 4721 * Determine if UID is holding permissions required to access {@link Uri} in 4722 * the given {@link ProviderInfo}. Final permission checking is always done 4723 * in {@link ContentProvider}. 4724 */ 4725 private final boolean checkHoldingPermissionsLocked( 4726 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4727 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4728 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4729 4730 if (pi.applicationInfo.uid == uid) { 4731 return true; 4732 } else if (!pi.exported) { 4733 return false; 4734 } 4735 4736 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4737 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4738 try { 4739 // check if target holds top-level <provider> permissions 4740 if (!readMet && pi.readPermission != null 4741 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4742 readMet = true; 4743 } 4744 if (!writeMet && pi.writePermission != null 4745 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4746 writeMet = true; 4747 } 4748 4749 // track if unprotected read/write is allowed; any denied 4750 // <path-permission> below removes this ability 4751 boolean allowDefaultRead = pi.readPermission == null; 4752 boolean allowDefaultWrite = pi.writePermission == null; 4753 4754 // check if target holds any <path-permission> that match uri 4755 final PathPermission[] pps = pi.pathPermissions; 4756 if (pps != null) { 4757 final String path = uri.getPath(); 4758 int i = pps.length; 4759 while (i > 0 && (!readMet || !writeMet)) { 4760 i--; 4761 PathPermission pp = pps[i]; 4762 if (pp.match(path)) { 4763 if (!readMet) { 4764 final String pprperm = pp.getReadPermission(); 4765 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4766 + pprperm + " for " + pp.getPath() 4767 + ": match=" + pp.match(path) 4768 + " check=" + pm.checkUidPermission(pprperm, uid)); 4769 if (pprperm != null) { 4770 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4771 readMet = true; 4772 } else { 4773 allowDefaultRead = false; 4774 } 4775 } 4776 } 4777 if (!writeMet) { 4778 final String ppwperm = pp.getWritePermission(); 4779 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4780 + ppwperm + " for " + pp.getPath() 4781 + ": match=" + pp.match(path) 4782 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4783 if (ppwperm != null) { 4784 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4785 writeMet = true; 4786 } else { 4787 allowDefaultWrite = false; 4788 } 4789 } 4790 } 4791 } 4792 } 4793 } 4794 4795 // grant unprotected <provider> read/write, if not blocked by 4796 // <path-permission> above 4797 if (allowDefaultRead) readMet = true; 4798 if (allowDefaultWrite) writeMet = true; 4799 4800 } catch (RemoteException e) { 4801 return false; 4802 } 4803 4804 return readMet && writeMet; 4805 } 4806 4807 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4808 int modeFlags) { 4809 // Root gets to do everything. 4810 if (uid == 0) { 4811 return true; 4812 } 4813 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4814 if (perms == null) return false; 4815 UriPermission perm = perms.get(uri); 4816 if (perm == null) return false; 4817 return (modeFlags&perm.modeFlags) == modeFlags; 4818 } 4819 4820 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4821 enforceNotIsolatedCaller("checkUriPermission"); 4822 4823 // Another redirected-binder-call permissions check as in 4824 // {@link checkComponentPermission}. 4825 Identity tlsIdentity = sCallerIdentity.get(); 4826 if (tlsIdentity != null) { 4827 uid = tlsIdentity.uid; 4828 pid = tlsIdentity.pid; 4829 } 4830 4831 uid = UserHandle.getAppId(uid); 4832 // Our own process gets to do everything. 4833 if (pid == MY_PID) { 4834 return PackageManager.PERMISSION_GRANTED; 4835 } 4836 synchronized(this) { 4837 return checkUriPermissionLocked(uri, uid, modeFlags) 4838 ? PackageManager.PERMISSION_GRANTED 4839 : PackageManager.PERMISSION_DENIED; 4840 } 4841 } 4842 4843 /** 4844 * Check if the targetPkg can be granted permission to access uri by 4845 * the callingUid using the given modeFlags. Throws a security exception 4846 * if callingUid is not allowed to do this. Returns the uid of the target 4847 * if the URI permission grant should be performed; returns -1 if it is not 4848 * needed (for example targetPkg already has permission to access the URI). 4849 * If you already know the uid of the target, you can supply it in 4850 * lastTargetUid else set that to -1. 4851 */ 4852 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4853 Uri uri, int modeFlags, int lastTargetUid) { 4854 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4855 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4856 if (modeFlags == 0) { 4857 return -1; 4858 } 4859 4860 if (targetPkg != null) { 4861 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4862 "Checking grant " + targetPkg + " permission to " + uri); 4863 } 4864 4865 final IPackageManager pm = AppGlobals.getPackageManager(); 4866 4867 // If this is not a content: uri, we can't do anything with it. 4868 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4869 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4870 "Can't grant URI permission for non-content URI: " + uri); 4871 return -1; 4872 } 4873 4874 String name = uri.getAuthority(); 4875 ProviderInfo pi = null; 4876 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4877 UserHandle.getUserId(callingUid)); 4878 if (cpr != null) { 4879 pi = cpr.info; 4880 } else { 4881 try { 4882 pi = pm.resolveContentProvider(name, 4883 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4884 } catch (RemoteException ex) { 4885 } 4886 } 4887 if (pi == null) { 4888 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4889 return -1; 4890 } 4891 4892 int targetUid = lastTargetUid; 4893 if (targetUid < 0 && targetPkg != null) { 4894 try { 4895 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4896 if (targetUid < 0) { 4897 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4898 "Can't grant URI permission no uid for: " + targetPkg); 4899 return -1; 4900 } 4901 } catch (RemoteException ex) { 4902 return -1; 4903 } 4904 } 4905 4906 if (targetUid >= 0) { 4907 // First... does the target actually need this permission? 4908 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4909 // No need to grant the target this permission. 4910 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4911 "Target " + targetPkg + " already has full permission to " + uri); 4912 return -1; 4913 } 4914 } else { 4915 // First... there is no target package, so can anyone access it? 4916 boolean allowed = pi.exported; 4917 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4918 if (pi.readPermission != null) { 4919 allowed = false; 4920 } 4921 } 4922 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4923 if (pi.writePermission != null) { 4924 allowed = false; 4925 } 4926 } 4927 if (allowed) { 4928 return -1; 4929 } 4930 } 4931 4932 // Second... is the provider allowing granting of URI permissions? 4933 if (!pi.grantUriPermissions) { 4934 throw new SecurityException("Provider " + pi.packageName 4935 + "/" + pi.name 4936 + " does not allow granting of Uri permissions (uri " 4937 + uri + ")"); 4938 } 4939 if (pi.uriPermissionPatterns != null) { 4940 final int N = pi.uriPermissionPatterns.length; 4941 boolean allowed = false; 4942 for (int i=0; i<N; i++) { 4943 if (pi.uriPermissionPatterns[i] != null 4944 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4945 allowed = true; 4946 break; 4947 } 4948 } 4949 if (!allowed) { 4950 throw new SecurityException("Provider " + pi.packageName 4951 + "/" + pi.name 4952 + " does not allow granting of permission to path of Uri " 4953 + uri); 4954 } 4955 } 4956 4957 // Third... does the caller itself have permission to access 4958 // this uri? 4959 if (callingUid != Process.myUid()) { 4960 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4961 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4962 throw new SecurityException("Uid " + callingUid 4963 + " does not have permission to uri " + uri); 4964 } 4965 } 4966 } 4967 4968 return targetUid; 4969 } 4970 4971 public int checkGrantUriPermission(int callingUid, String targetPkg, 4972 Uri uri, int modeFlags) { 4973 enforceNotIsolatedCaller("checkGrantUriPermission"); 4974 synchronized(this) { 4975 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4976 } 4977 } 4978 4979 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4980 Uri uri, int modeFlags, UriPermissionOwner owner) { 4981 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4982 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4983 if (modeFlags == 0) { 4984 return; 4985 } 4986 4987 // So here we are: the caller has the assumed permission 4988 // to the uri, and the target doesn't. Let's now give this to 4989 // the target. 4990 4991 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4992 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4993 4994 HashMap<Uri, UriPermission> targetUris 4995 = mGrantedUriPermissions.get(targetUid); 4996 if (targetUris == null) { 4997 targetUris = new HashMap<Uri, UriPermission>(); 4998 mGrantedUriPermissions.put(targetUid, targetUris); 4999 } 5000 5001 UriPermission perm = targetUris.get(uri); 5002 if (perm == null) { 5003 perm = new UriPermission(targetUid, uri); 5004 targetUris.put(uri, perm); 5005 } 5006 5007 perm.modeFlags |= modeFlags; 5008 if (owner == null) { 5009 perm.globalModeFlags |= modeFlags; 5010 } else { 5011 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5012 perm.readOwners.add(owner); 5013 owner.addReadPermission(perm); 5014 } 5015 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5016 perm.writeOwners.add(owner); 5017 owner.addWritePermission(perm); 5018 } 5019 } 5020 } 5021 5022 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5023 int modeFlags, UriPermissionOwner owner) { 5024 if (targetPkg == null) { 5025 throw new NullPointerException("targetPkg"); 5026 } 5027 5028 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5029 if (targetUid < 0) { 5030 return; 5031 } 5032 5033 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5034 } 5035 5036 static class NeededUriGrants extends ArrayList<Uri> { 5037 final String targetPkg; 5038 final int targetUid; 5039 final int flags; 5040 5041 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5042 targetPkg = _targetPkg; 5043 targetUid = _targetUid; 5044 flags = _flags; 5045 } 5046 } 5047 5048 /** 5049 * Like checkGrantUriPermissionLocked, but takes an Intent. 5050 */ 5051 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5052 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5053 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5054 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5055 + " clip=" + (intent != null ? intent.getClipData() : null) 5056 + " from " + intent + "; flags=0x" 5057 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5058 5059 if (targetPkg == null) { 5060 throw new NullPointerException("targetPkg"); 5061 } 5062 5063 if (intent == null) { 5064 return null; 5065 } 5066 Uri data = intent.getData(); 5067 ClipData clip = intent.getClipData(); 5068 if (data == null && clip == null) { 5069 return null; 5070 } 5071 if (data != null) { 5072 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5073 mode, needed != null ? needed.targetUid : -1); 5074 if (target > 0) { 5075 if (needed == null) { 5076 needed = new NeededUriGrants(targetPkg, target, mode); 5077 } 5078 needed.add(data); 5079 } 5080 } 5081 if (clip != null) { 5082 for (int i=0; i<clip.getItemCount(); i++) { 5083 Uri uri = clip.getItemAt(i).getUri(); 5084 if (uri != null) { 5085 int target = -1; 5086 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5087 mode, needed != null ? needed.targetUid : -1); 5088 if (target > 0) { 5089 if (needed == null) { 5090 needed = new NeededUriGrants(targetPkg, target, mode); 5091 } 5092 needed.add(uri); 5093 } 5094 } else { 5095 Intent clipIntent = clip.getItemAt(i).getIntent(); 5096 if (clipIntent != null) { 5097 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5098 callingUid, targetPkg, clipIntent, mode, needed); 5099 if (newNeeded != null) { 5100 needed = newNeeded; 5101 } 5102 } 5103 } 5104 } 5105 } 5106 5107 return needed; 5108 } 5109 5110 /** 5111 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5112 */ 5113 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5114 UriPermissionOwner owner) { 5115 if (needed != null) { 5116 for (int i=0; i<needed.size(); i++) { 5117 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5118 needed.get(i), needed.flags, owner); 5119 } 5120 } 5121 } 5122 5123 void grantUriPermissionFromIntentLocked(int callingUid, 5124 String targetPkg, Intent intent, UriPermissionOwner owner) { 5125 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5126 intent, intent != null ? intent.getFlags() : 0, null); 5127 if (needed == null) { 5128 return; 5129 } 5130 5131 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5132 } 5133 5134 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5135 Uri uri, int modeFlags) { 5136 enforceNotIsolatedCaller("grantUriPermission"); 5137 synchronized(this) { 5138 final ProcessRecord r = getRecordForAppLocked(caller); 5139 if (r == null) { 5140 throw new SecurityException("Unable to find app for caller " 5141 + caller 5142 + " when granting permission to uri " + uri); 5143 } 5144 if (targetPkg == null) { 5145 throw new IllegalArgumentException("null target"); 5146 } 5147 if (uri == null) { 5148 throw new IllegalArgumentException("null uri"); 5149 } 5150 5151 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5152 null); 5153 } 5154 } 5155 5156 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5157 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5158 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5159 HashMap<Uri, UriPermission> perms 5160 = mGrantedUriPermissions.get(perm.uid); 5161 if (perms != null) { 5162 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5163 "Removing " + perm.uid + " permission to " + perm.uri); 5164 perms.remove(perm.uri); 5165 if (perms.size() == 0) { 5166 mGrantedUriPermissions.remove(perm.uid); 5167 } 5168 } 5169 } 5170 } 5171 5172 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5173 int modeFlags) { 5174 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5175 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5176 if (modeFlags == 0) { 5177 return; 5178 } 5179 5180 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5181 "Revoking all granted permissions to " + uri); 5182 5183 final IPackageManager pm = AppGlobals.getPackageManager(); 5184 5185 final String authority = uri.getAuthority(); 5186 ProviderInfo pi = null; 5187 int userId = UserHandle.getUserId(callingUid); 5188 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5189 if (cpr != null) { 5190 pi = cpr.info; 5191 } else { 5192 try { 5193 pi = pm.resolveContentProvider(authority, 5194 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5195 } catch (RemoteException ex) { 5196 } 5197 } 5198 if (pi == null) { 5199 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5200 return; 5201 } 5202 5203 // Does the caller have this permission on the URI? 5204 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5205 // Right now, if you are not the original owner of the permission, 5206 // you are not allowed to revoke it. 5207 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5208 throw new SecurityException("Uid " + callingUid 5209 + " does not have permission to uri " + uri); 5210 //} 5211 } 5212 5213 // Go through all of the permissions and remove any that match. 5214 final List<String> SEGMENTS = uri.getPathSegments(); 5215 if (SEGMENTS != null) { 5216 final int NS = SEGMENTS.size(); 5217 int N = mGrantedUriPermissions.size(); 5218 for (int i=0; i<N; i++) { 5219 HashMap<Uri, UriPermission> perms 5220 = mGrantedUriPermissions.valueAt(i); 5221 Iterator<UriPermission> it = perms.values().iterator(); 5222 toploop: 5223 while (it.hasNext()) { 5224 UriPermission perm = it.next(); 5225 Uri targetUri = perm.uri; 5226 if (!authority.equals(targetUri.getAuthority())) { 5227 continue; 5228 } 5229 List<String> targetSegments = targetUri.getPathSegments(); 5230 if (targetSegments == null) { 5231 continue; 5232 } 5233 if (targetSegments.size() < NS) { 5234 continue; 5235 } 5236 for (int j=0; j<NS; j++) { 5237 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5238 continue toploop; 5239 } 5240 } 5241 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5242 "Revoking " + perm.uid + " permission to " + perm.uri); 5243 perm.clearModes(modeFlags); 5244 if (perm.modeFlags == 0) { 5245 it.remove(); 5246 } 5247 } 5248 if (perms.size() == 0) { 5249 mGrantedUriPermissions.remove( 5250 mGrantedUriPermissions.keyAt(i)); 5251 N--; 5252 i--; 5253 } 5254 } 5255 } 5256 } 5257 5258 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5259 int modeFlags) { 5260 enforceNotIsolatedCaller("revokeUriPermission"); 5261 synchronized(this) { 5262 final ProcessRecord r = getRecordForAppLocked(caller); 5263 if (r == null) { 5264 throw new SecurityException("Unable to find app for caller " 5265 + caller 5266 + " when revoking permission to uri " + uri); 5267 } 5268 if (uri == null) { 5269 Slog.w(TAG, "revokeUriPermission: null uri"); 5270 return; 5271 } 5272 5273 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5274 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5275 if (modeFlags == 0) { 5276 return; 5277 } 5278 5279 final IPackageManager pm = AppGlobals.getPackageManager(); 5280 5281 final String authority = uri.getAuthority(); 5282 ProviderInfo pi = null; 5283 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5284 if (cpr != null) { 5285 pi = cpr.info; 5286 } else { 5287 try { 5288 pi = pm.resolveContentProvider(authority, 5289 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5290 } catch (RemoteException ex) { 5291 } 5292 } 5293 if (pi == null) { 5294 Slog.w(TAG, "No content provider found for permission revoke: " 5295 + uri.toSafeString()); 5296 return; 5297 } 5298 5299 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5300 } 5301 } 5302 5303 @Override 5304 public IBinder newUriPermissionOwner(String name) { 5305 enforceNotIsolatedCaller("newUriPermissionOwner"); 5306 synchronized(this) { 5307 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5308 return owner.getExternalTokenLocked(); 5309 } 5310 } 5311 5312 @Override 5313 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5314 Uri uri, int modeFlags) { 5315 synchronized(this) { 5316 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5317 if (owner == null) { 5318 throw new IllegalArgumentException("Unknown owner: " + token); 5319 } 5320 if (fromUid != Binder.getCallingUid()) { 5321 if (Binder.getCallingUid() != Process.myUid()) { 5322 // Only system code can grant URI permissions on behalf 5323 // of other users. 5324 throw new SecurityException("nice try"); 5325 } 5326 } 5327 if (targetPkg == null) { 5328 throw new IllegalArgumentException("null target"); 5329 } 5330 if (uri == null) { 5331 throw new IllegalArgumentException("null uri"); 5332 } 5333 5334 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5335 } 5336 } 5337 5338 @Override 5339 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5340 synchronized(this) { 5341 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5342 if (owner == null) { 5343 throw new IllegalArgumentException("Unknown owner: " + token); 5344 } 5345 5346 if (uri == null) { 5347 owner.removeUriPermissionsLocked(mode); 5348 } else { 5349 owner.removeUriPermissionLocked(uri, mode); 5350 } 5351 } 5352 } 5353 5354 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5355 synchronized (this) { 5356 ProcessRecord app = 5357 who != null ? getRecordForAppLocked(who) : null; 5358 if (app == null) return; 5359 5360 Message msg = Message.obtain(); 5361 msg.what = WAIT_FOR_DEBUGGER_MSG; 5362 msg.obj = app; 5363 msg.arg1 = waiting ? 1 : 0; 5364 mHandler.sendMessage(msg); 5365 } 5366 } 5367 5368 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5369 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5370 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5371 outInfo.availMem = Process.getFreeMemory(); 5372 outInfo.totalMem = Process.getTotalMemory(); 5373 outInfo.threshold = homeAppMem; 5374 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5375 outInfo.hiddenAppThreshold = hiddenAppMem; 5376 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5377 ProcessList.SERVICE_ADJ); 5378 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5379 ProcessList.VISIBLE_APP_ADJ); 5380 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5381 ProcessList.FOREGROUND_APP_ADJ); 5382 } 5383 5384 // ========================================================= 5385 // TASK MANAGEMENT 5386 // ========================================================= 5387 5388 public List getTasks(int maxNum, int flags, 5389 IThumbnailReceiver receiver) { 5390 ArrayList list = new ArrayList(); 5391 5392 PendingThumbnailsRecord pending = null; 5393 IApplicationThread topThumbnail = null; 5394 ActivityRecord topRecord = null; 5395 5396 synchronized(this) { 5397 if (localLOGV) Slog.v( 5398 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5399 + ", receiver=" + receiver); 5400 5401 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5402 != PackageManager.PERMISSION_GRANTED) { 5403 if (receiver != null) { 5404 // If the caller wants to wait for pending thumbnails, 5405 // it ain't gonna get them. 5406 try { 5407 receiver.finished(); 5408 } catch (RemoteException ex) { 5409 } 5410 } 5411 String msg = "Permission Denial: getTasks() from pid=" 5412 + Binder.getCallingPid() 5413 + ", uid=" + Binder.getCallingUid() 5414 + " requires " + android.Manifest.permission.GET_TASKS; 5415 Slog.w(TAG, msg); 5416 throw new SecurityException(msg); 5417 } 5418 5419 int pos = mMainStack.mHistory.size()-1; 5420 ActivityRecord next = 5421 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5422 ActivityRecord top = null; 5423 TaskRecord curTask = null; 5424 int numActivities = 0; 5425 int numRunning = 0; 5426 while (pos >= 0 && maxNum > 0) { 5427 final ActivityRecord r = next; 5428 pos--; 5429 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5430 5431 // Initialize state for next task if needed. 5432 if (top == null || 5433 (top.state == ActivityState.INITIALIZING 5434 && top.task == r.task)) { 5435 top = r; 5436 curTask = r.task; 5437 numActivities = numRunning = 0; 5438 } 5439 5440 // Add 'r' into the current task. 5441 numActivities++; 5442 if (r.app != null && r.app.thread != null) { 5443 numRunning++; 5444 } 5445 5446 if (localLOGV) Slog.v( 5447 TAG, r.intent.getComponent().flattenToShortString() 5448 + ": task=" + r.task); 5449 5450 // If the next one is a different task, generate a new 5451 // TaskInfo entry for what we have. 5452 if (next == null || next.task != curTask) { 5453 ActivityManager.RunningTaskInfo ci 5454 = new ActivityManager.RunningTaskInfo(); 5455 ci.id = curTask.taskId; 5456 ci.baseActivity = r.intent.getComponent(); 5457 ci.topActivity = top.intent.getComponent(); 5458 if (top.thumbHolder != null) { 5459 ci.description = top.thumbHolder.lastDescription; 5460 } 5461 ci.numActivities = numActivities; 5462 ci.numRunning = numRunning; 5463 //System.out.println( 5464 // "#" + maxNum + ": " + " descr=" + ci.description); 5465 if (ci.thumbnail == null && receiver != null) { 5466 if (localLOGV) Slog.v( 5467 TAG, "State=" + top.state + "Idle=" + top.idle 5468 + " app=" + top.app 5469 + " thr=" + (top.app != null ? top.app.thread : null)); 5470 if (top.state == ActivityState.RESUMED 5471 || top.state == ActivityState.PAUSING) { 5472 if (top.idle && top.app != null 5473 && top.app.thread != null) { 5474 topRecord = top; 5475 topThumbnail = top.app.thread; 5476 } else { 5477 top.thumbnailNeeded = true; 5478 } 5479 } 5480 if (pending == null) { 5481 pending = new PendingThumbnailsRecord(receiver); 5482 } 5483 pending.pendingRecords.add(top); 5484 } 5485 list.add(ci); 5486 maxNum--; 5487 top = null; 5488 } 5489 } 5490 5491 if (pending != null) { 5492 mPendingThumbnails.add(pending); 5493 } 5494 } 5495 5496 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5497 5498 if (topThumbnail != null) { 5499 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5500 try { 5501 topThumbnail.requestThumbnail(topRecord.appToken); 5502 } catch (Exception e) { 5503 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5504 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5505 } 5506 } 5507 5508 if (pending == null && receiver != null) { 5509 // In this case all thumbnails were available and the client 5510 // is being asked to be told when the remaining ones come in... 5511 // which is unusually, since the top-most currently running 5512 // activity should never have a canned thumbnail! Oh well. 5513 try { 5514 receiver.finished(); 5515 } catch (RemoteException ex) { 5516 } 5517 } 5518 5519 return list; 5520 } 5521 5522 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5523 int flags, int userId) { 5524 final int callingUid = Binder.getCallingUid(); 5525 if (userId != UserHandle.getCallingUserId()) { 5526 // Check if the caller is holding permissions for cross-user requests. 5527 if (checkComponentPermission( 5528 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5529 Binder.getCallingPid(), callingUid, -1, true) 5530 != PackageManager.PERMISSION_GRANTED) { 5531 String msg = "Permission Denial: " 5532 + "Request to get recent tasks for user " + userId 5533 + " but is calling from user " + UserHandle.getUserId(callingUid) 5534 + "; this requires " 5535 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5536 Slog.w(TAG, msg); 5537 throw new SecurityException(msg); 5538 } else { 5539 if (userId == UserHandle.USER_CURRENT) { 5540 userId = mCurrentUserId; 5541 } 5542 } 5543 } 5544 5545 synchronized (this) { 5546 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5547 "getRecentTasks()"); 5548 final boolean detailed = checkCallingPermission( 5549 android.Manifest.permission.GET_DETAILED_TASKS) 5550 == PackageManager.PERMISSION_GRANTED; 5551 5552 IPackageManager pm = AppGlobals.getPackageManager(); 5553 5554 final int N = mRecentTasks.size(); 5555 ArrayList<ActivityManager.RecentTaskInfo> res 5556 = new ArrayList<ActivityManager.RecentTaskInfo>( 5557 maxNum < N ? maxNum : N); 5558 for (int i=0; i<N && maxNum > 0; i++) { 5559 TaskRecord tr = mRecentTasks.get(i); 5560 // Only add calling user's recent tasks 5561 if (tr.userId != userId) continue; 5562 // Return the entry if desired by the caller. We always return 5563 // the first entry, because callers always expect this to be the 5564 // foreground app. We may filter others if the caller has 5565 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5566 // we should exclude the entry. 5567 5568 if (i == 0 5569 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5570 || (tr.intent == null) 5571 || ((tr.intent.getFlags() 5572 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5573 ActivityManager.RecentTaskInfo rti 5574 = new ActivityManager.RecentTaskInfo(); 5575 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5576 rti.persistentId = tr.taskId; 5577 rti.baseIntent = new Intent( 5578 tr.intent != null ? tr.intent : tr.affinityIntent); 5579 if (!detailed) { 5580 rti.baseIntent.replaceExtras((Bundle)null); 5581 } 5582 rti.origActivity = tr.origActivity; 5583 rti.description = tr.lastDescription; 5584 5585 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5586 // Check whether this activity is currently available. 5587 try { 5588 if (rti.origActivity != null) { 5589 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5590 == null) { 5591 continue; 5592 } 5593 } else if (rti.baseIntent != null) { 5594 if (pm.queryIntentActivities(rti.baseIntent, 5595 null, 0, userId) == null) { 5596 continue; 5597 } 5598 } 5599 } catch (RemoteException e) { 5600 // Will never happen. 5601 } 5602 } 5603 5604 res.add(rti); 5605 maxNum--; 5606 } 5607 } 5608 return res; 5609 } 5610 } 5611 5612 private TaskRecord taskForIdLocked(int id) { 5613 final int N = mRecentTasks.size(); 5614 for (int i=0; i<N; i++) { 5615 TaskRecord tr = mRecentTasks.get(i); 5616 if (tr.taskId == id) { 5617 return tr; 5618 } 5619 } 5620 return null; 5621 } 5622 5623 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5624 synchronized (this) { 5625 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5626 "getTaskThumbnails()"); 5627 TaskRecord tr = taskForIdLocked(id); 5628 if (tr != null) { 5629 return mMainStack.getTaskThumbnailsLocked(tr); 5630 } 5631 } 5632 return null; 5633 } 5634 5635 public boolean removeSubTask(int taskId, int subTaskIndex) { 5636 synchronized (this) { 5637 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5638 "removeSubTask()"); 5639 long ident = Binder.clearCallingIdentity(); 5640 try { 5641 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5642 true) != null; 5643 } finally { 5644 Binder.restoreCallingIdentity(ident); 5645 } 5646 } 5647 } 5648 5649 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5650 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5651 Intent baseIntent = new Intent( 5652 tr.intent != null ? tr.intent : tr.affinityIntent); 5653 ComponentName component = baseIntent.getComponent(); 5654 if (component == null) { 5655 Slog.w(TAG, "Now component for base intent of task: " + tr); 5656 return; 5657 } 5658 5659 // Find any running services associated with this app. 5660 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5661 5662 if (killProcesses) { 5663 // Find any running processes associated with this app. 5664 final String pkg = component.getPackageName(); 5665 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5666 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5667 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5668 for (int i=0; i<uids.size(); i++) { 5669 ProcessRecord proc = uids.valueAt(i); 5670 if (proc.userId != tr.userId) { 5671 continue; 5672 } 5673 if (!proc.pkgList.contains(pkg)) { 5674 continue; 5675 } 5676 procs.add(proc); 5677 } 5678 } 5679 5680 // Kill the running processes. 5681 for (int i=0; i<procs.size(); i++) { 5682 ProcessRecord pr = procs.get(i); 5683 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5684 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5685 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5686 pr.processName, pr.setAdj, "remove task"); 5687 pr.killedBackground = true; 5688 Process.killProcessQuiet(pr.pid); 5689 } else { 5690 pr.waitingToKill = "remove task"; 5691 } 5692 } 5693 } 5694 } 5695 5696 public boolean removeTask(int taskId, int flags) { 5697 synchronized (this) { 5698 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5699 "removeTask()"); 5700 long ident = Binder.clearCallingIdentity(); 5701 try { 5702 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5703 false); 5704 if (r != null) { 5705 mRecentTasks.remove(r.task); 5706 cleanUpRemovedTaskLocked(r.task, flags); 5707 return true; 5708 } else { 5709 TaskRecord tr = null; 5710 int i=0; 5711 while (i < mRecentTasks.size()) { 5712 TaskRecord t = mRecentTasks.get(i); 5713 if (t.taskId == taskId) { 5714 tr = t; 5715 break; 5716 } 5717 i++; 5718 } 5719 if (tr != null) { 5720 if (tr.numActivities <= 0) { 5721 // Caller is just removing a recent task that is 5722 // not actively running. That is easy! 5723 mRecentTasks.remove(i); 5724 cleanUpRemovedTaskLocked(tr, flags); 5725 return true; 5726 } else { 5727 Slog.w(TAG, "removeTask: task " + taskId 5728 + " does not have activities to remove, " 5729 + " but numActivities=" + tr.numActivities 5730 + ": " + tr); 5731 } 5732 } 5733 } 5734 } finally { 5735 Binder.restoreCallingIdentity(ident); 5736 } 5737 } 5738 return false; 5739 } 5740 5741 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5742 int j; 5743 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5744 TaskRecord jt = startTask; 5745 5746 // First look backwards 5747 for (j=startIndex-1; j>=0; j--) { 5748 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5749 if (r.task != jt) { 5750 jt = r.task; 5751 if (affinity.equals(jt.affinity)) { 5752 return j; 5753 } 5754 } 5755 } 5756 5757 // Now look forwards 5758 final int N = mMainStack.mHistory.size(); 5759 jt = startTask; 5760 for (j=startIndex+1; j<N; j++) { 5761 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5762 if (r.task != jt) { 5763 if (affinity.equals(jt.affinity)) { 5764 return j; 5765 } 5766 jt = r.task; 5767 } 5768 } 5769 5770 // Might it be at the top? 5771 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5772 return N-1; 5773 } 5774 5775 return -1; 5776 } 5777 5778 /** 5779 * TODO: Add mController hook 5780 */ 5781 public void moveTaskToFront(int task, int flags, Bundle options) { 5782 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5783 "moveTaskToFront()"); 5784 5785 synchronized(this) { 5786 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5787 Binder.getCallingUid(), "Task to front")) { 5788 ActivityOptions.abort(options); 5789 return; 5790 } 5791 final long origId = Binder.clearCallingIdentity(); 5792 try { 5793 TaskRecord tr = taskForIdLocked(task); 5794 if (tr != null) { 5795 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5796 mMainStack.mUserLeaving = true; 5797 } 5798 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5799 // Caller wants the home activity moved with it. To accomplish this, 5800 // we'll just move the home task to the top first. 5801 mMainStack.moveHomeToFrontLocked(); 5802 } 5803 mMainStack.moveTaskToFrontLocked(tr, null, options); 5804 return; 5805 } 5806 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5807 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5808 if (hr.task.taskId == task) { 5809 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5810 mMainStack.mUserLeaving = true; 5811 } 5812 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5813 // Caller wants the home activity moved with it. To accomplish this, 5814 // we'll just move the home task to the top first. 5815 mMainStack.moveHomeToFrontLocked(); 5816 } 5817 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5818 return; 5819 } 5820 } 5821 } finally { 5822 Binder.restoreCallingIdentity(origId); 5823 } 5824 ActivityOptions.abort(options); 5825 } 5826 } 5827 5828 public void moveTaskToBack(int task) { 5829 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5830 "moveTaskToBack()"); 5831 5832 synchronized(this) { 5833 if (mMainStack.mResumedActivity != null 5834 && mMainStack.mResumedActivity.task.taskId == task) { 5835 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5836 Binder.getCallingUid(), "Task to back")) { 5837 return; 5838 } 5839 } 5840 final long origId = Binder.clearCallingIdentity(); 5841 mMainStack.moveTaskToBackLocked(task, null); 5842 Binder.restoreCallingIdentity(origId); 5843 } 5844 } 5845 5846 /** 5847 * Moves an activity, and all of the other activities within the same task, to the bottom 5848 * of the history stack. The activity's order within the task is unchanged. 5849 * 5850 * @param token A reference to the activity we wish to move 5851 * @param nonRoot If false then this only works if the activity is the root 5852 * of a task; if true it will work for any activity in a task. 5853 * @return Returns true if the move completed, false if not. 5854 */ 5855 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5856 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5857 synchronized(this) { 5858 final long origId = Binder.clearCallingIdentity(); 5859 int taskId = getTaskForActivityLocked(token, !nonRoot); 5860 if (taskId >= 0) { 5861 return mMainStack.moveTaskToBackLocked(taskId, null); 5862 } 5863 Binder.restoreCallingIdentity(origId); 5864 } 5865 return false; 5866 } 5867 5868 public void moveTaskBackwards(int task) { 5869 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5870 "moveTaskBackwards()"); 5871 5872 synchronized(this) { 5873 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5874 Binder.getCallingUid(), "Task backwards")) { 5875 return; 5876 } 5877 final long origId = Binder.clearCallingIdentity(); 5878 moveTaskBackwardsLocked(task); 5879 Binder.restoreCallingIdentity(origId); 5880 } 5881 } 5882 5883 private final void moveTaskBackwardsLocked(int task) { 5884 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5885 } 5886 5887 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5888 synchronized(this) { 5889 return getTaskForActivityLocked(token, onlyRoot); 5890 } 5891 } 5892 5893 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5894 final int N = mMainStack.mHistory.size(); 5895 TaskRecord lastTask = null; 5896 for (int i=0; i<N; i++) { 5897 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5898 if (r.appToken == token) { 5899 if (!onlyRoot || lastTask != r.task) { 5900 return r.task.taskId; 5901 } 5902 return -1; 5903 } 5904 lastTask = r.task; 5905 } 5906 5907 return -1; 5908 } 5909 5910 // ========================================================= 5911 // THUMBNAILS 5912 // ========================================================= 5913 5914 public void reportThumbnail(IBinder token, 5915 Bitmap thumbnail, CharSequence description) { 5916 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5917 final long origId = Binder.clearCallingIdentity(); 5918 sendPendingThumbnail(null, token, thumbnail, description, true); 5919 Binder.restoreCallingIdentity(origId); 5920 } 5921 5922 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5923 Bitmap thumbnail, CharSequence description, boolean always) { 5924 TaskRecord task = null; 5925 ArrayList receivers = null; 5926 5927 //System.out.println("Send pending thumbnail: " + r); 5928 5929 synchronized(this) { 5930 if (r == null) { 5931 r = mMainStack.isInStackLocked(token); 5932 if (r == null) { 5933 return; 5934 } 5935 } 5936 if (thumbnail == null && r.thumbHolder != null) { 5937 thumbnail = r.thumbHolder.lastThumbnail; 5938 description = r.thumbHolder.lastDescription; 5939 } 5940 if (thumbnail == null && !always) { 5941 // If there is no thumbnail, and this entry is not actually 5942 // going away, then abort for now and pick up the next 5943 // thumbnail we get. 5944 return; 5945 } 5946 task = r.task; 5947 5948 int N = mPendingThumbnails.size(); 5949 int i=0; 5950 while (i<N) { 5951 PendingThumbnailsRecord pr = 5952 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5953 //System.out.println("Looking in " + pr.pendingRecords); 5954 if (pr.pendingRecords.remove(r)) { 5955 if (receivers == null) { 5956 receivers = new ArrayList(); 5957 } 5958 receivers.add(pr); 5959 if (pr.pendingRecords.size() == 0) { 5960 pr.finished = true; 5961 mPendingThumbnails.remove(i); 5962 N--; 5963 continue; 5964 } 5965 } 5966 i++; 5967 } 5968 } 5969 5970 if (receivers != null) { 5971 final int N = receivers.size(); 5972 for (int i=0; i<N; i++) { 5973 try { 5974 PendingThumbnailsRecord pr = 5975 (PendingThumbnailsRecord)receivers.get(i); 5976 pr.receiver.newThumbnail( 5977 task != null ? task.taskId : -1, thumbnail, description); 5978 if (pr.finished) { 5979 pr.receiver.finished(); 5980 } 5981 } catch (Exception e) { 5982 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5983 } 5984 } 5985 } 5986 } 5987 5988 // ========================================================= 5989 // CONTENT PROVIDERS 5990 // ========================================================= 5991 5992 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5993 List<ProviderInfo> providers = null; 5994 try { 5995 providers = AppGlobals.getPackageManager(). 5996 queryContentProviders(app.processName, app.uid, 5997 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5998 } catch (RemoteException ex) { 5999 } 6000 if (DEBUG_MU) 6001 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6002 int userId = app.userId; 6003 if (providers != null) { 6004 int N = providers.size(); 6005 for (int i=0; i<N; i++) { 6006 ProviderInfo cpi = 6007 (ProviderInfo)providers.get(i); 6008 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6009 cpi.name, cpi.flags); 6010 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6011 // This is a singleton provider, but a user besides the 6012 // default user is asking to initialize a process it runs 6013 // in... well, no, it doesn't actually run in this process, 6014 // it runs in the process of the default user. Get rid of it. 6015 providers.remove(i); 6016 N--; 6017 continue; 6018 } 6019 6020 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6021 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6022 if (cpr == null) { 6023 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6024 mProviderMap.putProviderByClass(comp, cpr); 6025 } 6026 if (DEBUG_MU) 6027 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6028 app.pubProviders.put(cpi.name, cpr); 6029 app.addPackage(cpi.applicationInfo.packageName); 6030 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6031 } 6032 } 6033 return providers; 6034 } 6035 6036 /** 6037 * Check if {@link ProcessRecord} has a possible chance at accessing the 6038 * given {@link ProviderInfo}. Final permission checking is always done 6039 * in {@link ContentProvider}. 6040 */ 6041 private final String checkContentProviderPermissionLocked( 6042 ProviderInfo cpi, ProcessRecord r) { 6043 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6044 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6045 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6046 cpi.applicationInfo.uid, cpi.exported) 6047 == PackageManager.PERMISSION_GRANTED) { 6048 return null; 6049 } 6050 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6051 cpi.applicationInfo.uid, cpi.exported) 6052 == PackageManager.PERMISSION_GRANTED) { 6053 return null; 6054 } 6055 6056 PathPermission[] pps = cpi.pathPermissions; 6057 if (pps != null) { 6058 int i = pps.length; 6059 while (i > 0) { 6060 i--; 6061 PathPermission pp = pps[i]; 6062 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6063 cpi.applicationInfo.uid, cpi.exported) 6064 == PackageManager.PERMISSION_GRANTED) { 6065 return null; 6066 } 6067 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6068 cpi.applicationInfo.uid, cpi.exported) 6069 == PackageManager.PERMISSION_GRANTED) { 6070 return null; 6071 } 6072 } 6073 } 6074 6075 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6076 if (perms != null) { 6077 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6078 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6079 return null; 6080 } 6081 } 6082 } 6083 6084 String msg; 6085 if (!cpi.exported) { 6086 msg = "Permission Denial: opening provider " + cpi.name 6087 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6088 + ", uid=" + callingUid + ") that is not exported from uid " 6089 + cpi.applicationInfo.uid; 6090 } else { 6091 msg = "Permission Denial: opening provider " + cpi.name 6092 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6093 + ", uid=" + callingUid + ") requires " 6094 + cpi.readPermission + " or " + cpi.writePermission; 6095 } 6096 Slog.w(TAG, msg); 6097 return msg; 6098 } 6099 6100 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6101 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6102 if (r != null) { 6103 for (int i=0; i<r.conProviders.size(); i++) { 6104 ContentProviderConnection conn = r.conProviders.get(i); 6105 if (conn.provider == cpr) { 6106 if (DEBUG_PROVIDER) Slog.v(TAG, 6107 "Adding provider requested by " 6108 + r.processName + " from process " 6109 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6110 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6111 if (stable) { 6112 conn.stableCount++; 6113 conn.numStableIncs++; 6114 } else { 6115 conn.unstableCount++; 6116 conn.numUnstableIncs++; 6117 } 6118 return conn; 6119 } 6120 } 6121 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6122 if (stable) { 6123 conn.stableCount = 1; 6124 conn.numStableIncs = 1; 6125 } else { 6126 conn.unstableCount = 1; 6127 conn.numUnstableIncs = 1; 6128 } 6129 cpr.connections.add(conn); 6130 r.conProviders.add(conn); 6131 return conn; 6132 } 6133 cpr.addExternalProcessHandleLocked(externalProcessToken); 6134 return null; 6135 } 6136 6137 boolean decProviderCountLocked(ContentProviderConnection conn, 6138 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6139 if (conn != null) { 6140 cpr = conn.provider; 6141 if (DEBUG_PROVIDER) Slog.v(TAG, 6142 "Removing provider requested by " 6143 + conn.client.processName + " from process " 6144 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6145 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6146 if (stable) { 6147 conn.stableCount--; 6148 } else { 6149 conn.unstableCount--; 6150 } 6151 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6152 cpr.connections.remove(conn); 6153 conn.client.conProviders.remove(conn); 6154 return true; 6155 } 6156 return false; 6157 } 6158 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6159 return false; 6160 } 6161 6162 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6163 String name, IBinder token, boolean stable) { 6164 ContentProviderRecord cpr; 6165 ContentProviderConnection conn = null; 6166 ProviderInfo cpi = null; 6167 6168 synchronized(this) { 6169 ProcessRecord r = null; 6170 if (caller != null) { 6171 r = getRecordForAppLocked(caller); 6172 if (r == null) { 6173 throw new SecurityException( 6174 "Unable to find app for caller " + caller 6175 + " (pid=" + Binder.getCallingPid() 6176 + ") when getting content provider " + name); 6177 } 6178 } 6179 6180 // First check if this content provider has been published... 6181 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6182 cpr = mProviderMap.getProviderByName(name, userId); 6183 boolean providerRunning = cpr != null; 6184 if (providerRunning) { 6185 cpi = cpr.info; 6186 String msg; 6187 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6188 throw new SecurityException(msg); 6189 } 6190 6191 if (r != null && cpr.canRunHere(r)) { 6192 // This provider has been published or is in the process 6193 // of being published... but it is also allowed to run 6194 // in the caller's process, so don't make a connection 6195 // and just let the caller instantiate its own instance. 6196 ContentProviderHolder holder = cpr.newHolder(null); 6197 // don't give caller the provider object, it needs 6198 // to make its own. 6199 holder.provider = null; 6200 return holder; 6201 } 6202 6203 final long origId = Binder.clearCallingIdentity(); 6204 6205 // In this case the provider instance already exists, so we can 6206 // return it right away. 6207 conn = incProviderCountLocked(r, cpr, token, stable); 6208 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6209 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6210 // If this is a perceptible app accessing the provider, 6211 // make sure to count it as being accessed and thus 6212 // back up on the LRU list. This is good because 6213 // content providers are often expensive to start. 6214 updateLruProcessLocked(cpr.proc, false, true); 6215 } 6216 } 6217 6218 if (cpr.proc != null) { 6219 if (false) { 6220 if (cpr.name.flattenToShortString().equals( 6221 "com.android.providers.calendar/.CalendarProvider2")) { 6222 Slog.v(TAG, "****************** KILLING " 6223 + cpr.name.flattenToShortString()); 6224 Process.killProcess(cpr.proc.pid); 6225 } 6226 } 6227 boolean success = updateOomAdjLocked(cpr.proc); 6228 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6229 // NOTE: there is still a race here where a signal could be 6230 // pending on the process even though we managed to update its 6231 // adj level. Not sure what to do about this, but at least 6232 // the race is now smaller. 6233 if (!success) { 6234 // Uh oh... it looks like the provider's process 6235 // has been killed on us. We need to wait for a new 6236 // process to be started, and make sure its death 6237 // doesn't kill our process. 6238 Slog.i(TAG, 6239 "Existing provider " + cpr.name.flattenToShortString() 6240 + " is crashing; detaching " + r); 6241 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6242 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6243 if (!lastRef) { 6244 // This wasn't the last ref our process had on 6245 // the provider... we have now been killed, bail. 6246 return null; 6247 } 6248 providerRunning = false; 6249 conn = null; 6250 } 6251 } 6252 6253 Binder.restoreCallingIdentity(origId); 6254 } 6255 6256 boolean singleton; 6257 if (!providerRunning) { 6258 try { 6259 cpi = AppGlobals.getPackageManager(). 6260 resolveContentProvider(name, 6261 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6262 } catch (RemoteException ex) { 6263 } 6264 if (cpi == null) { 6265 return null; 6266 } 6267 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6268 cpi.name, cpi.flags); 6269 if (singleton) { 6270 userId = 0; 6271 } 6272 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6273 6274 String msg; 6275 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6276 throw new SecurityException(msg); 6277 } 6278 6279 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6280 && !cpi.processName.equals("system")) { 6281 // If this content provider does not run in the system 6282 // process, and the system is not yet ready to run other 6283 // processes, then fail fast instead of hanging. 6284 throw new IllegalArgumentException( 6285 "Attempt to launch content provider before system ready"); 6286 } 6287 6288 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6289 cpr = mProviderMap.getProviderByClass(comp, userId); 6290 final boolean firstClass = cpr == null; 6291 if (firstClass) { 6292 try { 6293 ApplicationInfo ai = 6294 AppGlobals.getPackageManager(). 6295 getApplicationInfo( 6296 cpi.applicationInfo.packageName, 6297 STOCK_PM_FLAGS, userId); 6298 if (ai == null) { 6299 Slog.w(TAG, "No package info for content provider " 6300 + cpi.name); 6301 return null; 6302 } 6303 ai = getAppInfoForUser(ai, userId); 6304 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6305 } catch (RemoteException ex) { 6306 // pm is in same process, this will never happen. 6307 } 6308 } 6309 6310 if (r != null && cpr.canRunHere(r)) { 6311 // If this is a multiprocess provider, then just return its 6312 // info and allow the caller to instantiate it. Only do 6313 // this if the provider is the same user as the caller's 6314 // process, or can run as root (so can be in any process). 6315 return cpr.newHolder(null); 6316 } 6317 6318 if (DEBUG_PROVIDER) { 6319 RuntimeException e = new RuntimeException("here"); 6320 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6321 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6322 } 6323 6324 // This is single process, and our app is now connecting to it. 6325 // See if we are already in the process of launching this 6326 // provider. 6327 final int N = mLaunchingProviders.size(); 6328 int i; 6329 for (i=0; i<N; i++) { 6330 if (mLaunchingProviders.get(i) == cpr) { 6331 break; 6332 } 6333 } 6334 6335 // If the provider is not already being launched, then get it 6336 // started. 6337 if (i >= N) { 6338 final long origId = Binder.clearCallingIdentity(); 6339 6340 try { 6341 // Content provider is now in use, its package can't be stopped. 6342 try { 6343 AppGlobals.getPackageManager().setPackageStoppedState( 6344 cpr.appInfo.packageName, false, userId); 6345 } catch (RemoteException e) { 6346 } catch (IllegalArgumentException e) { 6347 Slog.w(TAG, "Failed trying to unstop package " 6348 + cpr.appInfo.packageName + ": " + e); 6349 } 6350 6351 ProcessRecord proc = startProcessLocked(cpi.processName, 6352 cpr.appInfo, false, 0, "content provider", 6353 new ComponentName(cpi.applicationInfo.packageName, 6354 cpi.name), false, false); 6355 if (proc == null) { 6356 Slog.w(TAG, "Unable to launch app " 6357 + cpi.applicationInfo.packageName + "/" 6358 + cpi.applicationInfo.uid + " for provider " 6359 + name + ": process is bad"); 6360 return null; 6361 } 6362 cpr.launchingApp = proc; 6363 mLaunchingProviders.add(cpr); 6364 } finally { 6365 Binder.restoreCallingIdentity(origId); 6366 } 6367 } 6368 6369 // Make sure the provider is published (the same provider class 6370 // may be published under multiple names). 6371 if (firstClass) { 6372 mProviderMap.putProviderByClass(comp, cpr); 6373 } 6374 6375 mProviderMap.putProviderByName(name, cpr); 6376 conn = incProviderCountLocked(r, cpr, token, stable); 6377 if (conn != null) { 6378 conn.waiting = true; 6379 } 6380 } 6381 } 6382 6383 // Wait for the provider to be published... 6384 synchronized (cpr) { 6385 while (cpr.provider == null) { 6386 if (cpr.launchingApp == null) { 6387 Slog.w(TAG, "Unable to launch app " 6388 + cpi.applicationInfo.packageName + "/" 6389 + cpi.applicationInfo.uid + " for provider " 6390 + name + ": launching app became null"); 6391 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6392 cpi.applicationInfo.packageName, 6393 cpi.applicationInfo.uid, name); 6394 return null; 6395 } 6396 try { 6397 if (DEBUG_MU) { 6398 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6399 + cpr.launchingApp); 6400 } 6401 if (conn != null) { 6402 conn.waiting = true; 6403 } 6404 cpr.wait(); 6405 } catch (InterruptedException ex) { 6406 } finally { 6407 if (conn != null) { 6408 conn.waiting = false; 6409 } 6410 } 6411 } 6412 } 6413 return cpr != null ? cpr.newHolder(conn) : null; 6414 } 6415 6416 public final ContentProviderHolder getContentProvider( 6417 IApplicationThread caller, String name, boolean stable) { 6418 enforceNotIsolatedCaller("getContentProvider"); 6419 if (caller == null) { 6420 String msg = "null IApplicationThread when getting content provider " 6421 + name; 6422 Slog.w(TAG, msg); 6423 throw new SecurityException(msg); 6424 } 6425 6426 return getContentProviderImpl(caller, name, null, stable); 6427 } 6428 6429 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6430 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6431 "Do not have permission in call getContentProviderExternal()"); 6432 return getContentProviderExternalUnchecked(name, token); 6433 } 6434 6435 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6436 return getContentProviderImpl(null, name, token, true); 6437 } 6438 6439 /** 6440 * Drop a content provider from a ProcessRecord's bookkeeping 6441 * @param cpr 6442 */ 6443 public void removeContentProvider(IBinder connection, boolean stable) { 6444 enforceNotIsolatedCaller("removeContentProvider"); 6445 synchronized (this) { 6446 ContentProviderConnection conn; 6447 try { 6448 conn = (ContentProviderConnection)connection; 6449 } catch (ClassCastException e) { 6450 String msg ="removeContentProvider: " + connection 6451 + " not a ContentProviderConnection"; 6452 Slog.w(TAG, msg); 6453 throw new IllegalArgumentException(msg); 6454 } 6455 if (conn == null) { 6456 throw new NullPointerException("connection is null"); 6457 } 6458 if (decProviderCountLocked(conn, null, null, stable)) { 6459 updateOomAdjLocked(); 6460 } 6461 } 6462 } 6463 6464 public void removeContentProviderExternal(String name, IBinder token) { 6465 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6466 "Do not have permission in call removeContentProviderExternal()"); 6467 removeContentProviderExternalUnchecked(name, token); 6468 } 6469 6470 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6471 synchronized (this) { 6472 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6473 Binder.getOrigCallingUser()); 6474 if(cpr == null) { 6475 //remove from mProvidersByClass 6476 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6477 return; 6478 } 6479 6480 //update content provider record entry info 6481 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6482 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6483 Binder.getOrigCallingUser()); 6484 if (localCpr.hasExternalProcessHandles()) { 6485 if (localCpr.removeExternalProcessHandleLocked(token)) { 6486 updateOomAdjLocked(); 6487 } else { 6488 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6489 + " with no external reference for token: " 6490 + token + "."); 6491 } 6492 } else { 6493 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6494 + " with no external references."); 6495 } 6496 } 6497 } 6498 6499 public final void publishContentProviders(IApplicationThread caller, 6500 List<ContentProviderHolder> providers) { 6501 if (providers == null) { 6502 return; 6503 } 6504 6505 enforceNotIsolatedCaller("publishContentProviders"); 6506 synchronized (this) { 6507 final ProcessRecord r = getRecordForAppLocked(caller); 6508 if (DEBUG_MU) 6509 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6510 if (r == null) { 6511 throw new SecurityException( 6512 "Unable to find app for caller " + caller 6513 + " (pid=" + Binder.getCallingPid() 6514 + ") when publishing content providers"); 6515 } 6516 6517 final long origId = Binder.clearCallingIdentity(); 6518 6519 final int N = providers.size(); 6520 for (int i=0; i<N; i++) { 6521 ContentProviderHolder src = providers.get(i); 6522 if (src == null || src.info == null || src.provider == null) { 6523 continue; 6524 } 6525 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6526 if (DEBUG_MU) 6527 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6528 if (dst != null) { 6529 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6530 mProviderMap.putProviderByClass(comp, dst); 6531 String names[] = dst.info.authority.split(";"); 6532 for (int j = 0; j < names.length; j++) { 6533 mProviderMap.putProviderByName(names[j], dst); 6534 } 6535 6536 int NL = mLaunchingProviders.size(); 6537 int j; 6538 for (j=0; j<NL; j++) { 6539 if (mLaunchingProviders.get(j) == dst) { 6540 mLaunchingProviders.remove(j); 6541 j--; 6542 NL--; 6543 } 6544 } 6545 synchronized (dst) { 6546 dst.provider = src.provider; 6547 dst.proc = r; 6548 dst.notifyAll(); 6549 } 6550 updateOomAdjLocked(r); 6551 } 6552 } 6553 6554 Binder.restoreCallingIdentity(origId); 6555 } 6556 } 6557 6558 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6559 ContentProviderConnection conn; 6560 try { 6561 conn = (ContentProviderConnection)connection; 6562 } catch (ClassCastException e) { 6563 String msg ="refContentProvider: " + connection 6564 + " not a ContentProviderConnection"; 6565 Slog.w(TAG, msg); 6566 throw new IllegalArgumentException(msg); 6567 } 6568 if (conn == null) { 6569 throw new NullPointerException("connection is null"); 6570 } 6571 6572 synchronized (this) { 6573 if (stable > 0) { 6574 conn.numStableIncs += stable; 6575 } 6576 stable = conn.stableCount + stable; 6577 if (stable < 0) { 6578 throw new IllegalStateException("stableCount < 0: " + stable); 6579 } 6580 6581 if (unstable > 0) { 6582 conn.numUnstableIncs += unstable; 6583 } 6584 unstable = conn.unstableCount + unstable; 6585 if (unstable < 0) { 6586 throw new IllegalStateException("unstableCount < 0: " + unstable); 6587 } 6588 6589 if ((stable+unstable) <= 0) { 6590 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6591 + stable + " unstable=" + unstable); 6592 } 6593 conn.stableCount = stable; 6594 conn.unstableCount = unstable; 6595 return !conn.dead; 6596 } 6597 } 6598 6599 public void unstableProviderDied(IBinder connection) { 6600 ContentProviderConnection conn; 6601 try { 6602 conn = (ContentProviderConnection)connection; 6603 } catch (ClassCastException e) { 6604 String msg ="refContentProvider: " + connection 6605 + " not a ContentProviderConnection"; 6606 Slog.w(TAG, msg); 6607 throw new IllegalArgumentException(msg); 6608 } 6609 if (conn == null) { 6610 throw new NullPointerException("connection is null"); 6611 } 6612 6613 // Safely retrieve the content provider associated with the connection. 6614 IContentProvider provider; 6615 synchronized (this) { 6616 provider = conn.provider.provider; 6617 } 6618 6619 if (provider == null) { 6620 // Um, yeah, we're way ahead of you. 6621 return; 6622 } 6623 6624 // Make sure the caller is being honest with us. 6625 if (provider.asBinder().pingBinder()) { 6626 // Er, no, still looks good to us. 6627 synchronized (this) { 6628 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6629 + " says " + conn + " died, but we don't agree"); 6630 return; 6631 } 6632 } 6633 6634 // Well look at that! It's dead! 6635 synchronized (this) { 6636 if (conn.provider.provider != provider) { 6637 // But something changed... good enough. 6638 return; 6639 } 6640 6641 ProcessRecord proc = conn.provider.proc; 6642 if (proc == null || proc.thread == null) { 6643 // Seems like the process is already cleaned up. 6644 return; 6645 } 6646 6647 // As far as we're concerned, this is just like receiving a 6648 // death notification... just a bit prematurely. 6649 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6650 + ") early provider death"); 6651 final long ident = Binder.clearCallingIdentity(); 6652 try { 6653 appDiedLocked(proc, proc.pid, proc.thread); 6654 } finally { 6655 Binder.restoreCallingIdentity(ident); 6656 } 6657 } 6658 } 6659 6660 public static final void installSystemProviders() { 6661 List<ProviderInfo> providers; 6662 synchronized (mSelf) { 6663 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6664 providers = mSelf.generateApplicationProvidersLocked(app); 6665 if (providers != null) { 6666 for (int i=providers.size()-1; i>=0; i--) { 6667 ProviderInfo pi = (ProviderInfo)providers.get(i); 6668 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6669 Slog.w(TAG, "Not installing system proc provider " + pi.name 6670 + ": not system .apk"); 6671 providers.remove(i); 6672 } 6673 } 6674 } 6675 } 6676 if (providers != null) { 6677 mSystemThread.installSystemProviders(providers); 6678 } 6679 6680 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6681 6682 mSelf.mUsageStatsService.monitorPackages(); 6683 } 6684 6685 /** 6686 * Allows app to retrieve the MIME type of a URI without having permission 6687 * to access its content provider. 6688 * 6689 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6690 * 6691 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6692 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6693 */ 6694 public String getProviderMimeType(Uri uri) { 6695 enforceNotIsolatedCaller("getProviderMimeType"); 6696 final String name = uri.getAuthority(); 6697 final long ident = Binder.clearCallingIdentity(); 6698 ContentProviderHolder holder = null; 6699 6700 try { 6701 holder = getContentProviderExternalUnchecked(name, null); 6702 if (holder != null) { 6703 return holder.provider.getType(uri); 6704 } 6705 } catch (RemoteException e) { 6706 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6707 return null; 6708 } finally { 6709 if (holder != null) { 6710 removeContentProviderExternalUnchecked(name, null); 6711 } 6712 Binder.restoreCallingIdentity(ident); 6713 } 6714 6715 return null; 6716 } 6717 6718 // ========================================================= 6719 // GLOBAL MANAGEMENT 6720 // ========================================================= 6721 6722 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6723 ApplicationInfo info, String customProcess, boolean isolated) { 6724 String proc = customProcess != null ? customProcess : info.processName; 6725 BatteryStatsImpl.Uid.Proc ps = null; 6726 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6727 int uid = info.uid; 6728 if (isolated) { 6729 int userId = UserHandle.getUserId(uid); 6730 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6731 uid = 0; 6732 while (true) { 6733 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6734 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6735 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6736 } 6737 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6738 mNextIsolatedProcessUid++; 6739 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6740 // No process for this uid, use it. 6741 break; 6742 } 6743 stepsLeft--; 6744 if (stepsLeft <= 0) { 6745 return null; 6746 } 6747 } 6748 } 6749 synchronized (stats) { 6750 ps = stats.getProcessStatsLocked(info.uid, proc); 6751 } 6752 return new ProcessRecord(ps, thread, info, proc, uid); 6753 } 6754 6755 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6756 ProcessRecord app; 6757 if (!isolated) { 6758 app = getProcessRecordLocked(info.processName, info.uid); 6759 } else { 6760 app = null; 6761 } 6762 6763 if (app == null) { 6764 app = newProcessRecordLocked(null, info, null, isolated); 6765 mProcessNames.put(info.processName, app.uid, app); 6766 if (isolated) { 6767 mIsolatedProcesses.put(app.uid, app); 6768 } 6769 updateLruProcessLocked(app, true, true); 6770 } 6771 6772 // This package really, really can not be stopped. 6773 try { 6774 AppGlobals.getPackageManager().setPackageStoppedState( 6775 info.packageName, false, UserHandle.getUserId(app.uid)); 6776 } catch (RemoteException e) { 6777 } catch (IllegalArgumentException e) { 6778 Slog.w(TAG, "Failed trying to unstop package " 6779 + info.packageName + ": " + e); 6780 } 6781 6782 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6783 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6784 app.persistent = true; 6785 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6786 } 6787 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6788 mPersistentStartingProcesses.add(app); 6789 startProcessLocked(app, "added application", app.processName); 6790 } 6791 6792 return app; 6793 } 6794 6795 public void unhandledBack() { 6796 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6797 "unhandledBack()"); 6798 6799 synchronized(this) { 6800 int count = mMainStack.mHistory.size(); 6801 if (DEBUG_SWITCH) Slog.d( 6802 TAG, "Performing unhandledBack(): stack size = " + count); 6803 if (count > 1) { 6804 final long origId = Binder.clearCallingIdentity(); 6805 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6806 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6807 Binder.restoreCallingIdentity(origId); 6808 } 6809 } 6810 } 6811 6812 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6813 enforceNotIsolatedCaller("openContentUri"); 6814 String name = uri.getAuthority(); 6815 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6816 ParcelFileDescriptor pfd = null; 6817 if (cph != null) { 6818 // We record the binder invoker's uid in thread-local storage before 6819 // going to the content provider to open the file. Later, in the code 6820 // that handles all permissions checks, we look for this uid and use 6821 // that rather than the Activity Manager's own uid. The effect is that 6822 // we do the check against the caller's permissions even though it looks 6823 // to the content provider like the Activity Manager itself is making 6824 // the request. 6825 sCallerIdentity.set(new Identity( 6826 Binder.getCallingPid(), Binder.getCallingUid())); 6827 try { 6828 pfd = cph.provider.openFile(uri, "r"); 6829 } catch (FileNotFoundException e) { 6830 // do nothing; pfd will be returned null 6831 } finally { 6832 // Ensure that whatever happens, we clean up the identity state 6833 sCallerIdentity.remove(); 6834 } 6835 6836 // We've got the fd now, so we're done with the provider. 6837 removeContentProviderExternalUnchecked(name, null); 6838 } else { 6839 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6840 } 6841 return pfd; 6842 } 6843 6844 // Actually is sleeping or shutting down or whatever else in the future 6845 // is an inactive state. 6846 public boolean isSleeping() { 6847 return mSleeping || mShuttingDown; 6848 } 6849 6850 public void goingToSleep() { 6851 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6852 != PackageManager.PERMISSION_GRANTED) { 6853 throw new SecurityException("Requires permission " 6854 + android.Manifest.permission.DEVICE_POWER); 6855 } 6856 6857 synchronized(this) { 6858 mWentToSleep = true; 6859 updateEventDispatchingLocked(); 6860 6861 if (!mSleeping) { 6862 mSleeping = true; 6863 mMainStack.stopIfSleepingLocked(); 6864 6865 // Initialize the wake times of all processes. 6866 checkExcessivePowerUsageLocked(false); 6867 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6868 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6869 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6870 } 6871 } 6872 } 6873 6874 public boolean shutdown(int timeout) { 6875 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6876 != PackageManager.PERMISSION_GRANTED) { 6877 throw new SecurityException("Requires permission " 6878 + android.Manifest.permission.SHUTDOWN); 6879 } 6880 6881 boolean timedout = false; 6882 6883 synchronized(this) { 6884 mShuttingDown = true; 6885 updateEventDispatchingLocked(); 6886 6887 if (mMainStack.mResumedActivity != null) { 6888 mMainStack.stopIfSleepingLocked(); 6889 final long endTime = System.currentTimeMillis() + timeout; 6890 while (mMainStack.mResumedActivity != null 6891 || mMainStack.mPausingActivity != null) { 6892 long delay = endTime - System.currentTimeMillis(); 6893 if (delay <= 0) { 6894 Slog.w(TAG, "Activity manager shutdown timed out"); 6895 timedout = true; 6896 break; 6897 } 6898 try { 6899 this.wait(); 6900 } catch (InterruptedException e) { 6901 } 6902 } 6903 } 6904 } 6905 6906 mUsageStatsService.shutdown(); 6907 mBatteryStatsService.shutdown(); 6908 6909 return timedout; 6910 } 6911 6912 public final void activitySlept(IBinder token) { 6913 if (localLOGV) Slog.v( 6914 TAG, "Activity slept: token=" + token); 6915 6916 ActivityRecord r = null; 6917 6918 final long origId = Binder.clearCallingIdentity(); 6919 6920 synchronized (this) { 6921 r = mMainStack.isInStackLocked(token); 6922 if (r != null) { 6923 mMainStack.activitySleptLocked(r); 6924 } 6925 } 6926 6927 Binder.restoreCallingIdentity(origId); 6928 } 6929 6930 private void comeOutOfSleepIfNeededLocked() { 6931 if (!mWentToSleep && !mLockScreenShown) { 6932 if (mSleeping) { 6933 mSleeping = false; 6934 mMainStack.awakeFromSleepingLocked(); 6935 mMainStack.resumeTopActivityLocked(null); 6936 } 6937 } 6938 } 6939 6940 public void wakingUp() { 6941 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6942 != PackageManager.PERMISSION_GRANTED) { 6943 throw new SecurityException("Requires permission " 6944 + android.Manifest.permission.DEVICE_POWER); 6945 } 6946 6947 synchronized(this) { 6948 mWentToSleep = false; 6949 updateEventDispatchingLocked(); 6950 comeOutOfSleepIfNeededLocked(); 6951 } 6952 } 6953 6954 private void updateEventDispatchingLocked() { 6955 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6956 } 6957 6958 public void setLockScreenShown(boolean shown) { 6959 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6960 != PackageManager.PERMISSION_GRANTED) { 6961 throw new SecurityException("Requires permission " 6962 + android.Manifest.permission.DEVICE_POWER); 6963 } 6964 6965 synchronized(this) { 6966 mLockScreenShown = shown; 6967 comeOutOfSleepIfNeededLocked(); 6968 } 6969 } 6970 6971 public void stopAppSwitches() { 6972 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6973 != PackageManager.PERMISSION_GRANTED) { 6974 throw new SecurityException("Requires permission " 6975 + android.Manifest.permission.STOP_APP_SWITCHES); 6976 } 6977 6978 synchronized(this) { 6979 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6980 + APP_SWITCH_DELAY_TIME; 6981 mDidAppSwitch = false; 6982 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6983 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6984 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6985 } 6986 } 6987 6988 public void resumeAppSwitches() { 6989 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6990 != PackageManager.PERMISSION_GRANTED) { 6991 throw new SecurityException("Requires permission " 6992 + android.Manifest.permission.STOP_APP_SWITCHES); 6993 } 6994 6995 synchronized(this) { 6996 // Note that we don't execute any pending app switches... we will 6997 // let those wait until either the timeout, or the next start 6998 // activity request. 6999 mAppSwitchesAllowedTime = 0; 7000 } 7001 } 7002 7003 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7004 String name) { 7005 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7006 return true; 7007 } 7008 7009 final int perm = checkComponentPermission( 7010 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7011 callingUid, -1, true); 7012 if (perm == PackageManager.PERMISSION_GRANTED) { 7013 return true; 7014 } 7015 7016 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7017 return false; 7018 } 7019 7020 public void setDebugApp(String packageName, boolean waitForDebugger, 7021 boolean persistent) { 7022 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7023 "setDebugApp()"); 7024 7025 // Note that this is not really thread safe if there are multiple 7026 // callers into it at the same time, but that's not a situation we 7027 // care about. 7028 if (persistent) { 7029 final ContentResolver resolver = mContext.getContentResolver(); 7030 Settings.System.putString( 7031 resolver, Settings.System.DEBUG_APP, 7032 packageName); 7033 Settings.System.putInt( 7034 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7035 waitForDebugger ? 1 : 0); 7036 } 7037 7038 synchronized (this) { 7039 if (!persistent) { 7040 mOrigDebugApp = mDebugApp; 7041 mOrigWaitForDebugger = mWaitForDebugger; 7042 } 7043 mDebugApp = packageName; 7044 mWaitForDebugger = waitForDebugger; 7045 mDebugTransient = !persistent; 7046 if (packageName != null) { 7047 final long origId = Binder.clearCallingIdentity(); 7048 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7049 Binder.restoreCallingIdentity(origId); 7050 } 7051 } 7052 } 7053 7054 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7055 synchronized (this) { 7056 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7057 if (!isDebuggable) { 7058 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7059 throw new SecurityException("Process not debuggable: " + app.packageName); 7060 } 7061 } 7062 7063 mOpenGlTraceApp = processName; 7064 } 7065 } 7066 7067 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7068 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7069 synchronized (this) { 7070 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7071 if (!isDebuggable) { 7072 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7073 throw new SecurityException("Process not debuggable: " + app.packageName); 7074 } 7075 } 7076 mProfileApp = processName; 7077 mProfileFile = profileFile; 7078 if (mProfileFd != null) { 7079 try { 7080 mProfileFd.close(); 7081 } catch (IOException e) { 7082 } 7083 mProfileFd = null; 7084 } 7085 mProfileFd = profileFd; 7086 mProfileType = 0; 7087 mAutoStopProfiler = autoStopProfiler; 7088 } 7089 } 7090 7091 public void setAlwaysFinish(boolean enabled) { 7092 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7093 "setAlwaysFinish()"); 7094 7095 Settings.System.putInt( 7096 mContext.getContentResolver(), 7097 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7098 7099 synchronized (this) { 7100 mAlwaysFinishActivities = enabled; 7101 } 7102 } 7103 7104 public void setActivityController(IActivityController controller) { 7105 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7106 "setActivityController()"); 7107 synchronized (this) { 7108 mController = controller; 7109 } 7110 } 7111 7112 public boolean isUserAMonkey() { 7113 // For now the fact that there is a controller implies 7114 // we have a monkey. 7115 synchronized (this) { 7116 return mController != null; 7117 } 7118 } 7119 7120 public void registerProcessObserver(IProcessObserver observer) { 7121 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7122 "registerProcessObserver()"); 7123 synchronized (this) { 7124 mProcessObservers.register(observer); 7125 } 7126 } 7127 7128 public void unregisterProcessObserver(IProcessObserver observer) { 7129 synchronized (this) { 7130 mProcessObservers.unregister(observer); 7131 } 7132 } 7133 7134 public void setImmersive(IBinder token, boolean immersive) { 7135 synchronized(this) { 7136 ActivityRecord r = mMainStack.isInStackLocked(token); 7137 if (r == null) { 7138 throw new IllegalArgumentException(); 7139 } 7140 r.immersive = immersive; 7141 } 7142 } 7143 7144 public boolean isImmersive(IBinder token) { 7145 synchronized (this) { 7146 ActivityRecord r = mMainStack.isInStackLocked(token); 7147 if (r == null) { 7148 throw new IllegalArgumentException(); 7149 } 7150 return r.immersive; 7151 } 7152 } 7153 7154 public boolean isTopActivityImmersive() { 7155 enforceNotIsolatedCaller("startActivity"); 7156 synchronized (this) { 7157 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7158 return (r != null) ? r.immersive : false; 7159 } 7160 } 7161 7162 public final void enterSafeMode() { 7163 synchronized(this) { 7164 // It only makes sense to do this before the system is ready 7165 // and started launching other packages. 7166 if (!mSystemReady) { 7167 try { 7168 AppGlobals.getPackageManager().enterSafeMode(); 7169 } catch (RemoteException e) { 7170 } 7171 } 7172 } 7173 } 7174 7175 public final void showSafeModeOverlay() { 7176 View v = LayoutInflater.from(mContext).inflate( 7177 com.android.internal.R.layout.safe_mode, null); 7178 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7179 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7180 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7181 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7182 lp.gravity = Gravity.BOTTOM | Gravity.START; 7183 lp.format = v.getBackground().getOpacity(); 7184 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7185 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7186 ((WindowManager)mContext.getSystemService( 7187 Context.WINDOW_SERVICE)).addView(v, lp); 7188 } 7189 7190 public void noteWakeupAlarm(IIntentSender sender) { 7191 if (!(sender instanceof PendingIntentRecord)) { 7192 return; 7193 } 7194 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7195 synchronized (stats) { 7196 if (mBatteryStatsService.isOnBattery()) { 7197 mBatteryStatsService.enforceCallingPermission(); 7198 PendingIntentRecord rec = (PendingIntentRecord)sender; 7199 int MY_UID = Binder.getCallingUid(); 7200 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7201 BatteryStatsImpl.Uid.Pkg pkg = 7202 stats.getPackageStatsLocked(uid, rec.key.packageName); 7203 pkg.incWakeupsLocked(); 7204 } 7205 } 7206 } 7207 7208 public boolean killPids(int[] pids, String pReason, boolean secure) { 7209 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7210 throw new SecurityException("killPids only available to the system"); 7211 } 7212 String reason = (pReason == null) ? "Unknown" : pReason; 7213 // XXX Note: don't acquire main activity lock here, because the window 7214 // manager calls in with its locks held. 7215 7216 boolean killed = false; 7217 synchronized (mPidsSelfLocked) { 7218 int[] types = new int[pids.length]; 7219 int worstType = 0; 7220 for (int i=0; i<pids.length; i++) { 7221 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7222 if (proc != null) { 7223 int type = proc.setAdj; 7224 types[i] = type; 7225 if (type > worstType) { 7226 worstType = type; 7227 } 7228 } 7229 } 7230 7231 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7232 // then constrain it so we will kill all hidden procs. 7233 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7234 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7235 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7236 } 7237 7238 // If this is not a secure call, don't let it kill processes that 7239 // are important. 7240 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7241 worstType = ProcessList.SERVICE_ADJ; 7242 } 7243 7244 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7245 for (int i=0; i<pids.length; i++) { 7246 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7247 if (proc == null) { 7248 continue; 7249 } 7250 int adj = proc.setAdj; 7251 if (adj >= worstType && !proc.killedBackground) { 7252 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7253 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7254 proc.processName, adj, reason); 7255 killed = true; 7256 proc.killedBackground = true; 7257 Process.killProcessQuiet(pids[i]); 7258 } 7259 } 7260 } 7261 return killed; 7262 } 7263 7264 @Override 7265 public boolean killProcessesBelowForeground(String reason) { 7266 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7267 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7268 } 7269 7270 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7271 } 7272 7273 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7274 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7275 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7276 } 7277 7278 boolean killed = false; 7279 synchronized (mPidsSelfLocked) { 7280 final int size = mPidsSelfLocked.size(); 7281 for (int i = 0; i < size; i++) { 7282 final int pid = mPidsSelfLocked.keyAt(i); 7283 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7284 if (proc == null) continue; 7285 7286 final int adj = proc.setAdj; 7287 if (adj > belowAdj && !proc.killedBackground) { 7288 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7289 EventLog.writeEvent( 7290 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7291 killed = true; 7292 proc.killedBackground = true; 7293 Process.killProcessQuiet(pid); 7294 } 7295 } 7296 } 7297 return killed; 7298 } 7299 7300 public final void startRunning(String pkg, String cls, String action, 7301 String data) { 7302 synchronized(this) { 7303 if (mStartRunning) { 7304 return; 7305 } 7306 mStartRunning = true; 7307 mTopComponent = pkg != null && cls != null 7308 ? new ComponentName(pkg, cls) : null; 7309 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7310 mTopData = data; 7311 if (!mSystemReady) { 7312 return; 7313 } 7314 } 7315 7316 systemReady(null); 7317 } 7318 7319 private void retrieveSettings() { 7320 final ContentResolver resolver = mContext.getContentResolver(); 7321 String debugApp = Settings.System.getString( 7322 resolver, Settings.System.DEBUG_APP); 7323 boolean waitForDebugger = Settings.System.getInt( 7324 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7325 boolean alwaysFinishActivities = Settings.System.getInt( 7326 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7327 7328 Configuration configuration = new Configuration(); 7329 Settings.System.getConfiguration(resolver, configuration); 7330 7331 synchronized (this) { 7332 mDebugApp = mOrigDebugApp = debugApp; 7333 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7334 mAlwaysFinishActivities = alwaysFinishActivities; 7335 // This happens before any activities are started, so we can 7336 // change mConfiguration in-place. 7337 updateConfigurationLocked(configuration, null, false, true); 7338 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7339 } 7340 } 7341 7342 public boolean testIsSystemReady() { 7343 // no need to synchronize(this) just to read & return the value 7344 return mSystemReady; 7345 } 7346 7347 private static File getCalledPreBootReceiversFile() { 7348 File dataDir = Environment.getDataDirectory(); 7349 File systemDir = new File(dataDir, "system"); 7350 File fname = new File(systemDir, "called_pre_boots.dat"); 7351 return fname; 7352 } 7353 7354 static final int LAST_DONE_VERSION = 10000; 7355 7356 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7357 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7358 File file = getCalledPreBootReceiversFile(); 7359 FileInputStream fis = null; 7360 try { 7361 fis = new FileInputStream(file); 7362 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7363 int fvers = dis.readInt(); 7364 if (fvers == LAST_DONE_VERSION) { 7365 String vers = dis.readUTF(); 7366 String codename = dis.readUTF(); 7367 String build = dis.readUTF(); 7368 if (android.os.Build.VERSION.RELEASE.equals(vers) 7369 && android.os.Build.VERSION.CODENAME.equals(codename) 7370 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7371 int num = dis.readInt(); 7372 while (num > 0) { 7373 num--; 7374 String pkg = dis.readUTF(); 7375 String cls = dis.readUTF(); 7376 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7377 } 7378 } 7379 } 7380 } catch (FileNotFoundException e) { 7381 } catch (IOException e) { 7382 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7383 } finally { 7384 if (fis != null) { 7385 try { 7386 fis.close(); 7387 } catch (IOException e) { 7388 } 7389 } 7390 } 7391 return lastDoneReceivers; 7392 } 7393 7394 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7395 File file = getCalledPreBootReceiversFile(); 7396 FileOutputStream fos = null; 7397 DataOutputStream dos = null; 7398 try { 7399 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7400 fos = new FileOutputStream(file); 7401 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7402 dos.writeInt(LAST_DONE_VERSION); 7403 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7404 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7405 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7406 dos.writeInt(list.size()); 7407 for (int i=0; i<list.size(); i++) { 7408 dos.writeUTF(list.get(i).getPackageName()); 7409 dos.writeUTF(list.get(i).getClassName()); 7410 } 7411 } catch (IOException e) { 7412 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7413 file.delete(); 7414 } finally { 7415 FileUtils.sync(fos); 7416 if (dos != null) { 7417 try { 7418 dos.close(); 7419 } catch (IOException e) { 7420 // TODO Auto-generated catch block 7421 e.printStackTrace(); 7422 } 7423 } 7424 } 7425 } 7426 7427 public void systemReady(final Runnable goingCallback) { 7428 synchronized(this) { 7429 if (mSystemReady) { 7430 if (goingCallback != null) goingCallback.run(); 7431 return; 7432 } 7433 7434 // Check to see if there are any update receivers to run. 7435 if (!mDidUpdate) { 7436 if (mWaitingUpdate) { 7437 return; 7438 } 7439 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7440 List<ResolveInfo> ris = null; 7441 try { 7442 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7443 intent, null, 0, 0); 7444 } catch (RemoteException e) { 7445 } 7446 if (ris != null) { 7447 for (int i=ris.size()-1; i>=0; i--) { 7448 if ((ris.get(i).activityInfo.applicationInfo.flags 7449 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7450 ris.remove(i); 7451 } 7452 } 7453 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7454 7455 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7456 7457 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7458 for (int i=0; i<ris.size(); i++) { 7459 ActivityInfo ai = ris.get(i).activityInfo; 7460 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7461 if (lastDoneReceivers.contains(comp)) { 7462 ris.remove(i); 7463 i--; 7464 } 7465 } 7466 7467 for (int i=0; i<ris.size(); i++) { 7468 ActivityInfo ai = ris.get(i).activityInfo; 7469 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7470 doneReceivers.add(comp); 7471 intent.setComponent(comp); 7472 IIntentReceiver finisher = null; 7473 if (i == ris.size()-1) { 7474 finisher = new IIntentReceiver.Stub() { 7475 public void performReceive(Intent intent, int resultCode, 7476 String data, Bundle extras, boolean ordered, 7477 boolean sticky) { 7478 // The raw IIntentReceiver interface is called 7479 // with the AM lock held, so redispatch to 7480 // execute our code without the lock. 7481 mHandler.post(new Runnable() { 7482 public void run() { 7483 synchronized (ActivityManagerService.this) { 7484 mDidUpdate = true; 7485 } 7486 writeLastDonePreBootReceivers(doneReceivers); 7487 showBootMessage(mContext.getText( 7488 R.string.android_upgrading_complete), 7489 false); 7490 systemReady(goingCallback); 7491 } 7492 }); 7493 } 7494 }; 7495 } 7496 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7497 /* TODO: Send this to all users */ 7498 broadcastIntentLocked(null, null, intent, null, finisher, 7499 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7500 0 /* UserId zero */); 7501 if (finisher != null) { 7502 mWaitingUpdate = true; 7503 } 7504 } 7505 } 7506 if (mWaitingUpdate) { 7507 return; 7508 } 7509 mDidUpdate = true; 7510 } 7511 7512 mSystemReady = true; 7513 if (!mStartRunning) { 7514 return; 7515 } 7516 } 7517 7518 ArrayList<ProcessRecord> procsToKill = null; 7519 synchronized(mPidsSelfLocked) { 7520 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7521 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7522 if (!isAllowedWhileBooting(proc.info)){ 7523 if (procsToKill == null) { 7524 procsToKill = new ArrayList<ProcessRecord>(); 7525 } 7526 procsToKill.add(proc); 7527 } 7528 } 7529 } 7530 7531 synchronized(this) { 7532 if (procsToKill != null) { 7533 for (int i=procsToKill.size()-1; i>=0; i--) { 7534 ProcessRecord proc = procsToKill.get(i); 7535 Slog.i(TAG, "Removing system update proc: " + proc); 7536 removeProcessLocked(proc, true, false, "system update done"); 7537 } 7538 } 7539 7540 // Now that we have cleaned up any update processes, we 7541 // are ready to start launching real processes and know that 7542 // we won't trample on them any more. 7543 mProcessesReady = true; 7544 } 7545 7546 Slog.i(TAG, "System now ready"); 7547 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7548 SystemClock.uptimeMillis()); 7549 7550 synchronized(this) { 7551 // Make sure we have no pre-ready processes sitting around. 7552 7553 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7554 ResolveInfo ri = mContext.getPackageManager() 7555 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7556 STOCK_PM_FLAGS); 7557 CharSequence errorMsg = null; 7558 if (ri != null) { 7559 ActivityInfo ai = ri.activityInfo; 7560 ApplicationInfo app = ai.applicationInfo; 7561 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7562 mTopAction = Intent.ACTION_FACTORY_TEST; 7563 mTopData = null; 7564 mTopComponent = new ComponentName(app.packageName, 7565 ai.name); 7566 } else { 7567 errorMsg = mContext.getResources().getText( 7568 com.android.internal.R.string.factorytest_not_system); 7569 } 7570 } else { 7571 errorMsg = mContext.getResources().getText( 7572 com.android.internal.R.string.factorytest_no_action); 7573 } 7574 if (errorMsg != null) { 7575 mTopAction = null; 7576 mTopData = null; 7577 mTopComponent = null; 7578 Message msg = Message.obtain(); 7579 msg.what = SHOW_FACTORY_ERROR_MSG; 7580 msg.getData().putCharSequence("msg", errorMsg); 7581 mHandler.sendMessage(msg); 7582 } 7583 } 7584 } 7585 7586 retrieveSettings(); 7587 7588 if (goingCallback != null) goingCallback.run(); 7589 7590 synchronized (this) { 7591 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7592 try { 7593 List apps = AppGlobals.getPackageManager(). 7594 getPersistentApplications(STOCK_PM_FLAGS); 7595 if (apps != null) { 7596 int N = apps.size(); 7597 int i; 7598 for (i=0; i<N; i++) { 7599 ApplicationInfo info 7600 = (ApplicationInfo)apps.get(i); 7601 if (info != null && 7602 !info.packageName.equals("android")) { 7603 addAppLocked(info, false); 7604 } 7605 } 7606 } 7607 } catch (RemoteException ex) { 7608 // pm is in same process, this will never happen. 7609 } 7610 } 7611 7612 // Start up initial activity. 7613 mBooting = true; 7614 7615 try { 7616 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7617 Message msg = Message.obtain(); 7618 msg.what = SHOW_UID_ERROR_MSG; 7619 mHandler.sendMessage(msg); 7620 } 7621 } catch (RemoteException e) { 7622 } 7623 7624 mMainStack.resumeTopActivityLocked(null); 7625 } 7626 } 7627 7628 private boolean makeAppCrashingLocked(ProcessRecord app, 7629 String shortMsg, String longMsg, String stackTrace) { 7630 app.crashing = true; 7631 app.crashingReport = generateProcessError(app, 7632 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7633 startAppProblemLocked(app); 7634 app.stopFreezingAllLocked(); 7635 return handleAppCrashLocked(app); 7636 } 7637 7638 private void makeAppNotRespondingLocked(ProcessRecord app, 7639 String activity, String shortMsg, String longMsg) { 7640 app.notResponding = true; 7641 app.notRespondingReport = generateProcessError(app, 7642 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7643 activity, shortMsg, longMsg, null); 7644 startAppProblemLocked(app); 7645 app.stopFreezingAllLocked(); 7646 } 7647 7648 /** 7649 * Generate a process error record, suitable for attachment to a ProcessRecord. 7650 * 7651 * @param app The ProcessRecord in which the error occurred. 7652 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7653 * ActivityManager.AppErrorStateInfo 7654 * @param activity The activity associated with the crash, if known. 7655 * @param shortMsg Short message describing the crash. 7656 * @param longMsg Long message describing the crash. 7657 * @param stackTrace Full crash stack trace, may be null. 7658 * 7659 * @return Returns a fully-formed AppErrorStateInfo record. 7660 */ 7661 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7662 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7663 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7664 7665 report.condition = condition; 7666 report.processName = app.processName; 7667 report.pid = app.pid; 7668 report.uid = app.info.uid; 7669 report.tag = activity; 7670 report.shortMsg = shortMsg; 7671 report.longMsg = longMsg; 7672 report.stackTrace = stackTrace; 7673 7674 return report; 7675 } 7676 7677 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7678 synchronized (this) { 7679 app.crashing = false; 7680 app.crashingReport = null; 7681 app.notResponding = false; 7682 app.notRespondingReport = null; 7683 if (app.anrDialog == fromDialog) { 7684 app.anrDialog = null; 7685 } 7686 if (app.waitDialog == fromDialog) { 7687 app.waitDialog = null; 7688 } 7689 if (app.pid > 0 && app.pid != MY_PID) { 7690 handleAppCrashLocked(app); 7691 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7692 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7693 app.processName, app.setAdj, "user's request after error"); 7694 Process.killProcessQuiet(app.pid); 7695 } 7696 } 7697 } 7698 7699 private boolean handleAppCrashLocked(ProcessRecord app) { 7700 if (mHeadless) { 7701 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7702 return false; 7703 } 7704 long now = SystemClock.uptimeMillis(); 7705 7706 Long crashTime; 7707 if (!app.isolated) { 7708 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7709 } else { 7710 crashTime = null; 7711 } 7712 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7713 // This process loses! 7714 Slog.w(TAG, "Process " + app.info.processName 7715 + " has crashed too many times: killing!"); 7716 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7717 app.info.processName, app.uid); 7718 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7719 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7720 if (r.app == app) { 7721 Slog.w(TAG, " Force finishing activity " 7722 + r.intent.getComponent().flattenToShortString()); 7723 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7724 } 7725 } 7726 if (!app.persistent) { 7727 // We don't want to start this process again until the user 7728 // explicitly does so... but for persistent process, we really 7729 // need to keep it running. If a persistent process is actually 7730 // repeatedly crashing, then badness for everyone. 7731 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7732 app.info.processName); 7733 if (!app.isolated) { 7734 // XXX We don't have a way to mark isolated processes 7735 // as bad, since they don't have a peristent identity. 7736 mBadProcesses.put(app.info.processName, app.uid, now); 7737 mProcessCrashTimes.remove(app.info.processName, app.uid); 7738 } 7739 app.bad = true; 7740 app.removed = true; 7741 // Don't let services in this process be restarted and potentially 7742 // annoy the user repeatedly. Unless it is persistent, since those 7743 // processes run critical code. 7744 removeProcessLocked(app, false, false, "crash"); 7745 mMainStack.resumeTopActivityLocked(null); 7746 return false; 7747 } 7748 mMainStack.resumeTopActivityLocked(null); 7749 } else { 7750 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7751 if (r != null && r.app == app) { 7752 // If the top running activity is from this crashing 7753 // process, then terminate it to avoid getting in a loop. 7754 Slog.w(TAG, " Force finishing activity " 7755 + r.intent.getComponent().flattenToShortString()); 7756 int index = mMainStack.indexOfActivityLocked(r); 7757 r.stack.finishActivityLocked(r, index, 7758 Activity.RESULT_CANCELED, null, "crashed"); 7759 // Also terminate any activities below it that aren't yet 7760 // stopped, to avoid a situation where one will get 7761 // re-start our crashing activity once it gets resumed again. 7762 index--; 7763 if (index >= 0) { 7764 r = (ActivityRecord)mMainStack.mHistory.get(index); 7765 if (r.state == ActivityState.RESUMED 7766 || r.state == ActivityState.PAUSING 7767 || r.state == ActivityState.PAUSED) { 7768 if (!r.isHomeActivity || mHomeProcess != r.app) { 7769 Slog.w(TAG, " Force finishing activity " 7770 + r.intent.getComponent().flattenToShortString()); 7771 r.stack.finishActivityLocked(r, index, 7772 Activity.RESULT_CANCELED, null, "crashed"); 7773 } 7774 } 7775 } 7776 } 7777 } 7778 7779 // Bump up the crash count of any services currently running in the proc. 7780 if (app.services.size() != 0) { 7781 // Any services running in the application need to be placed 7782 // back in the pending list. 7783 Iterator<ServiceRecord> it = app.services.iterator(); 7784 while (it.hasNext()) { 7785 ServiceRecord sr = it.next(); 7786 sr.crashCount++; 7787 } 7788 } 7789 7790 // If the crashing process is what we consider to be the "home process" and it has been 7791 // replaced by a third-party app, clear the package preferred activities from packages 7792 // with a home activity running in the process to prevent a repeatedly crashing app 7793 // from blocking the user to manually clear the list. 7794 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7795 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7796 Iterator it = mHomeProcess.activities.iterator(); 7797 while (it.hasNext()) { 7798 ActivityRecord r = (ActivityRecord)it.next(); 7799 if (r.isHomeActivity) { 7800 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7801 try { 7802 ActivityThread.getPackageManager() 7803 .clearPackagePreferredActivities(r.packageName); 7804 } catch (RemoteException c) { 7805 // pm is in same process, this will never happen. 7806 } 7807 } 7808 } 7809 } 7810 7811 if (!app.isolated) { 7812 // XXX Can't keep track of crash times for isolated processes, 7813 // because they don't have a perisistent identity. 7814 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7815 } 7816 7817 return true; 7818 } 7819 7820 void startAppProblemLocked(ProcessRecord app) { 7821 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7822 mContext, app.info.packageName, app.info.flags); 7823 skipCurrentReceiverLocked(app); 7824 } 7825 7826 void skipCurrentReceiverLocked(ProcessRecord app) { 7827 for (BroadcastQueue queue : mBroadcastQueues) { 7828 queue.skipCurrentReceiverLocked(app); 7829 } 7830 } 7831 7832 /** 7833 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7834 * The application process will exit immediately after this call returns. 7835 * @param app object of the crashing app, null for the system server 7836 * @param crashInfo describing the exception 7837 */ 7838 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7839 ProcessRecord r = findAppProcess(app, "Crash"); 7840 final String processName = app == null ? "system_server" 7841 : (r == null ? "unknown" : r.processName); 7842 7843 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7844 processName, 7845 r == null ? -1 : r.info.flags, 7846 crashInfo.exceptionClassName, 7847 crashInfo.exceptionMessage, 7848 crashInfo.throwFileName, 7849 crashInfo.throwLineNumber); 7850 7851 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7852 7853 crashApplication(r, crashInfo); 7854 } 7855 7856 public void handleApplicationStrictModeViolation( 7857 IBinder app, 7858 int violationMask, 7859 StrictMode.ViolationInfo info) { 7860 ProcessRecord r = findAppProcess(app, "StrictMode"); 7861 if (r == null) { 7862 return; 7863 } 7864 7865 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7866 Integer stackFingerprint = info.hashCode(); 7867 boolean logIt = true; 7868 synchronized (mAlreadyLoggedViolatedStacks) { 7869 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7870 logIt = false; 7871 // TODO: sub-sample into EventLog for these, with 7872 // the info.durationMillis? Then we'd get 7873 // the relative pain numbers, without logging all 7874 // the stack traces repeatedly. We'd want to do 7875 // likewise in the client code, which also does 7876 // dup suppression, before the Binder call. 7877 } else { 7878 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7879 mAlreadyLoggedViolatedStacks.clear(); 7880 } 7881 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7882 } 7883 } 7884 if (logIt) { 7885 logStrictModeViolationToDropBox(r, info); 7886 } 7887 } 7888 7889 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7890 AppErrorResult result = new AppErrorResult(); 7891 synchronized (this) { 7892 final long origId = Binder.clearCallingIdentity(); 7893 7894 Message msg = Message.obtain(); 7895 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7896 HashMap<String, Object> data = new HashMap<String, Object>(); 7897 data.put("result", result); 7898 data.put("app", r); 7899 data.put("violationMask", violationMask); 7900 data.put("info", info); 7901 msg.obj = data; 7902 mHandler.sendMessage(msg); 7903 7904 Binder.restoreCallingIdentity(origId); 7905 } 7906 int res = result.get(); 7907 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7908 } 7909 } 7910 7911 // Depending on the policy in effect, there could be a bunch of 7912 // these in quick succession so we try to batch these together to 7913 // minimize disk writes, number of dropbox entries, and maximize 7914 // compression, by having more fewer, larger records. 7915 private void logStrictModeViolationToDropBox( 7916 ProcessRecord process, 7917 StrictMode.ViolationInfo info) { 7918 if (info == null) { 7919 return; 7920 } 7921 final boolean isSystemApp = process == null || 7922 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7923 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7924 final String processName = process == null ? "unknown" : process.processName; 7925 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7926 final DropBoxManager dbox = (DropBoxManager) 7927 mContext.getSystemService(Context.DROPBOX_SERVICE); 7928 7929 // Exit early if the dropbox isn't configured to accept this report type. 7930 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7931 7932 boolean bufferWasEmpty; 7933 boolean needsFlush; 7934 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7935 synchronized (sb) { 7936 bufferWasEmpty = sb.length() == 0; 7937 appendDropBoxProcessHeaders(process, processName, sb); 7938 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7939 sb.append("System-App: ").append(isSystemApp).append("\n"); 7940 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7941 if (info.violationNumThisLoop != 0) { 7942 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7943 } 7944 if (info.numAnimationsRunning != 0) { 7945 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7946 } 7947 if (info.broadcastIntentAction != null) { 7948 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7949 } 7950 if (info.durationMillis != -1) { 7951 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7952 } 7953 if (info.numInstances != -1) { 7954 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7955 } 7956 if (info.tags != null) { 7957 for (String tag : info.tags) { 7958 sb.append("Span-Tag: ").append(tag).append("\n"); 7959 } 7960 } 7961 sb.append("\n"); 7962 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7963 sb.append(info.crashInfo.stackTrace); 7964 } 7965 sb.append("\n"); 7966 7967 // Only buffer up to ~64k. Various logging bits truncate 7968 // things at 128k. 7969 needsFlush = (sb.length() > 64 * 1024); 7970 } 7971 7972 // Flush immediately if the buffer's grown too large, or this 7973 // is a non-system app. Non-system apps are isolated with a 7974 // different tag & policy and not batched. 7975 // 7976 // Batching is useful during internal testing with 7977 // StrictMode settings turned up high. Without batching, 7978 // thousands of separate files could be created on boot. 7979 if (!isSystemApp || needsFlush) { 7980 new Thread("Error dump: " + dropboxTag) { 7981 @Override 7982 public void run() { 7983 String report; 7984 synchronized (sb) { 7985 report = sb.toString(); 7986 sb.delete(0, sb.length()); 7987 sb.trimToSize(); 7988 } 7989 if (report.length() != 0) { 7990 dbox.addText(dropboxTag, report); 7991 } 7992 } 7993 }.start(); 7994 return; 7995 } 7996 7997 // System app batching: 7998 if (!bufferWasEmpty) { 7999 // An existing dropbox-writing thread is outstanding, so 8000 // we don't need to start it up. The existing thread will 8001 // catch the buffer appends we just did. 8002 return; 8003 } 8004 8005 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8006 // (After this point, we shouldn't access AMS internal data structures.) 8007 new Thread("Error dump: " + dropboxTag) { 8008 @Override 8009 public void run() { 8010 // 5 second sleep to let stacks arrive and be batched together 8011 try { 8012 Thread.sleep(5000); // 5 seconds 8013 } catch (InterruptedException e) {} 8014 8015 String errorReport; 8016 synchronized (mStrictModeBuffer) { 8017 errorReport = mStrictModeBuffer.toString(); 8018 if (errorReport.length() == 0) { 8019 return; 8020 } 8021 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8022 mStrictModeBuffer.trimToSize(); 8023 } 8024 dbox.addText(dropboxTag, errorReport); 8025 } 8026 }.start(); 8027 } 8028 8029 /** 8030 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8031 * @param app object of the crashing app, null for the system server 8032 * @param tag reported by the caller 8033 * @param crashInfo describing the context of the error 8034 * @return true if the process should exit immediately (WTF is fatal) 8035 */ 8036 public boolean handleApplicationWtf(IBinder app, String tag, 8037 ApplicationErrorReport.CrashInfo crashInfo) { 8038 ProcessRecord r = findAppProcess(app, "WTF"); 8039 final String processName = app == null ? "system_server" 8040 : (r == null ? "unknown" : r.processName); 8041 8042 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8043 processName, 8044 r == null ? -1 : r.info.flags, 8045 tag, crashInfo.exceptionMessage); 8046 8047 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8048 8049 if (r != null && r.pid != Process.myPid() && 8050 Settings.Secure.getInt(mContext.getContentResolver(), 8051 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8052 crashApplication(r, crashInfo); 8053 return true; 8054 } else { 8055 return false; 8056 } 8057 } 8058 8059 /** 8060 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8061 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8062 */ 8063 private ProcessRecord findAppProcess(IBinder app, String reason) { 8064 if (app == null) { 8065 return null; 8066 } 8067 8068 synchronized (this) { 8069 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8070 final int NA = apps.size(); 8071 for (int ia=0; ia<NA; ia++) { 8072 ProcessRecord p = apps.valueAt(ia); 8073 if (p.thread != null && p.thread.asBinder() == app) { 8074 return p; 8075 } 8076 } 8077 } 8078 8079 Slog.w(TAG, "Can't find mystery application for " + reason 8080 + " from pid=" + Binder.getCallingPid() 8081 + " uid=" + Binder.getCallingUid() + ": " + app); 8082 return null; 8083 } 8084 } 8085 8086 /** 8087 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8088 * to append various headers to the dropbox log text. 8089 */ 8090 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8091 StringBuilder sb) { 8092 // Watchdog thread ends up invoking this function (with 8093 // a null ProcessRecord) to add the stack file to dropbox. 8094 // Do not acquire a lock on this (am) in such cases, as it 8095 // could cause a potential deadlock, if and when watchdog 8096 // is invoked due to unavailability of lock on am and it 8097 // would prevent watchdog from killing system_server. 8098 if (process == null) { 8099 sb.append("Process: ").append(processName).append("\n"); 8100 return; 8101 } 8102 // Note: ProcessRecord 'process' is guarded by the service 8103 // instance. (notably process.pkgList, which could otherwise change 8104 // concurrently during execution of this method) 8105 synchronized (this) { 8106 sb.append("Process: ").append(processName).append("\n"); 8107 int flags = process.info.flags; 8108 IPackageManager pm = AppGlobals.getPackageManager(); 8109 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8110 for (String pkg : process.pkgList) { 8111 sb.append("Package: ").append(pkg); 8112 try { 8113 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8114 if (pi != null) { 8115 sb.append(" v").append(pi.versionCode); 8116 if (pi.versionName != null) { 8117 sb.append(" (").append(pi.versionName).append(")"); 8118 } 8119 } 8120 } catch (RemoteException e) { 8121 Slog.e(TAG, "Error getting package info: " + pkg, e); 8122 } 8123 sb.append("\n"); 8124 } 8125 } 8126 } 8127 8128 private static String processClass(ProcessRecord process) { 8129 if (process == null || process.pid == MY_PID) { 8130 return "system_server"; 8131 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8132 return "system_app"; 8133 } else { 8134 return "data_app"; 8135 } 8136 } 8137 8138 /** 8139 * Write a description of an error (crash, WTF, ANR) to the drop box. 8140 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8141 * @param process which caused the error, null means the system server 8142 * @param activity which triggered the error, null if unknown 8143 * @param parent activity related to the error, null if unknown 8144 * @param subject line related to the error, null if absent 8145 * @param report in long form describing the error, null if absent 8146 * @param logFile to include in the report, null if none 8147 * @param crashInfo giving an application stack trace, null if absent 8148 */ 8149 public void addErrorToDropBox(String eventType, 8150 ProcessRecord process, String processName, ActivityRecord activity, 8151 ActivityRecord parent, String subject, 8152 final String report, final File logFile, 8153 final ApplicationErrorReport.CrashInfo crashInfo) { 8154 // NOTE -- this must never acquire the ActivityManagerService lock, 8155 // otherwise the watchdog may be prevented from resetting the system. 8156 8157 final String dropboxTag = processClass(process) + "_" + eventType; 8158 final DropBoxManager dbox = (DropBoxManager) 8159 mContext.getSystemService(Context.DROPBOX_SERVICE); 8160 8161 // Exit early if the dropbox isn't configured to accept this report type. 8162 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8163 8164 final StringBuilder sb = new StringBuilder(1024); 8165 appendDropBoxProcessHeaders(process, processName, sb); 8166 if (activity != null) { 8167 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8168 } 8169 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8170 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8171 } 8172 if (parent != null && parent != activity) { 8173 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8174 } 8175 if (subject != null) { 8176 sb.append("Subject: ").append(subject).append("\n"); 8177 } 8178 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8179 if (Debug.isDebuggerConnected()) { 8180 sb.append("Debugger: Connected\n"); 8181 } 8182 sb.append("\n"); 8183 8184 // Do the rest in a worker thread to avoid blocking the caller on I/O 8185 // (After this point, we shouldn't access AMS internal data structures.) 8186 Thread worker = new Thread("Error dump: " + dropboxTag) { 8187 @Override 8188 public void run() { 8189 if (report != null) { 8190 sb.append(report); 8191 } 8192 if (logFile != null) { 8193 try { 8194 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8195 } catch (IOException e) { 8196 Slog.e(TAG, "Error reading " + logFile, e); 8197 } 8198 } 8199 if (crashInfo != null && crashInfo.stackTrace != null) { 8200 sb.append(crashInfo.stackTrace); 8201 } 8202 8203 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8204 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8205 if (lines > 0) { 8206 sb.append("\n"); 8207 8208 // Merge several logcat streams, and take the last N lines 8209 InputStreamReader input = null; 8210 try { 8211 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8212 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8213 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8214 8215 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8216 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8217 input = new InputStreamReader(logcat.getInputStream()); 8218 8219 int num; 8220 char[] buf = new char[8192]; 8221 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8222 } catch (IOException e) { 8223 Slog.e(TAG, "Error running logcat", e); 8224 } finally { 8225 if (input != null) try { input.close(); } catch (IOException e) {} 8226 } 8227 } 8228 8229 dbox.addText(dropboxTag, sb.toString()); 8230 } 8231 }; 8232 8233 if (process == null) { 8234 // If process is null, we are being called from some internal code 8235 // and may be about to die -- run this synchronously. 8236 worker.run(); 8237 } else { 8238 worker.start(); 8239 } 8240 } 8241 8242 /** 8243 * Bring up the "unexpected error" dialog box for a crashing app. 8244 * Deal with edge cases (intercepts from instrumented applications, 8245 * ActivityController, error intent receivers, that sort of thing). 8246 * @param r the application crashing 8247 * @param crashInfo describing the failure 8248 */ 8249 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8250 long timeMillis = System.currentTimeMillis(); 8251 String shortMsg = crashInfo.exceptionClassName; 8252 String longMsg = crashInfo.exceptionMessage; 8253 String stackTrace = crashInfo.stackTrace; 8254 if (shortMsg != null && longMsg != null) { 8255 longMsg = shortMsg + ": " + longMsg; 8256 } else if (shortMsg != null) { 8257 longMsg = shortMsg; 8258 } 8259 8260 AppErrorResult result = new AppErrorResult(); 8261 synchronized (this) { 8262 if (mController != null) { 8263 try { 8264 String name = r != null ? r.processName : null; 8265 int pid = r != null ? r.pid : Binder.getCallingPid(); 8266 if (!mController.appCrashed(name, pid, 8267 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8268 Slog.w(TAG, "Force-killing crashed app " + name 8269 + " at watcher's request"); 8270 Process.killProcess(pid); 8271 return; 8272 } 8273 } catch (RemoteException e) { 8274 mController = null; 8275 } 8276 } 8277 8278 final long origId = Binder.clearCallingIdentity(); 8279 8280 // If this process is running instrumentation, finish it. 8281 if (r != null && r.instrumentationClass != null) { 8282 Slog.w(TAG, "Error in app " + r.processName 8283 + " running instrumentation " + r.instrumentationClass + ":"); 8284 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8285 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8286 Bundle info = new Bundle(); 8287 info.putString("shortMsg", shortMsg); 8288 info.putString("longMsg", longMsg); 8289 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8290 Binder.restoreCallingIdentity(origId); 8291 return; 8292 } 8293 8294 // If we can't identify the process or it's already exceeded its crash quota, 8295 // quit right away without showing a crash dialog. 8296 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8297 Binder.restoreCallingIdentity(origId); 8298 return; 8299 } 8300 8301 Message msg = Message.obtain(); 8302 msg.what = SHOW_ERROR_MSG; 8303 HashMap data = new HashMap(); 8304 data.put("result", result); 8305 data.put("app", r); 8306 msg.obj = data; 8307 mHandler.sendMessage(msg); 8308 8309 Binder.restoreCallingIdentity(origId); 8310 } 8311 8312 int res = result.get(); 8313 8314 Intent appErrorIntent = null; 8315 synchronized (this) { 8316 if (r != null && !r.isolated) { 8317 // XXX Can't keep track of crash time for isolated processes, 8318 // since they don't have a persistent identity. 8319 mProcessCrashTimes.put(r.info.processName, r.uid, 8320 SystemClock.uptimeMillis()); 8321 } 8322 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8323 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8324 } 8325 } 8326 8327 if (appErrorIntent != null) { 8328 try { 8329 mContext.startActivity(appErrorIntent); 8330 } catch (ActivityNotFoundException e) { 8331 Slog.w(TAG, "bug report receiver dissappeared", e); 8332 } 8333 } 8334 } 8335 8336 Intent createAppErrorIntentLocked(ProcessRecord r, 8337 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8338 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8339 if (report == null) { 8340 return null; 8341 } 8342 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8343 result.setComponent(r.errorReportReceiver); 8344 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8345 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8346 return result; 8347 } 8348 8349 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8350 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8351 if (r.errorReportReceiver == null) { 8352 return null; 8353 } 8354 8355 if (!r.crashing && !r.notResponding) { 8356 return null; 8357 } 8358 8359 ApplicationErrorReport report = new ApplicationErrorReport(); 8360 report.packageName = r.info.packageName; 8361 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8362 report.processName = r.processName; 8363 report.time = timeMillis; 8364 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8365 8366 if (r.crashing) { 8367 report.type = ApplicationErrorReport.TYPE_CRASH; 8368 report.crashInfo = crashInfo; 8369 } else if (r.notResponding) { 8370 report.type = ApplicationErrorReport.TYPE_ANR; 8371 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8372 8373 report.anrInfo.activity = r.notRespondingReport.tag; 8374 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8375 report.anrInfo.info = r.notRespondingReport.longMsg; 8376 } 8377 8378 return report; 8379 } 8380 8381 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8382 enforceNotIsolatedCaller("getProcessesInErrorState"); 8383 // assume our apps are happy - lazy create the list 8384 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8385 8386 final boolean allUsers = ActivityManager.checkUidPermission( 8387 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8388 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8389 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8390 8391 synchronized (this) { 8392 8393 // iterate across all processes 8394 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8395 ProcessRecord app = mLruProcesses.get(i); 8396 if (!allUsers && app.userId != userId) { 8397 continue; 8398 } 8399 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8400 // This one's in trouble, so we'll generate a report for it 8401 // crashes are higher priority (in case there's a crash *and* an anr) 8402 ActivityManager.ProcessErrorStateInfo report = null; 8403 if (app.crashing) { 8404 report = app.crashingReport; 8405 } else if (app.notResponding) { 8406 report = app.notRespondingReport; 8407 } 8408 8409 if (report != null) { 8410 if (errList == null) { 8411 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8412 } 8413 errList.add(report); 8414 } else { 8415 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8416 " crashing = " + app.crashing + 8417 " notResponding = " + app.notResponding); 8418 } 8419 } 8420 } 8421 } 8422 8423 return errList; 8424 } 8425 8426 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8427 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8428 if (currApp != null) { 8429 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8430 } 8431 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8432 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8433 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8434 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8435 if (currApp != null) { 8436 currApp.lru = 0; 8437 } 8438 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8439 } else if (adj >= ProcessList.SERVICE_ADJ) { 8440 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8441 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8442 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8443 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8444 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8445 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8446 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8447 } else { 8448 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8449 } 8450 } 8451 8452 private void fillInProcMemInfo(ProcessRecord app, 8453 ActivityManager.RunningAppProcessInfo outInfo) { 8454 outInfo.pid = app.pid; 8455 outInfo.uid = app.info.uid; 8456 if (mHeavyWeightProcess == app) { 8457 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8458 } 8459 if (app.persistent) { 8460 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8461 } 8462 if (app.hasActivities) { 8463 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8464 } 8465 outInfo.lastTrimLevel = app.trimMemoryLevel; 8466 int adj = app.curAdj; 8467 outInfo.importance = oomAdjToImportance(adj, outInfo); 8468 outInfo.importanceReasonCode = app.adjTypeCode; 8469 } 8470 8471 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8472 enforceNotIsolatedCaller("getRunningAppProcesses"); 8473 // Lazy instantiation of list 8474 List<ActivityManager.RunningAppProcessInfo> runList = null; 8475 final boolean allUsers = ActivityManager.checkUidPermission( 8476 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8477 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8478 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8479 synchronized (this) { 8480 // Iterate across all processes 8481 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8482 ProcessRecord app = mLruProcesses.get(i); 8483 if (!allUsers && app.userId != userId) { 8484 continue; 8485 } 8486 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8487 // Generate process state info for running application 8488 ActivityManager.RunningAppProcessInfo currApp = 8489 new ActivityManager.RunningAppProcessInfo(app.processName, 8490 app.pid, app.getPackageList()); 8491 fillInProcMemInfo(app, currApp); 8492 if (app.adjSource instanceof ProcessRecord) { 8493 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8494 currApp.importanceReasonImportance = oomAdjToImportance( 8495 app.adjSourceOom, null); 8496 } else if (app.adjSource instanceof ActivityRecord) { 8497 ActivityRecord r = (ActivityRecord)app.adjSource; 8498 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8499 } 8500 if (app.adjTarget instanceof ComponentName) { 8501 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8502 } 8503 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8504 // + " lru=" + currApp.lru); 8505 if (runList == null) { 8506 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8507 } 8508 runList.add(currApp); 8509 } 8510 } 8511 } 8512 return runList; 8513 } 8514 8515 public List<ApplicationInfo> getRunningExternalApplications() { 8516 enforceNotIsolatedCaller("getRunningExternalApplications"); 8517 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8518 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8519 if (runningApps != null && runningApps.size() > 0) { 8520 Set<String> extList = new HashSet<String>(); 8521 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8522 if (app.pkgList != null) { 8523 for (String pkg : app.pkgList) { 8524 extList.add(pkg); 8525 } 8526 } 8527 } 8528 IPackageManager pm = AppGlobals.getPackageManager(); 8529 for (String pkg : extList) { 8530 try { 8531 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8532 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8533 retList.add(info); 8534 } 8535 } catch (RemoteException e) { 8536 } 8537 } 8538 } 8539 return retList; 8540 } 8541 8542 @Override 8543 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8544 enforceNotIsolatedCaller("getMyMemoryState"); 8545 synchronized (this) { 8546 ProcessRecord proc; 8547 synchronized (mPidsSelfLocked) { 8548 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8549 } 8550 fillInProcMemInfo(proc, outInfo); 8551 } 8552 } 8553 8554 @Override 8555 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8556 if (checkCallingPermission(android.Manifest.permission.DUMP) 8557 != PackageManager.PERMISSION_GRANTED) { 8558 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8559 + Binder.getCallingPid() 8560 + ", uid=" + Binder.getCallingUid() 8561 + " without permission " 8562 + android.Manifest.permission.DUMP); 8563 return; 8564 } 8565 8566 boolean dumpAll = false; 8567 boolean dumpClient = false; 8568 String dumpPackage = null; 8569 8570 int opti = 0; 8571 while (opti < args.length) { 8572 String opt = args[opti]; 8573 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8574 break; 8575 } 8576 opti++; 8577 if ("-a".equals(opt)) { 8578 dumpAll = true; 8579 } else if ("-c".equals(opt)) { 8580 dumpClient = true; 8581 } else if ("-h".equals(opt)) { 8582 pw.println("Activity manager dump options:"); 8583 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8584 pw.println(" cmd may be one of:"); 8585 pw.println(" a[ctivities]: activity stack state"); 8586 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8587 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8588 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8589 pw.println(" o[om]: out of memory management"); 8590 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8591 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8592 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8593 pw.println(" service [COMP_SPEC]: service client-side state"); 8594 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8595 pw.println(" all: dump all activities"); 8596 pw.println(" top: dump the top activity"); 8597 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8598 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8599 pw.println(" a partial substring in a component name, a"); 8600 pw.println(" hex object identifier."); 8601 pw.println(" -a: include all available server state."); 8602 pw.println(" -c: include client state."); 8603 return; 8604 } else { 8605 pw.println("Unknown argument: " + opt + "; use -h for help"); 8606 } 8607 } 8608 8609 long origId = Binder.clearCallingIdentity(); 8610 boolean more = false; 8611 // Is the caller requesting to dump a particular piece of data? 8612 if (opti < args.length) { 8613 String cmd = args[opti]; 8614 opti++; 8615 if ("activities".equals(cmd) || "a".equals(cmd)) { 8616 synchronized (this) { 8617 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8618 } 8619 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8620 String[] newArgs; 8621 String name; 8622 if (opti >= args.length) { 8623 name = null; 8624 newArgs = EMPTY_STRING_ARRAY; 8625 } else { 8626 name = args[opti]; 8627 opti++; 8628 newArgs = new String[args.length - opti]; 8629 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8630 args.length - opti); 8631 } 8632 synchronized (this) { 8633 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8634 } 8635 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8636 String[] newArgs; 8637 String name; 8638 if (opti >= args.length) { 8639 name = null; 8640 newArgs = EMPTY_STRING_ARRAY; 8641 } else { 8642 name = args[opti]; 8643 opti++; 8644 newArgs = new String[args.length - opti]; 8645 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8646 args.length - opti); 8647 } 8648 synchronized (this) { 8649 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8650 } 8651 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8652 String[] newArgs; 8653 String name; 8654 if (opti >= args.length) { 8655 name = null; 8656 newArgs = EMPTY_STRING_ARRAY; 8657 } else { 8658 name = args[opti]; 8659 opti++; 8660 newArgs = new String[args.length - opti]; 8661 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8662 args.length - opti); 8663 } 8664 synchronized (this) { 8665 dumpProcessesLocked(fd, pw, args, opti, true, name); 8666 } 8667 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8668 synchronized (this) { 8669 dumpOomLocked(fd, pw, args, opti, true); 8670 } 8671 } else if ("provider".equals(cmd)) { 8672 String[] newArgs; 8673 String name; 8674 if (opti >= args.length) { 8675 name = null; 8676 newArgs = EMPTY_STRING_ARRAY; 8677 } else { 8678 name = args[opti]; 8679 opti++; 8680 newArgs = new String[args.length - opti]; 8681 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8682 } 8683 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8684 pw.println("No providers match: " + name); 8685 pw.println("Use -h for help."); 8686 } 8687 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8688 synchronized (this) { 8689 dumpProvidersLocked(fd, pw, args, opti, true, null); 8690 } 8691 } else if ("service".equals(cmd)) { 8692 String[] newArgs; 8693 String name; 8694 if (opti >= args.length) { 8695 name = null; 8696 newArgs = EMPTY_STRING_ARRAY; 8697 } else { 8698 name = args[opti]; 8699 opti++; 8700 newArgs = new String[args.length - opti]; 8701 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8702 args.length - opti); 8703 } 8704 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8705 pw.println("No services match: " + name); 8706 pw.println("Use -h for help."); 8707 } 8708 } else if ("package".equals(cmd)) { 8709 String[] newArgs; 8710 if (opti >= args.length) { 8711 pw.println("package: no package name specified"); 8712 pw.println("Use -h for help."); 8713 } else { 8714 dumpPackage = args[opti]; 8715 opti++; 8716 newArgs = new String[args.length - opti]; 8717 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8718 args.length - opti); 8719 args = newArgs; 8720 opti = 0; 8721 more = true; 8722 } 8723 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8724 synchronized (this) { 8725 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8726 } 8727 } else { 8728 // Dumping a single activity? 8729 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8730 pw.println("Bad activity command, or no activities match: " + cmd); 8731 pw.println("Use -h for help."); 8732 } 8733 } 8734 if (!more) { 8735 Binder.restoreCallingIdentity(origId); 8736 return; 8737 } 8738 } 8739 8740 // No piece of data specified, dump everything. 8741 synchronized (this) { 8742 boolean needSep; 8743 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8744 if (needSep) { 8745 pw.println(" "); 8746 } 8747 if (dumpAll) { 8748 pw.println("-------------------------------------------------------------------------------"); 8749 } 8750 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8751 if (needSep) { 8752 pw.println(" "); 8753 } 8754 if (dumpAll) { 8755 pw.println("-------------------------------------------------------------------------------"); 8756 } 8757 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8758 if (needSep) { 8759 pw.println(" "); 8760 } 8761 if (dumpAll) { 8762 pw.println("-------------------------------------------------------------------------------"); 8763 } 8764 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8765 if (needSep) { 8766 pw.println(" "); 8767 } 8768 if (dumpAll) { 8769 pw.println("-------------------------------------------------------------------------------"); 8770 } 8771 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8772 if (needSep) { 8773 pw.println(" "); 8774 } 8775 if (dumpAll) { 8776 pw.println("-------------------------------------------------------------------------------"); 8777 } 8778 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8779 } 8780 Binder.restoreCallingIdentity(origId); 8781 } 8782 8783 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8784 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8785 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8786 pw.println(" Main stack:"); 8787 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8788 dumpPackage); 8789 pw.println(" "); 8790 pw.println(" Running activities (most recent first):"); 8791 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8792 dumpPackage); 8793 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8794 pw.println(" "); 8795 pw.println(" Activities waiting for another to become visible:"); 8796 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8797 !dumpAll, false, dumpPackage); 8798 } 8799 if (mMainStack.mStoppingActivities.size() > 0) { 8800 pw.println(" "); 8801 pw.println(" Activities waiting to stop:"); 8802 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8803 !dumpAll, false, dumpPackage); 8804 } 8805 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8806 pw.println(" "); 8807 pw.println(" Activities waiting to sleep:"); 8808 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8809 !dumpAll, false, dumpPackage); 8810 } 8811 if (mMainStack.mFinishingActivities.size() > 0) { 8812 pw.println(" "); 8813 pw.println(" Activities waiting to finish:"); 8814 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8815 !dumpAll, false, dumpPackage); 8816 } 8817 8818 pw.println(" "); 8819 if (mMainStack.mPausingActivity != null) { 8820 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8821 } 8822 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8823 pw.println(" mFocusedActivity: " + mFocusedActivity); 8824 if (dumpAll) { 8825 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8826 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8827 pw.println(" mDismissKeyguardOnNextActivity: " 8828 + mMainStack.mDismissKeyguardOnNextActivity); 8829 } 8830 8831 if (mRecentTasks.size() > 0) { 8832 pw.println(); 8833 pw.println(" Recent tasks:"); 8834 8835 final int N = mRecentTasks.size(); 8836 for (int i=0; i<N; i++) { 8837 TaskRecord tr = mRecentTasks.get(i); 8838 if (dumpPackage != null) { 8839 if (tr.realActivity == null || 8840 !dumpPackage.equals(tr.realActivity)) { 8841 continue; 8842 } 8843 } 8844 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8845 pw.println(tr); 8846 if (dumpAll) { 8847 mRecentTasks.get(i).dump(pw, " "); 8848 } 8849 } 8850 } 8851 8852 if (dumpAll) { 8853 pw.println(" "); 8854 pw.println(" mCurTask: " + mCurTask); 8855 } 8856 8857 return true; 8858 } 8859 8860 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8861 int opti, boolean dumpAll, String dumpPackage) { 8862 boolean needSep = false; 8863 int numPers = 0; 8864 8865 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8866 8867 if (dumpAll) { 8868 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8869 final int NA = procs.size(); 8870 for (int ia=0; ia<NA; ia++) { 8871 ProcessRecord r = procs.valueAt(ia); 8872 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8873 continue; 8874 } 8875 if (!needSep) { 8876 pw.println(" All known processes:"); 8877 needSep = true; 8878 } 8879 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8880 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8881 pw.print(" "); pw.println(r); 8882 r.dump(pw, " "); 8883 if (r.persistent) { 8884 numPers++; 8885 } 8886 } 8887 } 8888 } 8889 8890 if (mIsolatedProcesses.size() > 0) { 8891 if (needSep) pw.println(" "); 8892 needSep = true; 8893 pw.println(" Isolated process list (sorted by uid):"); 8894 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8895 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8896 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8897 continue; 8898 } 8899 pw.println(String.format("%sIsolated #%2d: %s", 8900 " ", i, r.toString())); 8901 } 8902 } 8903 8904 if (mLruProcesses.size() > 0) { 8905 if (needSep) pw.println(" "); 8906 needSep = true; 8907 pw.println(" Process LRU list (sorted by oom_adj):"); 8908 dumpProcessOomList(pw, this, mLruProcesses, " ", 8909 "Proc", "PERS", false, dumpPackage); 8910 needSep = true; 8911 } 8912 8913 if (dumpAll) { 8914 synchronized (mPidsSelfLocked) { 8915 boolean printed = false; 8916 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8917 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8918 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8919 continue; 8920 } 8921 if (!printed) { 8922 if (needSep) pw.println(" "); 8923 needSep = true; 8924 pw.println(" PID mappings:"); 8925 printed = true; 8926 } 8927 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8928 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8929 } 8930 } 8931 } 8932 8933 if (mForegroundProcesses.size() > 0) { 8934 synchronized (mPidsSelfLocked) { 8935 boolean printed = false; 8936 for (int i=0; i<mForegroundProcesses.size(); i++) { 8937 ProcessRecord r = mPidsSelfLocked.get( 8938 mForegroundProcesses.valueAt(i).pid); 8939 if (dumpPackage != null && (r == null 8940 || !dumpPackage.equals(r.info.packageName))) { 8941 continue; 8942 } 8943 if (!printed) { 8944 if (needSep) pw.println(" "); 8945 needSep = true; 8946 pw.println(" Foreground Processes:"); 8947 printed = true; 8948 } 8949 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8950 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8951 } 8952 } 8953 } 8954 8955 if (mPersistentStartingProcesses.size() > 0) { 8956 if (needSep) pw.println(" "); 8957 needSep = true; 8958 pw.println(" Persisent processes that are starting:"); 8959 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8960 "Starting Norm", "Restarting PERS", dumpPackage); 8961 } 8962 8963 if (mRemovedProcesses.size() > 0) { 8964 if (needSep) pw.println(" "); 8965 needSep = true; 8966 pw.println(" Processes that are being removed:"); 8967 dumpProcessList(pw, this, mRemovedProcesses, " ", 8968 "Removed Norm", "Removed PERS", dumpPackage); 8969 } 8970 8971 if (mProcessesOnHold.size() > 0) { 8972 if (needSep) pw.println(" "); 8973 needSep = true; 8974 pw.println(" Processes that are on old until the system is ready:"); 8975 dumpProcessList(pw, this, mProcessesOnHold, " ", 8976 "OnHold Norm", "OnHold PERS", dumpPackage); 8977 } 8978 8979 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8980 8981 if (mProcessCrashTimes.getMap().size() > 0) { 8982 boolean printed = false; 8983 long now = SystemClock.uptimeMillis(); 8984 for (Map.Entry<String, SparseArray<Long>> procs 8985 : mProcessCrashTimes.getMap().entrySet()) { 8986 String pname = procs.getKey(); 8987 SparseArray<Long> uids = procs.getValue(); 8988 final int N = uids.size(); 8989 for (int i=0; i<N; i++) { 8990 int puid = uids.keyAt(i); 8991 ProcessRecord r = mProcessNames.get(pname, puid); 8992 if (dumpPackage != null && (r == null 8993 || !dumpPackage.equals(r.info.packageName))) { 8994 continue; 8995 } 8996 if (!printed) { 8997 if (needSep) pw.println(" "); 8998 needSep = true; 8999 pw.println(" Time since processes crashed:"); 9000 printed = true; 9001 } 9002 pw.print(" Process "); pw.print(pname); 9003 pw.print(" uid "); pw.print(puid); 9004 pw.print(": last crashed "); 9005 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9006 pw.println(" ago"); 9007 } 9008 } 9009 } 9010 9011 if (mBadProcesses.getMap().size() > 0) { 9012 boolean printed = false; 9013 for (Map.Entry<String, SparseArray<Long>> procs 9014 : mBadProcesses.getMap().entrySet()) { 9015 String pname = procs.getKey(); 9016 SparseArray<Long> uids = procs.getValue(); 9017 final int N = uids.size(); 9018 for (int i=0; i<N; i++) { 9019 int puid = uids.keyAt(i); 9020 ProcessRecord r = mProcessNames.get(pname, puid); 9021 if (dumpPackage != null && (r == null 9022 || !dumpPackage.equals(r.info.packageName))) { 9023 continue; 9024 } 9025 if (!printed) { 9026 if (needSep) pw.println(" "); 9027 needSep = true; 9028 pw.println(" Bad processes:"); 9029 } 9030 pw.print(" Bad process "); pw.print(pname); 9031 pw.print(" uid "); pw.print(puid); 9032 pw.print(": crashed at time "); 9033 pw.println(uids.valueAt(i)); 9034 } 9035 } 9036 } 9037 9038 pw.println(); 9039 pw.println(" mHomeProcess: " + mHomeProcess); 9040 pw.println(" mPreviousProcess: " + mPreviousProcess); 9041 if (dumpAll) { 9042 StringBuilder sb = new StringBuilder(128); 9043 sb.append(" mPreviousProcessVisibleTime: "); 9044 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9045 pw.println(sb); 9046 } 9047 if (mHeavyWeightProcess != null) { 9048 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9049 } 9050 pw.println(" mConfiguration: " + mConfiguration); 9051 if (dumpAll) { 9052 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9053 if (mCompatModePackages.getPackages().size() > 0) { 9054 boolean printed = false; 9055 for (Map.Entry<String, Integer> entry 9056 : mCompatModePackages.getPackages().entrySet()) { 9057 String pkg = entry.getKey(); 9058 int mode = entry.getValue(); 9059 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9060 continue; 9061 } 9062 if (!printed) { 9063 pw.println(" mScreenCompatPackages:"); 9064 printed = true; 9065 } 9066 pw.print(" "); pw.print(pkg); pw.print(": "); 9067 pw.print(mode); pw.println(); 9068 } 9069 } 9070 } 9071 if (mSleeping || mWentToSleep || mLockScreenShown) { 9072 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9073 + " mLockScreenShown " + mLockScreenShown); 9074 } 9075 if (mShuttingDown) { 9076 pw.println(" mShuttingDown=" + mShuttingDown); 9077 } 9078 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9079 || mOrigWaitForDebugger) { 9080 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9081 + " mDebugTransient=" + mDebugTransient 9082 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9083 } 9084 if (mOpenGlTraceApp != null) { 9085 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9086 } 9087 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9088 || mProfileFd != null) { 9089 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9090 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9091 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9092 + mAutoStopProfiler); 9093 } 9094 if (mAlwaysFinishActivities || mController != null) { 9095 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9096 + " mController=" + mController); 9097 } 9098 if (dumpAll) { 9099 pw.println(" Total persistent processes: " + numPers); 9100 pw.println(" mStartRunning=" + mStartRunning 9101 + " mProcessesReady=" + mProcessesReady 9102 + " mSystemReady=" + mSystemReady); 9103 pw.println(" mBooting=" + mBooting 9104 + " mBooted=" + mBooted 9105 + " mFactoryTest=" + mFactoryTest); 9106 pw.print(" mLastPowerCheckRealtime="); 9107 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9108 pw.println(""); 9109 pw.print(" mLastPowerCheckUptime="); 9110 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9111 pw.println(""); 9112 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9113 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9114 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9115 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9116 + " mNumHiddenProcs=" + mNumHiddenProcs 9117 + " mNumServiceProcs=" + mNumServiceProcs 9118 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9119 } 9120 9121 return true; 9122 } 9123 9124 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9125 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9126 if (mProcessesToGc.size() > 0) { 9127 boolean printed = false; 9128 long now = SystemClock.uptimeMillis(); 9129 for (int i=0; i<mProcessesToGc.size(); i++) { 9130 ProcessRecord proc = mProcessesToGc.get(i); 9131 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9132 continue; 9133 } 9134 if (!printed) { 9135 if (needSep) pw.println(" "); 9136 needSep = true; 9137 pw.println(" Processes that are waiting to GC:"); 9138 printed = true; 9139 } 9140 pw.print(" Process "); pw.println(proc); 9141 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9142 pw.print(", last gced="); 9143 pw.print(now-proc.lastRequestedGc); 9144 pw.print(" ms ago, last lowMem="); 9145 pw.print(now-proc.lastLowMemory); 9146 pw.println(" ms ago"); 9147 9148 } 9149 } 9150 return needSep; 9151 } 9152 9153 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9154 int opti, boolean dumpAll) { 9155 boolean needSep = false; 9156 9157 if (mLruProcesses.size() > 0) { 9158 if (needSep) pw.println(" "); 9159 needSep = true; 9160 pw.println(" OOM levels:"); 9161 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9162 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9163 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9164 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9165 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9166 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9167 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9168 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9169 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9170 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9171 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9172 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9173 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9174 9175 if (needSep) pw.println(" "); 9176 needSep = true; 9177 pw.println(" Process OOM control:"); 9178 dumpProcessOomList(pw, this, mLruProcesses, " ", 9179 "Proc", "PERS", true, null); 9180 needSep = true; 9181 } 9182 9183 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9184 9185 pw.println(); 9186 pw.println(" mHomeProcess: " + mHomeProcess); 9187 pw.println(" mPreviousProcess: " + mPreviousProcess); 9188 if (mHeavyWeightProcess != null) { 9189 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9190 } 9191 9192 return true; 9193 } 9194 9195 /** 9196 * There are three ways to call this: 9197 * - no provider specified: dump all the providers 9198 * - a flattened component name that matched an existing provider was specified as the 9199 * first arg: dump that one provider 9200 * - the first arg isn't the flattened component name of an existing provider: 9201 * dump all providers whose component contains the first arg as a substring 9202 */ 9203 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9204 int opti, boolean dumpAll) { 9205 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9206 } 9207 9208 static class ItemMatcher { 9209 ArrayList<ComponentName> components; 9210 ArrayList<String> strings; 9211 ArrayList<Integer> objects; 9212 boolean all; 9213 9214 ItemMatcher() { 9215 all = true; 9216 } 9217 9218 void build(String name) { 9219 ComponentName componentName = ComponentName.unflattenFromString(name); 9220 if (componentName != null) { 9221 if (components == null) { 9222 components = new ArrayList<ComponentName>(); 9223 } 9224 components.add(componentName); 9225 all = false; 9226 } else { 9227 int objectId = 0; 9228 // Not a '/' separated full component name; maybe an object ID? 9229 try { 9230 objectId = Integer.parseInt(name, 16); 9231 if (objects == null) { 9232 objects = new ArrayList<Integer>(); 9233 } 9234 objects.add(objectId); 9235 all = false; 9236 } catch (RuntimeException e) { 9237 // Not an integer; just do string match. 9238 if (strings == null) { 9239 strings = new ArrayList<String>(); 9240 } 9241 strings.add(name); 9242 all = false; 9243 } 9244 } 9245 } 9246 9247 int build(String[] args, int opti) { 9248 for (; opti<args.length; opti++) { 9249 String name = args[opti]; 9250 if ("--".equals(name)) { 9251 return opti+1; 9252 } 9253 build(name); 9254 } 9255 return opti; 9256 } 9257 9258 boolean match(Object object, ComponentName comp) { 9259 if (all) { 9260 return true; 9261 } 9262 if (components != null) { 9263 for (int i=0; i<components.size(); i++) { 9264 if (components.get(i).equals(comp)) { 9265 return true; 9266 } 9267 } 9268 } 9269 if (objects != null) { 9270 for (int i=0; i<objects.size(); i++) { 9271 if (System.identityHashCode(object) == objects.get(i)) { 9272 return true; 9273 } 9274 } 9275 } 9276 if (strings != null) { 9277 String flat = comp.flattenToString(); 9278 for (int i=0; i<strings.size(); i++) { 9279 if (flat.contains(strings.get(i))) { 9280 return true; 9281 } 9282 } 9283 } 9284 return false; 9285 } 9286 } 9287 9288 /** 9289 * There are three things that cmd can be: 9290 * - a flattened component name that matches an existing activity 9291 * - the cmd arg isn't the flattened component name of an existing activity: 9292 * dump all activity whose component contains the cmd as a substring 9293 * - A hex number of the ActivityRecord object instance. 9294 */ 9295 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9296 int opti, boolean dumpAll) { 9297 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9298 9299 if ("all".equals(name)) { 9300 synchronized (this) { 9301 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9302 activities.add(r1); 9303 } 9304 } 9305 } else if ("top".equals(name)) { 9306 synchronized (this) { 9307 final int N = mMainStack.mHistory.size(); 9308 if (N > 0) { 9309 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9310 } 9311 } 9312 } else { 9313 ItemMatcher matcher = new ItemMatcher(); 9314 matcher.build(name); 9315 9316 synchronized (this) { 9317 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9318 if (matcher.match(r1, r1.intent.getComponent())) { 9319 activities.add(r1); 9320 } 9321 } 9322 } 9323 } 9324 9325 if (activities.size() <= 0) { 9326 return false; 9327 } 9328 9329 String[] newArgs = new String[args.length - opti]; 9330 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9331 9332 TaskRecord lastTask = null; 9333 boolean needSep = false; 9334 for (int i=activities.size()-1; i>=0; i--) { 9335 ActivityRecord r = (ActivityRecord)activities.get(i); 9336 if (needSep) { 9337 pw.println(); 9338 } 9339 needSep = true; 9340 synchronized (this) { 9341 if (lastTask != r.task) { 9342 lastTask = r.task; 9343 pw.print("TASK "); pw.print(lastTask.affinity); 9344 pw.print(" id="); pw.println(lastTask.taskId); 9345 if (dumpAll) { 9346 lastTask.dump(pw, " "); 9347 } 9348 } 9349 } 9350 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9351 } 9352 return true; 9353 } 9354 9355 /** 9356 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9357 * there is a thread associated with the activity. 9358 */ 9359 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9360 final ActivityRecord r, String[] args, boolean dumpAll) { 9361 String innerPrefix = prefix + " "; 9362 synchronized (this) { 9363 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9364 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9365 pw.print(" pid="); 9366 if (r.app != null) pw.println(r.app.pid); 9367 else pw.println("(not running)"); 9368 if (dumpAll) { 9369 r.dump(pw, innerPrefix); 9370 } 9371 } 9372 if (r.app != null && r.app.thread != null) { 9373 // flush anything that is already in the PrintWriter since the thread is going 9374 // to write to the file descriptor directly 9375 pw.flush(); 9376 try { 9377 TransferPipe tp = new TransferPipe(); 9378 try { 9379 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9380 r.appToken, innerPrefix, args); 9381 tp.go(fd); 9382 } finally { 9383 tp.kill(); 9384 } 9385 } catch (IOException e) { 9386 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9387 } catch (RemoteException e) { 9388 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9389 } 9390 } 9391 } 9392 9393 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9394 int opti, boolean dumpAll, String dumpPackage) { 9395 boolean needSep = false; 9396 9397 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9398 if (dumpAll) { 9399 if (mRegisteredReceivers.size() > 0) { 9400 boolean printed = false; 9401 Iterator it = mRegisteredReceivers.values().iterator(); 9402 while (it.hasNext()) { 9403 ReceiverList r = (ReceiverList)it.next(); 9404 if (dumpPackage != null && (r.app == null || 9405 !dumpPackage.equals(r.app.info.packageName))) { 9406 continue; 9407 } 9408 if (!printed) { 9409 pw.println(" Registered Receivers:"); 9410 needSep = true; 9411 printed = true; 9412 } 9413 pw.print(" * "); pw.println(r); 9414 r.dump(pw, " "); 9415 } 9416 } 9417 9418 if (mReceiverResolver.dump(pw, needSep ? 9419 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9420 " ", dumpPackage, false)) { 9421 needSep = true; 9422 } 9423 } 9424 9425 for (BroadcastQueue q : mBroadcastQueues) { 9426 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9427 } 9428 9429 needSep = true; 9430 9431 if (mStickyBroadcasts != null && dumpPackage == null) { 9432 if (needSep) { 9433 pw.println(); 9434 } 9435 needSep = true; 9436 pw.println(" Sticky broadcasts:"); 9437 StringBuilder sb = new StringBuilder(128); 9438 for (Map.Entry<String, ArrayList<Intent>> ent 9439 : mStickyBroadcasts.entrySet()) { 9440 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9441 if (dumpAll) { 9442 pw.println(":"); 9443 ArrayList<Intent> intents = ent.getValue(); 9444 final int N = intents.size(); 9445 for (int i=0; i<N; i++) { 9446 sb.setLength(0); 9447 sb.append(" Intent: "); 9448 intents.get(i).toShortString(sb, false, true, false, false); 9449 pw.println(sb.toString()); 9450 Bundle bundle = intents.get(i).getExtras(); 9451 if (bundle != null) { 9452 pw.print(" "); 9453 pw.println(bundle.toString()); 9454 } 9455 } 9456 } else { 9457 pw.println(""); 9458 } 9459 } 9460 needSep = true; 9461 } 9462 9463 if (dumpAll) { 9464 pw.println(); 9465 for (BroadcastQueue queue : mBroadcastQueues) { 9466 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9467 + queue.mBroadcastsScheduled); 9468 } 9469 pw.println(" mHandler:"); 9470 mHandler.dump(new PrintWriterPrinter(pw), " "); 9471 needSep = true; 9472 } 9473 9474 return needSep; 9475 } 9476 9477 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9478 int opti, boolean dumpAll, String dumpPackage) { 9479 boolean needSep = true; 9480 9481 ItemMatcher matcher = new ItemMatcher(); 9482 matcher.build(args, opti); 9483 9484 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9485 9486 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9487 9488 if (mLaunchingProviders.size() > 0) { 9489 boolean printed = false; 9490 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9491 ContentProviderRecord r = mLaunchingProviders.get(i); 9492 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9493 continue; 9494 } 9495 if (!printed) { 9496 if (needSep) pw.println(" "); 9497 needSep = true; 9498 pw.println(" Launching content providers:"); 9499 printed = true; 9500 } 9501 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9502 pw.println(r); 9503 } 9504 } 9505 9506 if (mGrantedUriPermissions.size() > 0) { 9507 if (needSep) pw.println(); 9508 needSep = true; 9509 pw.println("Granted Uri Permissions:"); 9510 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9511 int uid = mGrantedUriPermissions.keyAt(i); 9512 HashMap<Uri, UriPermission> perms 9513 = mGrantedUriPermissions.valueAt(i); 9514 pw.print(" * UID "); pw.print(uid); 9515 pw.println(" holds:"); 9516 for (UriPermission perm : perms.values()) { 9517 pw.print(" "); pw.println(perm); 9518 if (dumpAll) { 9519 perm.dump(pw, " "); 9520 } 9521 } 9522 } 9523 needSep = true; 9524 } 9525 9526 return needSep; 9527 } 9528 9529 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9530 int opti, boolean dumpAll, String dumpPackage) { 9531 boolean needSep = false; 9532 9533 if (mIntentSenderRecords.size() > 0) { 9534 boolean printed = false; 9535 Iterator<WeakReference<PendingIntentRecord>> it 9536 = mIntentSenderRecords.values().iterator(); 9537 while (it.hasNext()) { 9538 WeakReference<PendingIntentRecord> ref = it.next(); 9539 PendingIntentRecord rec = ref != null ? ref.get(): null; 9540 if (dumpPackage != null && (rec == null 9541 || !dumpPackage.equals(rec.key.packageName))) { 9542 continue; 9543 } 9544 if (!printed) { 9545 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9546 printed = true; 9547 } 9548 needSep = true; 9549 if (rec != null) { 9550 pw.print(" * "); pw.println(rec); 9551 if (dumpAll) { 9552 rec.dump(pw, " "); 9553 } 9554 } else { 9555 pw.print(" * "); pw.println(ref); 9556 } 9557 } 9558 } 9559 9560 return needSep; 9561 } 9562 9563 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9564 String prefix, String label, boolean complete, boolean brief, boolean client, 9565 String dumpPackage) { 9566 TaskRecord lastTask = null; 9567 boolean needNL = false; 9568 final String innerPrefix = prefix + " "; 9569 final String[] args = new String[0]; 9570 for (int i=list.size()-1; i>=0; i--) { 9571 final ActivityRecord r = (ActivityRecord)list.get(i); 9572 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9573 continue; 9574 } 9575 final boolean full = !brief && (complete || !r.isInHistory()); 9576 if (needNL) { 9577 pw.println(" "); 9578 needNL = false; 9579 } 9580 if (lastTask != r.task) { 9581 lastTask = r.task; 9582 pw.print(prefix); 9583 pw.print(full ? "* " : " "); 9584 pw.println(lastTask); 9585 if (full) { 9586 lastTask.dump(pw, prefix + " "); 9587 } else if (complete) { 9588 // Complete + brief == give a summary. Isn't that obvious?!? 9589 if (lastTask.intent != null) { 9590 pw.print(prefix); pw.print(" "); 9591 pw.println(lastTask.intent.toInsecureStringWithClip()); 9592 } 9593 } 9594 } 9595 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9596 pw.print(" #"); pw.print(i); pw.print(": "); 9597 pw.println(r); 9598 if (full) { 9599 r.dump(pw, innerPrefix); 9600 } else if (complete) { 9601 // Complete + brief == give a summary. Isn't that obvious?!? 9602 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9603 if (r.app != null) { 9604 pw.print(innerPrefix); pw.println(r.app); 9605 } 9606 } 9607 if (client && r.app != null && r.app.thread != null) { 9608 // flush anything that is already in the PrintWriter since the thread is going 9609 // to write to the file descriptor directly 9610 pw.flush(); 9611 try { 9612 TransferPipe tp = new TransferPipe(); 9613 try { 9614 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9615 r.appToken, innerPrefix, args); 9616 // Short timeout, since blocking here can 9617 // deadlock with the application. 9618 tp.go(fd, 2000); 9619 } finally { 9620 tp.kill(); 9621 } 9622 } catch (IOException e) { 9623 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9624 } catch (RemoteException e) { 9625 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9626 } 9627 needNL = true; 9628 } 9629 } 9630 } 9631 9632 private static String buildOomTag(String prefix, String space, int val, int base) { 9633 if (val == base) { 9634 if (space == null) return prefix; 9635 return prefix + " "; 9636 } 9637 return prefix + "+" + Integer.toString(val-base); 9638 } 9639 9640 private static final int dumpProcessList(PrintWriter pw, 9641 ActivityManagerService service, List list, 9642 String prefix, String normalLabel, String persistentLabel, 9643 String dumpPackage) { 9644 int numPers = 0; 9645 final int N = list.size()-1; 9646 for (int i=N; i>=0; i--) { 9647 ProcessRecord r = (ProcessRecord)list.get(i); 9648 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9649 continue; 9650 } 9651 pw.println(String.format("%s%s #%2d: %s", 9652 prefix, (r.persistent ? persistentLabel : normalLabel), 9653 i, r.toString())); 9654 if (r.persistent) { 9655 numPers++; 9656 } 9657 } 9658 return numPers; 9659 } 9660 9661 private static final boolean dumpProcessOomList(PrintWriter pw, 9662 ActivityManagerService service, List<ProcessRecord> origList, 9663 String prefix, String normalLabel, String persistentLabel, 9664 boolean inclDetails, String dumpPackage) { 9665 9666 ArrayList<Pair<ProcessRecord, Integer>> list 9667 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9668 for (int i=0; i<origList.size(); i++) { 9669 ProcessRecord r = origList.get(i); 9670 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9671 continue; 9672 } 9673 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9674 } 9675 9676 if (list.size() <= 0) { 9677 return false; 9678 } 9679 9680 Comparator<Pair<ProcessRecord, Integer>> comparator 9681 = new Comparator<Pair<ProcessRecord, Integer>>() { 9682 @Override 9683 public int compare(Pair<ProcessRecord, Integer> object1, 9684 Pair<ProcessRecord, Integer> object2) { 9685 if (object1.first.setAdj != object2.first.setAdj) { 9686 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9687 } 9688 if (object1.second.intValue() != object2.second.intValue()) { 9689 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9690 } 9691 return 0; 9692 } 9693 }; 9694 9695 Collections.sort(list, comparator); 9696 9697 final long curRealtime = SystemClock.elapsedRealtime(); 9698 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9699 final long curUptime = SystemClock.uptimeMillis(); 9700 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9701 9702 for (int i=list.size()-1; i>=0; i--) { 9703 ProcessRecord r = list.get(i).first; 9704 String oomAdj; 9705 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9706 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9707 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9708 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9709 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9710 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9711 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9712 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9713 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9714 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9715 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9716 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9717 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9718 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9719 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9720 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9721 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9722 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9723 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9724 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9725 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9726 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9727 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9728 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9729 } else { 9730 oomAdj = Integer.toString(r.setAdj); 9731 } 9732 String schedGroup; 9733 switch (r.setSchedGroup) { 9734 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9735 schedGroup = "B"; 9736 break; 9737 case Process.THREAD_GROUP_DEFAULT: 9738 schedGroup = "F"; 9739 break; 9740 default: 9741 schedGroup = Integer.toString(r.setSchedGroup); 9742 break; 9743 } 9744 String foreground; 9745 if (r.foregroundActivities) { 9746 foreground = "A"; 9747 } else if (r.foregroundServices) { 9748 foreground = "S"; 9749 } else { 9750 foreground = " "; 9751 } 9752 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9753 prefix, (r.persistent ? persistentLabel : normalLabel), 9754 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9755 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9756 if (r.adjSource != null || r.adjTarget != null) { 9757 pw.print(prefix); 9758 pw.print(" "); 9759 if (r.adjTarget instanceof ComponentName) { 9760 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9761 } else if (r.adjTarget != null) { 9762 pw.print(r.adjTarget.toString()); 9763 } else { 9764 pw.print("{null}"); 9765 } 9766 pw.print("<="); 9767 if (r.adjSource instanceof ProcessRecord) { 9768 pw.print("Proc{"); 9769 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9770 pw.println("}"); 9771 } else if (r.adjSource != null) { 9772 pw.println(r.adjSource.toString()); 9773 } else { 9774 pw.println("{null}"); 9775 } 9776 } 9777 if (inclDetails) { 9778 pw.print(prefix); 9779 pw.print(" "); 9780 pw.print("oom: max="); pw.print(r.maxAdj); 9781 pw.print(" hidden="); pw.print(r.hiddenAdj); 9782 pw.print(" empty="); pw.print(r.emptyAdj); 9783 pw.print(" curRaw="); pw.print(r.curRawAdj); 9784 pw.print(" setRaw="); pw.print(r.setRawAdj); 9785 pw.print(" cur="); pw.print(r.curAdj); 9786 pw.print(" set="); pw.println(r.setAdj); 9787 pw.print(prefix); 9788 pw.print(" "); 9789 pw.print("keeping="); pw.print(r.keeping); 9790 pw.print(" hidden="); pw.print(r.hidden); 9791 pw.print(" empty="); pw.print(r.empty); 9792 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9793 9794 if (!r.keeping) { 9795 if (r.lastWakeTime != 0) { 9796 long wtime; 9797 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9798 synchronized (stats) { 9799 wtime = stats.getProcessWakeTime(r.info.uid, 9800 r.pid, curRealtime); 9801 } 9802 long timeUsed = wtime - r.lastWakeTime; 9803 pw.print(prefix); 9804 pw.print(" "); 9805 pw.print("keep awake over "); 9806 TimeUtils.formatDuration(realtimeSince, pw); 9807 pw.print(" used "); 9808 TimeUtils.formatDuration(timeUsed, pw); 9809 pw.print(" ("); 9810 pw.print((timeUsed*100)/realtimeSince); 9811 pw.println("%)"); 9812 } 9813 if (r.lastCpuTime != 0) { 9814 long timeUsed = r.curCpuTime - r.lastCpuTime; 9815 pw.print(prefix); 9816 pw.print(" "); 9817 pw.print("run cpu over "); 9818 TimeUtils.formatDuration(uptimeSince, pw); 9819 pw.print(" used "); 9820 TimeUtils.formatDuration(timeUsed, pw); 9821 pw.print(" ("); 9822 pw.print((timeUsed*100)/uptimeSince); 9823 pw.println("%)"); 9824 } 9825 } 9826 } 9827 } 9828 return true; 9829 } 9830 9831 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9832 ArrayList<ProcessRecord> procs; 9833 synchronized (this) { 9834 if (args != null && args.length > start 9835 && args[start].charAt(0) != '-') { 9836 procs = new ArrayList<ProcessRecord>(); 9837 int pid = -1; 9838 try { 9839 pid = Integer.parseInt(args[start]); 9840 } catch (NumberFormatException e) { 9841 9842 } 9843 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9844 ProcessRecord proc = mLruProcesses.get(i); 9845 if (proc.pid == pid) { 9846 procs.add(proc); 9847 } else if (proc.processName.equals(args[start])) { 9848 procs.add(proc); 9849 } 9850 } 9851 if (procs.size() <= 0) { 9852 pw.println("No process found for: " + args[start]); 9853 return null; 9854 } 9855 } else { 9856 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9857 } 9858 } 9859 return procs; 9860 } 9861 9862 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9863 PrintWriter pw, String[] args) { 9864 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9865 if (procs == null) { 9866 return; 9867 } 9868 9869 long uptime = SystemClock.uptimeMillis(); 9870 long realtime = SystemClock.elapsedRealtime(); 9871 pw.println("Applications Graphics Acceleration Info:"); 9872 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9873 9874 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9875 ProcessRecord r = procs.get(i); 9876 if (r.thread != null) { 9877 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9878 pw.flush(); 9879 try { 9880 TransferPipe tp = new TransferPipe(); 9881 try { 9882 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9883 tp.go(fd); 9884 } finally { 9885 tp.kill(); 9886 } 9887 } catch (IOException e) { 9888 pw.println("Failure while dumping the app: " + r); 9889 pw.flush(); 9890 } catch (RemoteException e) { 9891 pw.println("Got a RemoteException while dumping the app " + r); 9892 pw.flush(); 9893 } 9894 } 9895 } 9896 } 9897 9898 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9899 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9900 if (procs == null) { 9901 return; 9902 } 9903 9904 pw.println("Applications Database Info:"); 9905 9906 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9907 ProcessRecord r = procs.get(i); 9908 if (r.thread != null) { 9909 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9910 pw.flush(); 9911 try { 9912 TransferPipe tp = new TransferPipe(); 9913 try { 9914 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9915 tp.go(fd); 9916 } finally { 9917 tp.kill(); 9918 } 9919 } catch (IOException e) { 9920 pw.println("Failure while dumping the app: " + r); 9921 pw.flush(); 9922 } catch (RemoteException e) { 9923 pw.println("Got a RemoteException while dumping the app " + r); 9924 pw.flush(); 9925 } 9926 } 9927 } 9928 } 9929 9930 final static class MemItem { 9931 final String label; 9932 final String shortLabel; 9933 final long pss; 9934 final int id; 9935 ArrayList<MemItem> subitems; 9936 9937 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9938 label = _label; 9939 shortLabel = _shortLabel; 9940 pss = _pss; 9941 id = _id; 9942 } 9943 } 9944 9945 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9946 boolean sort) { 9947 if (sort) { 9948 Collections.sort(items, new Comparator<MemItem>() { 9949 @Override 9950 public int compare(MemItem lhs, MemItem rhs) { 9951 if (lhs.pss < rhs.pss) { 9952 return 1; 9953 } else if (lhs.pss > rhs.pss) { 9954 return -1; 9955 } 9956 return 0; 9957 } 9958 }); 9959 } 9960 9961 for (int i=0; i<items.size(); i++) { 9962 MemItem mi = items.get(i); 9963 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9964 if (mi.subitems != null) { 9965 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9966 } 9967 } 9968 } 9969 9970 // These are in KB. 9971 static final long[] DUMP_MEM_BUCKETS = new long[] { 9972 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9973 120*1024, 160*1024, 200*1024, 9974 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9975 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9976 }; 9977 9978 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9979 boolean stackLike) { 9980 int start = label.lastIndexOf('.'); 9981 if (start >= 0) start++; 9982 else start = 0; 9983 int end = label.length(); 9984 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9985 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9986 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9987 out.append(bucket); 9988 out.append(stackLike ? "MB." : "MB "); 9989 out.append(label, start, end); 9990 return; 9991 } 9992 } 9993 out.append(memKB/1024); 9994 out.append(stackLike ? "MB." : "MB "); 9995 out.append(label, start, end); 9996 } 9997 9998 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9999 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10000 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10001 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10002 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10003 }; 10004 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10005 "System", "Persistent", "Foreground", 10006 "Visible", "Perceptible", "Heavy Weight", 10007 "Backup", "A Services", "Home", "Previous", 10008 "B Services", "Background" 10009 }; 10010 10011 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10012 PrintWriter pw, String prefix, String[] args, boolean brief, 10013 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10014 boolean dumpAll = false; 10015 boolean oomOnly = false; 10016 10017 int opti = 0; 10018 while (opti < args.length) { 10019 String opt = args[opti]; 10020 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10021 break; 10022 } 10023 opti++; 10024 if ("-a".equals(opt)) { 10025 dumpAll = true; 10026 } else if ("--oom".equals(opt)) { 10027 oomOnly = true; 10028 } else if ("-h".equals(opt)) { 10029 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10030 pw.println(" -a: include all available information for each process."); 10031 pw.println(" --oom: only show processes organized by oom adj."); 10032 pw.println("If [process] is specified it can be the name or "); 10033 pw.println("pid of a specific process to dump."); 10034 return; 10035 } else { 10036 pw.println("Unknown argument: " + opt + "; use -h for help"); 10037 } 10038 } 10039 10040 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10041 if (procs == null) { 10042 return; 10043 } 10044 10045 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10046 long uptime = SystemClock.uptimeMillis(); 10047 long realtime = SystemClock.elapsedRealtime(); 10048 10049 if (procs.size() == 1 || isCheckinRequest) { 10050 dumpAll = true; 10051 } 10052 10053 if (isCheckinRequest) { 10054 // short checkin version 10055 pw.println(uptime + "," + realtime); 10056 pw.flush(); 10057 } else { 10058 pw.println("Applications Memory Usage (kB):"); 10059 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10060 } 10061 10062 String[] innerArgs = new String[args.length-opti]; 10063 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10064 10065 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10066 long nativePss=0, dalvikPss=0, otherPss=0; 10067 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10068 10069 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10070 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10071 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10072 10073 long totalPss = 0; 10074 10075 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10076 ProcessRecord r = procs.get(i); 10077 if (r.thread != null) { 10078 if (!isCheckinRequest && dumpAll) { 10079 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10080 pw.flush(); 10081 } 10082 Debug.MemoryInfo mi = null; 10083 if (dumpAll) { 10084 try { 10085 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10086 } catch (RemoteException e) { 10087 if (!isCheckinRequest) { 10088 pw.println("Got RemoteException!"); 10089 pw.flush(); 10090 } 10091 } 10092 } else { 10093 mi = new Debug.MemoryInfo(); 10094 Debug.getMemoryInfo(r.pid, mi); 10095 } 10096 10097 if (!isCheckinRequest && mi != null) { 10098 long myTotalPss = mi.getTotalPss(); 10099 totalPss += myTotalPss; 10100 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10101 r.processName, myTotalPss, 0); 10102 procMems.add(pssItem); 10103 10104 nativePss += mi.nativePss; 10105 dalvikPss += mi.dalvikPss; 10106 otherPss += mi.otherPss; 10107 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10108 long mem = mi.getOtherPss(j); 10109 miscPss[j] += mem; 10110 otherPss -= mem; 10111 } 10112 10113 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10114 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10115 || oomIndex == (oomPss.length-1)) { 10116 oomPss[oomIndex] += myTotalPss; 10117 if (oomProcs[oomIndex] == null) { 10118 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10119 } 10120 oomProcs[oomIndex].add(pssItem); 10121 break; 10122 } 10123 } 10124 } 10125 } 10126 } 10127 10128 if (!isCheckinRequest && procs.size() > 1) { 10129 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10130 10131 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10132 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10133 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10134 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10135 String label = Debug.MemoryInfo.getOtherLabel(j); 10136 catMems.add(new MemItem(label, label, miscPss[j], j)); 10137 } 10138 10139 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10140 for (int j=0; j<oomPss.length; j++) { 10141 if (oomPss[j] != 0) { 10142 String label = DUMP_MEM_OOM_LABEL[j]; 10143 MemItem item = new MemItem(label, label, oomPss[j], 10144 DUMP_MEM_OOM_ADJ[j]); 10145 item.subitems = oomProcs[j]; 10146 oomMems.add(item); 10147 } 10148 } 10149 10150 if (outTag != null || outStack != null) { 10151 if (outTag != null) { 10152 appendMemBucket(outTag, totalPss, "total", false); 10153 } 10154 if (outStack != null) { 10155 appendMemBucket(outStack, totalPss, "total", true); 10156 } 10157 boolean firstLine = true; 10158 for (int i=0; i<oomMems.size(); i++) { 10159 MemItem miCat = oomMems.get(i); 10160 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10161 continue; 10162 } 10163 if (miCat.id < ProcessList.SERVICE_ADJ 10164 || miCat.id == ProcessList.HOME_APP_ADJ 10165 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10166 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10167 outTag.append(" / "); 10168 } 10169 if (outStack != null) { 10170 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10171 if (firstLine) { 10172 outStack.append(":"); 10173 firstLine = false; 10174 } 10175 outStack.append("\n\t at "); 10176 } else { 10177 outStack.append("$"); 10178 } 10179 } 10180 for (int j=0; j<miCat.subitems.size(); j++) { 10181 MemItem mi = miCat.subitems.get(j); 10182 if (j > 0) { 10183 if (outTag != null) { 10184 outTag.append(" "); 10185 } 10186 if (outStack != null) { 10187 outStack.append("$"); 10188 } 10189 } 10190 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10191 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10192 } 10193 if (outStack != null) { 10194 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10195 } 10196 } 10197 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10198 outStack.append("("); 10199 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10200 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10201 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10202 outStack.append(":"); 10203 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10204 } 10205 } 10206 outStack.append(")"); 10207 } 10208 } 10209 } 10210 } 10211 10212 if (!brief && !oomOnly) { 10213 pw.println(); 10214 pw.println("Total PSS by process:"); 10215 dumpMemItems(pw, " ", procMems, true); 10216 pw.println(); 10217 } 10218 pw.println("Total PSS by OOM adjustment:"); 10219 dumpMemItems(pw, " ", oomMems, false); 10220 if (!oomOnly) { 10221 PrintWriter out = categoryPw != null ? categoryPw : pw; 10222 out.println(); 10223 out.println("Total PSS by category:"); 10224 dumpMemItems(out, " ", catMems, true); 10225 } 10226 pw.println(); 10227 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10228 final int[] SINGLE_LONG_FORMAT = new int[] { 10229 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10230 }; 10231 long[] longOut = new long[1]; 10232 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10233 SINGLE_LONG_FORMAT, null, longOut, null); 10234 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10235 longOut[0] = 0; 10236 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10237 SINGLE_LONG_FORMAT, null, longOut, null); 10238 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10239 longOut[0] = 0; 10240 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10241 SINGLE_LONG_FORMAT, null, longOut, null); 10242 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10243 longOut[0] = 0; 10244 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10245 SINGLE_LONG_FORMAT, null, longOut, null); 10246 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10247 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10248 pw.print(shared); pw.println(" kB"); 10249 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10250 pw.print(voltile); pw.println(" kB volatile"); 10251 } 10252 } 10253 10254 /** 10255 * Searches array of arguments for the specified string 10256 * @param args array of argument strings 10257 * @param value value to search for 10258 * @return true if the value is contained in the array 10259 */ 10260 private static boolean scanArgs(String[] args, String value) { 10261 if (args != null) { 10262 for (String arg : args) { 10263 if (value.equals(arg)) { 10264 return true; 10265 } 10266 } 10267 } 10268 return false; 10269 } 10270 10271 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10272 ContentProviderRecord cpr, boolean always) { 10273 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10274 10275 if (!inLaunching || always) { 10276 synchronized (cpr) { 10277 cpr.launchingApp = null; 10278 cpr.notifyAll(); 10279 } 10280 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10281 String names[] = cpr.info.authority.split(";"); 10282 for (int j = 0; j < names.length; j++) { 10283 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10284 } 10285 } 10286 10287 for (int i=0; i<cpr.connections.size(); i++) { 10288 ContentProviderConnection conn = cpr.connections.get(i); 10289 if (conn.waiting) { 10290 // If this connection is waiting for the provider, then we don't 10291 // need to mess with its process unless we are always removing 10292 // or for some reason the provider is not currently launching. 10293 if (inLaunching && !always) { 10294 continue; 10295 } 10296 } 10297 ProcessRecord capp = conn.client; 10298 conn.dead = true; 10299 if (conn.stableCount > 0) { 10300 if (!capp.persistent && capp.thread != null 10301 && capp.pid != 0 10302 && capp.pid != MY_PID) { 10303 Slog.i(TAG, "Kill " + capp.processName 10304 + " (pid " + capp.pid + "): provider " + cpr.info.name 10305 + " in dying process " + (proc != null ? proc.processName : "??")); 10306 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10307 capp.processName, capp.setAdj, "dying provider " 10308 + cpr.name.toShortString()); 10309 Process.killProcessQuiet(capp.pid); 10310 } 10311 } else if (capp.thread != null && conn.provider.provider != null) { 10312 try { 10313 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10314 } catch (RemoteException e) { 10315 } 10316 // In the protocol here, we don't expect the client to correctly 10317 // clean up this connection, we'll just remove it. 10318 cpr.connections.remove(i); 10319 conn.client.conProviders.remove(conn); 10320 } 10321 } 10322 10323 if (inLaunching && always) { 10324 mLaunchingProviders.remove(cpr); 10325 } 10326 return inLaunching; 10327 } 10328 10329 /** 10330 * Main code for cleaning up a process when it has gone away. This is 10331 * called both as a result of the process dying, or directly when stopping 10332 * a process when running in single process mode. 10333 */ 10334 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10335 boolean restarting, boolean allowRestart, int index) { 10336 if (index >= 0) { 10337 mLruProcesses.remove(index); 10338 } 10339 10340 mProcessesToGc.remove(app); 10341 10342 // Dismiss any open dialogs. 10343 if (app.crashDialog != null) { 10344 app.crashDialog.dismiss(); 10345 app.crashDialog = null; 10346 } 10347 if (app.anrDialog != null) { 10348 app.anrDialog.dismiss(); 10349 app.anrDialog = null; 10350 } 10351 if (app.waitDialog != null) { 10352 app.waitDialog.dismiss(); 10353 app.waitDialog = null; 10354 } 10355 10356 app.crashing = false; 10357 app.notResponding = false; 10358 10359 app.resetPackageList(); 10360 app.unlinkDeathRecipient(); 10361 app.thread = null; 10362 app.forcingToForeground = null; 10363 app.foregroundServices = false; 10364 app.foregroundActivities = false; 10365 app.hasShownUi = false; 10366 app.hasAboveClient = false; 10367 10368 mServices.killServicesLocked(app, allowRestart); 10369 10370 boolean restart = false; 10371 10372 // Remove published content providers. 10373 if (!app.pubProviders.isEmpty()) { 10374 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10375 while (it.hasNext()) { 10376 ContentProviderRecord cpr = it.next(); 10377 10378 final boolean always = app.bad || !allowRestart; 10379 if (removeDyingProviderLocked(app, cpr, always) || always) { 10380 // We left the provider in the launching list, need to 10381 // restart it. 10382 restart = true; 10383 } 10384 10385 cpr.provider = null; 10386 cpr.proc = null; 10387 } 10388 app.pubProviders.clear(); 10389 } 10390 10391 // Take care of any launching providers waiting for this process. 10392 if (checkAppInLaunchingProvidersLocked(app, false)) { 10393 restart = true; 10394 } 10395 10396 // Unregister from connected content providers. 10397 if (!app.conProviders.isEmpty()) { 10398 for (int i=0; i<app.conProviders.size(); i++) { 10399 ContentProviderConnection conn = app.conProviders.get(i); 10400 conn.provider.connections.remove(conn); 10401 } 10402 app.conProviders.clear(); 10403 } 10404 10405 // At this point there may be remaining entries in mLaunchingProviders 10406 // where we were the only one waiting, so they are no longer of use. 10407 // Look for these and clean up if found. 10408 // XXX Commented out for now. Trying to figure out a way to reproduce 10409 // the actual situation to identify what is actually going on. 10410 if (false) { 10411 for (int i=0; i<mLaunchingProviders.size(); i++) { 10412 ContentProviderRecord cpr = (ContentProviderRecord) 10413 mLaunchingProviders.get(i); 10414 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10415 synchronized (cpr) { 10416 cpr.launchingApp = null; 10417 cpr.notifyAll(); 10418 } 10419 } 10420 } 10421 } 10422 10423 skipCurrentReceiverLocked(app); 10424 10425 // Unregister any receivers. 10426 if (app.receivers.size() > 0) { 10427 Iterator<ReceiverList> it = app.receivers.iterator(); 10428 while (it.hasNext()) { 10429 removeReceiverLocked(it.next()); 10430 } 10431 app.receivers.clear(); 10432 } 10433 10434 // If the app is undergoing backup, tell the backup manager about it 10435 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10436 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10437 try { 10438 IBackupManager bm = IBackupManager.Stub.asInterface( 10439 ServiceManager.getService(Context.BACKUP_SERVICE)); 10440 bm.agentDisconnected(app.info.packageName); 10441 } catch (RemoteException e) { 10442 // can't happen; backup manager is local 10443 } 10444 } 10445 10446 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10447 ProcessChangeItem item = mPendingProcessChanges.get(i); 10448 if (item.pid == app.pid) { 10449 mPendingProcessChanges.remove(i); 10450 mAvailProcessChanges.add(item); 10451 } 10452 } 10453 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10454 10455 // If the caller is restarting this app, then leave it in its 10456 // current lists and let the caller take care of it. 10457 if (restarting) { 10458 return; 10459 } 10460 10461 if (!app.persistent || app.isolated) { 10462 if (DEBUG_PROCESSES) Slog.v(TAG, 10463 "Removing non-persistent process during cleanup: " + app); 10464 mProcessNames.remove(app.processName, app.uid); 10465 mIsolatedProcesses.remove(app.uid); 10466 if (mHeavyWeightProcess == app) { 10467 mHeavyWeightProcess = null; 10468 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10469 } 10470 } else if (!app.removed) { 10471 // This app is persistent, so we need to keep its record around. 10472 // If it is not already on the pending app list, add it there 10473 // and start a new process for it. 10474 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10475 mPersistentStartingProcesses.add(app); 10476 restart = true; 10477 } 10478 } 10479 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10480 "Clean-up removing on hold: " + app); 10481 mProcessesOnHold.remove(app); 10482 10483 if (app == mHomeProcess) { 10484 mHomeProcess = null; 10485 } 10486 if (app == mPreviousProcess) { 10487 mPreviousProcess = null; 10488 } 10489 10490 if (restart && !app.isolated) { 10491 // We have components that still need to be running in the 10492 // process, so re-launch it. 10493 mProcessNames.put(app.processName, app.uid, app); 10494 startProcessLocked(app, "restart", app.processName); 10495 } else if (app.pid > 0 && app.pid != MY_PID) { 10496 // Goodbye! 10497 synchronized (mPidsSelfLocked) { 10498 mPidsSelfLocked.remove(app.pid); 10499 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10500 } 10501 app.setPid(0); 10502 } 10503 } 10504 10505 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10506 // Look through the content providers we are waiting to have launched, 10507 // and if any run in this process then either schedule a restart of 10508 // the process or kill the client waiting for it if this process has 10509 // gone bad. 10510 int NL = mLaunchingProviders.size(); 10511 boolean restart = false; 10512 for (int i=0; i<NL; i++) { 10513 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10514 if (cpr.launchingApp == app) { 10515 if (!alwaysBad && !app.bad) { 10516 restart = true; 10517 } else { 10518 removeDyingProviderLocked(app, cpr, true); 10519 NL = mLaunchingProviders.size(); 10520 } 10521 } 10522 } 10523 return restart; 10524 } 10525 10526 // ========================================================= 10527 // SERVICES 10528 // ========================================================= 10529 10530 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10531 int flags) { 10532 enforceNotIsolatedCaller("getServices"); 10533 synchronized (this) { 10534 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10535 } 10536 } 10537 10538 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10539 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10540 synchronized (this) { 10541 return mServices.getRunningServiceControlPanelLocked(name); 10542 } 10543 } 10544 10545 public ComponentName startService(IApplicationThread caller, Intent service, 10546 String resolvedType) { 10547 enforceNotIsolatedCaller("startService"); 10548 // Refuse possible leaked file descriptors 10549 if (service != null && service.hasFileDescriptors() == true) { 10550 throw new IllegalArgumentException("File descriptors passed in Intent"); 10551 } 10552 10553 if (DEBUG_SERVICE) 10554 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10555 synchronized(this) { 10556 final int callingPid = Binder.getCallingPid(); 10557 final int callingUid = Binder.getCallingUid(); 10558 final long origId = Binder.clearCallingIdentity(); 10559 ComponentName res = mServices.startServiceLocked(caller, service, 10560 resolvedType, callingPid, callingUid); 10561 Binder.restoreCallingIdentity(origId); 10562 return res; 10563 } 10564 } 10565 10566 ComponentName startServiceInPackage(int uid, 10567 Intent service, String resolvedType) { 10568 synchronized(this) { 10569 if (DEBUG_SERVICE) 10570 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10571 final long origId = Binder.clearCallingIdentity(); 10572 ComponentName res = mServices.startServiceLocked(null, service, 10573 resolvedType, -1, uid); 10574 Binder.restoreCallingIdentity(origId); 10575 return res; 10576 } 10577 } 10578 10579 public int stopService(IApplicationThread caller, Intent service, 10580 String resolvedType) { 10581 enforceNotIsolatedCaller("stopService"); 10582 // Refuse possible leaked file descriptors 10583 if (service != null && service.hasFileDescriptors() == true) { 10584 throw new IllegalArgumentException("File descriptors passed in Intent"); 10585 } 10586 10587 synchronized(this) { 10588 return mServices.stopServiceLocked(caller, service, resolvedType); 10589 } 10590 } 10591 10592 public IBinder peekService(Intent service, String resolvedType) { 10593 enforceNotIsolatedCaller("peekService"); 10594 // Refuse possible leaked file descriptors 10595 if (service != null && service.hasFileDescriptors() == true) { 10596 throw new IllegalArgumentException("File descriptors passed in Intent"); 10597 } 10598 synchronized(this) { 10599 return mServices.peekServiceLocked(service, resolvedType); 10600 } 10601 } 10602 10603 public boolean stopServiceToken(ComponentName className, IBinder token, 10604 int startId) { 10605 synchronized(this) { 10606 return mServices.stopServiceTokenLocked(className, token, startId); 10607 } 10608 } 10609 10610 public void setServiceForeground(ComponentName className, IBinder token, 10611 int id, Notification notification, boolean removeNotification) { 10612 synchronized(this) { 10613 mServices.setServiceForegroundLocked(className, token, id, notification, 10614 removeNotification); 10615 } 10616 } 10617 10618 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10619 String className, int flags) { 10620 boolean result = false; 10621 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10622 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10623 if (ActivityManager.checkUidPermission( 10624 android.Manifest.permission.INTERACT_ACROSS_USERS, 10625 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10626 ComponentName comp = new ComponentName(aInfo.packageName, className); 10627 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10628 + " requests FLAG_SINGLE_USER, but app does not hold " 10629 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10630 Slog.w(TAG, msg); 10631 throw new SecurityException(msg); 10632 } 10633 result = true; 10634 } 10635 } else if (componentProcessName == aInfo.packageName) { 10636 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10637 } else if ("system".equals(componentProcessName)) { 10638 result = true; 10639 } 10640 if (DEBUG_MU) { 10641 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10642 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10643 } 10644 return result; 10645 } 10646 10647 public int bindService(IApplicationThread caller, IBinder token, 10648 Intent service, String resolvedType, 10649 IServiceConnection connection, int flags, int userId) { 10650 enforceNotIsolatedCaller("bindService"); 10651 // Refuse possible leaked file descriptors 10652 if (service != null && service.hasFileDescriptors() == true) { 10653 throw new IllegalArgumentException("File descriptors passed in Intent"); 10654 } 10655 10656 checkValidCaller(Binder.getCallingUid(), userId); 10657 10658 synchronized(this) { 10659 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10660 connection, flags, userId); 10661 } 10662 } 10663 10664 public boolean unbindService(IServiceConnection connection) { 10665 synchronized (this) { 10666 return mServices.unbindServiceLocked(connection); 10667 } 10668 } 10669 10670 public void publishService(IBinder token, Intent intent, IBinder service) { 10671 // Refuse possible leaked file descriptors 10672 if (intent != null && intent.hasFileDescriptors() == true) { 10673 throw new IllegalArgumentException("File descriptors passed in Intent"); 10674 } 10675 10676 synchronized(this) { 10677 if (!(token instanceof ServiceRecord)) { 10678 throw new IllegalArgumentException("Invalid service token"); 10679 } 10680 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10681 } 10682 } 10683 10684 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 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 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10692 } 10693 } 10694 10695 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10696 synchronized(this) { 10697 if (!(token instanceof ServiceRecord)) { 10698 throw new IllegalArgumentException("Invalid service token"); 10699 } 10700 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10701 } 10702 } 10703 10704 // ========================================================= 10705 // BACKUP AND RESTORE 10706 // ========================================================= 10707 10708 // Cause the target app to be launched if necessary and its backup agent 10709 // instantiated. The backup agent will invoke backupAgentCreated() on the 10710 // activity manager to announce its creation. 10711 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10712 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10713 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10714 10715 synchronized(this) { 10716 // !!! TODO: currently no check here that we're already bound 10717 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10718 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10719 synchronized (stats) { 10720 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10721 } 10722 10723 // Backup agent is now in use, its package can't be stopped. 10724 try { 10725 AppGlobals.getPackageManager().setPackageStoppedState( 10726 app.packageName, false, UserHandle.getUserId(app.uid)); 10727 } catch (RemoteException e) { 10728 } catch (IllegalArgumentException e) { 10729 Slog.w(TAG, "Failed trying to unstop package " 10730 + app.packageName + ": " + e); 10731 } 10732 10733 BackupRecord r = new BackupRecord(ss, app, backupMode); 10734 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10735 ? new ComponentName(app.packageName, app.backupAgentName) 10736 : new ComponentName("android", "FullBackupAgent"); 10737 // startProcessLocked() returns existing proc's record if it's already running 10738 ProcessRecord proc = startProcessLocked(app.processName, app, 10739 false, 0, "backup", hostingName, false, false); 10740 if (proc == null) { 10741 Slog.e(TAG, "Unable to start backup agent process " + r); 10742 return false; 10743 } 10744 10745 r.app = proc; 10746 mBackupTarget = r; 10747 mBackupAppName = app.packageName; 10748 10749 // Try not to kill the process during backup 10750 updateOomAdjLocked(proc); 10751 10752 // If the process is already attached, schedule the creation of the backup agent now. 10753 // If it is not yet live, this will be done when it attaches to the framework. 10754 if (proc.thread != null) { 10755 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10756 try { 10757 proc.thread.scheduleCreateBackupAgent(app, 10758 compatibilityInfoForPackageLocked(app), backupMode); 10759 } catch (RemoteException e) { 10760 // Will time out on the backup manager side 10761 } 10762 } else { 10763 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10764 } 10765 // Invariants: at this point, the target app process exists and the application 10766 // is either already running or in the process of coming up. mBackupTarget and 10767 // mBackupAppName describe the app, so that when it binds back to the AM we 10768 // know that it's scheduled for a backup-agent operation. 10769 } 10770 10771 return true; 10772 } 10773 10774 // A backup agent has just come up 10775 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10776 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10777 + " = " + agent); 10778 10779 synchronized(this) { 10780 if (!agentPackageName.equals(mBackupAppName)) { 10781 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10782 return; 10783 } 10784 } 10785 10786 long oldIdent = Binder.clearCallingIdentity(); 10787 try { 10788 IBackupManager bm = IBackupManager.Stub.asInterface( 10789 ServiceManager.getService(Context.BACKUP_SERVICE)); 10790 bm.agentConnected(agentPackageName, agent); 10791 } catch (RemoteException e) { 10792 // can't happen; the backup manager service is local 10793 } catch (Exception e) { 10794 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10795 e.printStackTrace(); 10796 } finally { 10797 Binder.restoreCallingIdentity(oldIdent); 10798 } 10799 } 10800 10801 // done with this agent 10802 public void unbindBackupAgent(ApplicationInfo appInfo) { 10803 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10804 if (appInfo == null) { 10805 Slog.w(TAG, "unbind backup agent for null app"); 10806 return; 10807 } 10808 10809 synchronized(this) { 10810 if (mBackupAppName == null) { 10811 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10812 return; 10813 } 10814 10815 if (!mBackupAppName.equals(appInfo.packageName)) { 10816 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10817 return; 10818 } 10819 10820 ProcessRecord proc = mBackupTarget.app; 10821 mBackupTarget = null; 10822 mBackupAppName = null; 10823 10824 // Not backing this app up any more; reset its OOM adjustment 10825 updateOomAdjLocked(proc); 10826 10827 // If the app crashed during backup, 'thread' will be null here 10828 if (proc.thread != null) { 10829 try { 10830 proc.thread.scheduleDestroyBackupAgent(appInfo, 10831 compatibilityInfoForPackageLocked(appInfo)); 10832 } catch (Exception e) { 10833 Slog.e(TAG, "Exception when unbinding backup agent:"); 10834 e.printStackTrace(); 10835 } 10836 } 10837 } 10838 } 10839 // ========================================================= 10840 // BROADCASTS 10841 // ========================================================= 10842 10843 private final List getStickiesLocked(String action, IntentFilter filter, 10844 List cur) { 10845 final ContentResolver resolver = mContext.getContentResolver(); 10846 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10847 if (list == null) { 10848 return cur; 10849 } 10850 int N = list.size(); 10851 for (int i=0; i<N; i++) { 10852 Intent intent = list.get(i); 10853 if (filter.match(resolver, intent, true, TAG) >= 0) { 10854 if (cur == null) { 10855 cur = new ArrayList<Intent>(); 10856 } 10857 cur.add(intent); 10858 } 10859 } 10860 return cur; 10861 } 10862 10863 boolean isPendingBroadcastProcessLocked(int pid) { 10864 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10865 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10866 } 10867 10868 void skipPendingBroadcastLocked(int pid) { 10869 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10870 for (BroadcastQueue queue : mBroadcastQueues) { 10871 queue.skipPendingBroadcastLocked(pid); 10872 } 10873 } 10874 10875 // The app just attached; send any pending broadcasts that it should receive 10876 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10877 boolean didSomething = false; 10878 for (BroadcastQueue queue : mBroadcastQueues) { 10879 didSomething |= queue.sendPendingBroadcastsLocked(app); 10880 } 10881 return didSomething; 10882 } 10883 10884 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10885 IIntentReceiver receiver, IntentFilter filter, String permission) { 10886 enforceNotIsolatedCaller("registerReceiver"); 10887 int callingUid; 10888 synchronized(this) { 10889 ProcessRecord callerApp = null; 10890 if (caller != null) { 10891 callerApp = getRecordForAppLocked(caller); 10892 if (callerApp == null) { 10893 throw new SecurityException( 10894 "Unable to find app for caller " + caller 10895 + " (pid=" + Binder.getCallingPid() 10896 + ") when registering receiver " + receiver); 10897 } 10898 if (callerApp.info.uid != Process.SYSTEM_UID && 10899 !callerApp.pkgList.contains(callerPackage)) { 10900 throw new SecurityException("Given caller package " + callerPackage 10901 + " is not running in process " + callerApp); 10902 } 10903 callingUid = callerApp.info.uid; 10904 } else { 10905 callerPackage = null; 10906 callingUid = Binder.getCallingUid(); 10907 } 10908 10909 List allSticky = null; 10910 10911 // Look for any matching sticky broadcasts... 10912 Iterator actions = filter.actionsIterator(); 10913 if (actions != null) { 10914 while (actions.hasNext()) { 10915 String action = (String)actions.next(); 10916 allSticky = getStickiesLocked(action, filter, allSticky); 10917 } 10918 } else { 10919 allSticky = getStickiesLocked(null, filter, allSticky); 10920 } 10921 10922 // The first sticky in the list is returned directly back to 10923 // the client. 10924 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10925 10926 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10927 + ": " + sticky); 10928 10929 if (receiver == null) { 10930 return sticky; 10931 } 10932 10933 ReceiverList rl 10934 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10935 if (rl == null) { 10936 rl = new ReceiverList(this, callerApp, 10937 Binder.getCallingPid(), 10938 Binder.getCallingUid(), receiver); 10939 if (rl.app != null) { 10940 rl.app.receivers.add(rl); 10941 } else { 10942 try { 10943 receiver.asBinder().linkToDeath(rl, 0); 10944 } catch (RemoteException e) { 10945 return sticky; 10946 } 10947 rl.linkedToDeath = true; 10948 } 10949 mRegisteredReceivers.put(receiver.asBinder(), rl); 10950 } 10951 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10952 permission, callingUid); 10953 rl.add(bf); 10954 if (!bf.debugCheck()) { 10955 Slog.w(TAG, "==> For Dynamic broadast"); 10956 } 10957 mReceiverResolver.addFilter(bf); 10958 10959 // Enqueue broadcasts for all existing stickies that match 10960 // this filter. 10961 if (allSticky != null) { 10962 ArrayList receivers = new ArrayList(); 10963 receivers.add(bf); 10964 10965 int N = allSticky.size(); 10966 for (int i=0; i<N; i++) { 10967 Intent intent = (Intent)allSticky.get(i); 10968 BroadcastQueue queue = broadcastQueueForIntent(intent); 10969 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10970 null, -1, -1, null, receivers, null, 0, null, null, 10971 false, true, true, false); 10972 queue.enqueueParallelBroadcastLocked(r); 10973 queue.scheduleBroadcastsLocked(); 10974 } 10975 } 10976 10977 return sticky; 10978 } 10979 } 10980 10981 public void unregisterReceiver(IIntentReceiver receiver) { 10982 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10983 10984 final long origId = Binder.clearCallingIdentity(); 10985 try { 10986 boolean doTrim = false; 10987 10988 synchronized(this) { 10989 ReceiverList rl 10990 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10991 if (rl != null) { 10992 if (rl.curBroadcast != null) { 10993 BroadcastRecord r = rl.curBroadcast; 10994 final boolean doNext = finishReceiverLocked( 10995 receiver.asBinder(), r.resultCode, r.resultData, 10996 r.resultExtras, r.resultAbort, true); 10997 if (doNext) { 10998 doTrim = true; 10999 r.queue.processNextBroadcast(false); 11000 } 11001 } 11002 11003 if (rl.app != null) { 11004 rl.app.receivers.remove(rl); 11005 } 11006 removeReceiverLocked(rl); 11007 if (rl.linkedToDeath) { 11008 rl.linkedToDeath = false; 11009 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11010 } 11011 } 11012 } 11013 11014 // If we actually concluded any broadcasts, we might now be able 11015 // to trim the recipients' apps from our working set 11016 if (doTrim) { 11017 trimApplications(); 11018 return; 11019 } 11020 11021 } finally { 11022 Binder.restoreCallingIdentity(origId); 11023 } 11024 } 11025 11026 void removeReceiverLocked(ReceiverList rl) { 11027 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11028 int N = rl.size(); 11029 for (int i=0; i<N; i++) { 11030 mReceiverResolver.removeFilter(rl.get(i)); 11031 } 11032 } 11033 11034 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11035 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11036 ProcessRecord r = mLruProcesses.get(i); 11037 if (r.thread != null) { 11038 try { 11039 r.thread.dispatchPackageBroadcast(cmd, packages); 11040 } catch (RemoteException ex) { 11041 } 11042 } 11043 } 11044 } 11045 11046 private final int broadcastIntentLocked(ProcessRecord callerApp, 11047 String callerPackage, Intent intent, String resolvedType, 11048 IIntentReceiver resultTo, int resultCode, String resultData, 11049 Bundle map, String requiredPermission, 11050 boolean ordered, boolean sticky, int callingPid, int callingUid, 11051 int userId) { 11052 intent = new Intent(intent); 11053 11054 // By default broadcasts do not go to stopped apps. 11055 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11056 11057 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11058 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11059 + " ordered=" + ordered + " userid=" + userId); 11060 if ((resultTo != null) && !ordered) { 11061 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11062 } 11063 11064 boolean onlySendToCaller = false; 11065 11066 // If the caller is trying to send this broadcast to a different 11067 // user, verify that is allowed. 11068 if (UserHandle.getUserId(callingUid) != userId) { 11069 if (checkComponentPermission( 11070 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11071 callingPid, callingUid, -1, true) 11072 != PackageManager.PERMISSION_GRANTED) { 11073 if (checkComponentPermission( 11074 android.Manifest.permission.INTERACT_ACROSS_USERS, 11075 callingPid, callingUid, -1, true) 11076 == PackageManager.PERMISSION_GRANTED) { 11077 onlySendToCaller = true; 11078 } else { 11079 String msg = "Permission Denial: " + intent.getAction() 11080 + " broadcast from " + callerPackage 11081 + " asks to send as user " + userId 11082 + " but is calling from user " + UserHandle.getUserId(callingUid) 11083 + "; this requires " 11084 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11085 Slog.w(TAG, msg); 11086 throw new SecurityException(msg); 11087 } 11088 } 11089 } 11090 11091 // Handle special intents: if this broadcast is from the package 11092 // manager about a package being removed, we need to remove all of 11093 // its activities from the history stack. 11094 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11095 intent.getAction()); 11096 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11097 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11098 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11099 || uidRemoved) { 11100 if (checkComponentPermission( 11101 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11102 callingPid, callingUid, -1, true) 11103 == PackageManager.PERMISSION_GRANTED) { 11104 if (uidRemoved) { 11105 final Bundle intentExtras = intent.getExtras(); 11106 final int uid = intentExtras != null 11107 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11108 if (uid >= 0) { 11109 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11110 synchronized (bs) { 11111 bs.removeUidStatsLocked(uid); 11112 } 11113 } 11114 } else { 11115 // If resources are unvailble just force stop all 11116 // those packages and flush the attribute cache as well. 11117 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11118 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11119 if (list != null && (list.length > 0)) { 11120 for (String pkg : list) { 11121 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11122 } 11123 sendPackageBroadcastLocked( 11124 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11125 } 11126 } else { 11127 Uri data = intent.getData(); 11128 String ssp; 11129 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11130 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11131 forceStopPackageLocked(ssp, 11132 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11133 false, userId); 11134 } 11135 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11136 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11137 new String[] {ssp}); 11138 } 11139 } 11140 } 11141 } 11142 } else { 11143 String msg = "Permission Denial: " + intent.getAction() 11144 + " broadcast from " + callerPackage + " (pid=" + callingPid 11145 + ", uid=" + callingUid + ")" 11146 + " requires " 11147 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11148 Slog.w(TAG, msg); 11149 throw new SecurityException(msg); 11150 } 11151 11152 // Special case for adding a package: by default turn on compatibility 11153 // mode. 11154 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11155 Uri data = intent.getData(); 11156 String ssp; 11157 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11158 mCompatModePackages.handlePackageAddedLocked(ssp, 11159 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11160 } 11161 } 11162 11163 /* 11164 * If this is the time zone changed action, queue up a message that will reset the timezone 11165 * of all currently running processes. This message will get queued up before the broadcast 11166 * happens. 11167 */ 11168 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11169 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11170 } 11171 11172 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11173 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11174 } 11175 11176 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11177 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11178 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11179 } 11180 11181 /* 11182 * Prevent non-system code (defined here to be non-persistent 11183 * processes) from sending protected broadcasts. 11184 */ 11185 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11186 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11187 callingUid == 0) { 11188 // Always okay. 11189 } else if (callerApp == null || !callerApp.persistent) { 11190 try { 11191 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11192 intent.getAction())) { 11193 String msg = "Permission Denial: not allowed to send broadcast " 11194 + intent.getAction() + " from pid=" 11195 + callingPid + ", uid=" + callingUid; 11196 Slog.w(TAG, msg); 11197 throw new SecurityException(msg); 11198 } 11199 } catch (RemoteException e) { 11200 Slog.w(TAG, "Remote exception", e); 11201 return ActivityManager.BROADCAST_SUCCESS; 11202 } 11203 } 11204 11205 // Add to the sticky list if requested. 11206 if (sticky) { 11207 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11208 callingPid, callingUid) 11209 != PackageManager.PERMISSION_GRANTED) { 11210 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11211 + callingPid + ", uid=" + callingUid 11212 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11213 Slog.w(TAG, msg); 11214 throw new SecurityException(msg); 11215 } 11216 if (requiredPermission != null) { 11217 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11218 + " and enforce permission " + requiredPermission); 11219 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11220 } 11221 if (intent.getComponent() != null) { 11222 throw new SecurityException( 11223 "Sticky broadcasts can't target a specific component"); 11224 } 11225 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11226 if (list == null) { 11227 list = new ArrayList<Intent>(); 11228 mStickyBroadcasts.put(intent.getAction(), list); 11229 } 11230 int N = list.size(); 11231 int i; 11232 for (i=0; i<N; i++) { 11233 if (intent.filterEquals(list.get(i))) { 11234 // This sticky already exists, replace it. 11235 list.set(i, new Intent(intent)); 11236 break; 11237 } 11238 } 11239 if (i >= N) { 11240 list.add(new Intent(intent)); 11241 } 11242 } 11243 11244 // Figure out who all will receive this broadcast. 11245 List receivers = null; 11246 List<BroadcastFilter> registeredReceivers = null; 11247 try { 11248 // Need to resolve the intent to interested receivers... 11249 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11250 == 0) { 11251 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11252 intent, resolvedType, STOCK_PM_FLAGS, userId); 11253 } 11254 if (intent.getComponent() == null) { 11255 registeredReceivers = mReceiverResolver.queryIntent(intent, 11256 resolvedType, false, userId); 11257 } 11258 } catch (RemoteException ex) { 11259 // pm is in same process, this will never happen. 11260 } 11261 11262 final boolean replacePending = 11263 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11264 11265 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11266 + " replacePending=" + replacePending); 11267 11268 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11269 if (!ordered && NR > 0) { 11270 // If we are not serializing this broadcast, then send the 11271 // registered receivers separately so they don't wait for the 11272 // components to be launched. 11273 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11274 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11275 callerPackage, callingPid, callingUid, requiredPermission, 11276 registeredReceivers, resultTo, resultCode, resultData, map, 11277 ordered, sticky, false, onlySendToCaller); 11278 if (DEBUG_BROADCAST) Slog.v( 11279 TAG, "Enqueueing parallel broadcast " + r); 11280 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11281 if (!replaced) { 11282 queue.enqueueParallelBroadcastLocked(r); 11283 queue.scheduleBroadcastsLocked(); 11284 } 11285 registeredReceivers = null; 11286 NR = 0; 11287 } 11288 11289 // Merge into one list. 11290 int ir = 0; 11291 if (receivers != null) { 11292 // A special case for PACKAGE_ADDED: do not allow the package 11293 // being added to see this broadcast. This prevents them from 11294 // using this as a back door to get run as soon as they are 11295 // installed. Maybe in the future we want to have a special install 11296 // broadcast or such for apps, but we'd like to deliberately make 11297 // this decision. 11298 String skipPackages[] = null; 11299 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11300 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11301 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11302 Uri data = intent.getData(); 11303 if (data != null) { 11304 String pkgName = data.getSchemeSpecificPart(); 11305 if (pkgName != null) { 11306 skipPackages = new String[] { pkgName }; 11307 } 11308 } 11309 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11310 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11311 } 11312 if (skipPackages != null && (skipPackages.length > 0)) { 11313 for (String skipPackage : skipPackages) { 11314 if (skipPackage != null) { 11315 int NT = receivers.size(); 11316 for (int it=0; it<NT; it++) { 11317 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11318 if (curt.activityInfo.packageName.equals(skipPackage)) { 11319 receivers.remove(it); 11320 it--; 11321 NT--; 11322 } 11323 } 11324 } 11325 } 11326 } 11327 11328 int NT = receivers != null ? receivers.size() : 0; 11329 int it = 0; 11330 ResolveInfo curt = null; 11331 BroadcastFilter curr = null; 11332 while (it < NT && ir < NR) { 11333 if (curt == null) { 11334 curt = (ResolveInfo)receivers.get(it); 11335 } 11336 if (curr == null) { 11337 curr = registeredReceivers.get(ir); 11338 } 11339 if (curr.getPriority() >= curt.priority) { 11340 // Insert this broadcast record into the final list. 11341 receivers.add(it, curr); 11342 ir++; 11343 curr = null; 11344 it++; 11345 NT++; 11346 } else { 11347 // Skip to the next ResolveInfo in the final list. 11348 it++; 11349 curt = null; 11350 } 11351 } 11352 } 11353 while (ir < NR) { 11354 if (receivers == null) { 11355 receivers = new ArrayList(); 11356 } 11357 receivers.add(registeredReceivers.get(ir)); 11358 ir++; 11359 } 11360 11361 if ((receivers != null && receivers.size() > 0) 11362 || resultTo != null) { 11363 BroadcastQueue queue = broadcastQueueForIntent(intent); 11364 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11365 callerPackage, callingPid, callingUid, requiredPermission, 11366 receivers, resultTo, resultCode, resultData, map, ordered, 11367 sticky, false, onlySendToCaller); 11368 if (DEBUG_BROADCAST) Slog.v( 11369 TAG, "Enqueueing ordered broadcast " + r 11370 + ": prev had " + queue.mOrderedBroadcasts.size()); 11371 if (DEBUG_BROADCAST) { 11372 int seq = r.intent.getIntExtra("seq", -1); 11373 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11374 } 11375 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11376 if (!replaced) { 11377 queue.enqueueOrderedBroadcastLocked(r); 11378 queue.scheduleBroadcastsLocked(); 11379 } 11380 } 11381 11382 return ActivityManager.BROADCAST_SUCCESS; 11383 } 11384 11385 final Intent verifyBroadcastLocked(Intent intent) { 11386 // Refuse possible leaked file descriptors 11387 if (intent != null && intent.hasFileDescriptors() == true) { 11388 throw new IllegalArgumentException("File descriptors passed in Intent"); 11389 } 11390 11391 int flags = intent.getFlags(); 11392 11393 if (!mProcessesReady) { 11394 // if the caller really truly claims to know what they're doing, go 11395 // ahead and allow the broadcast without launching any receivers 11396 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11397 intent = new Intent(intent); 11398 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11399 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11400 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11401 + " before boot completion"); 11402 throw new IllegalStateException("Cannot broadcast before boot completed"); 11403 } 11404 } 11405 11406 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11407 throw new IllegalArgumentException( 11408 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11409 } 11410 11411 return intent; 11412 } 11413 11414 public final int broadcastIntent(IApplicationThread caller, 11415 Intent intent, String resolvedType, IIntentReceiver resultTo, 11416 int resultCode, String resultData, Bundle map, 11417 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11418 enforceNotIsolatedCaller("broadcastIntent"); 11419 synchronized(this) { 11420 intent = verifyBroadcastLocked(intent); 11421 11422 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11423 final int callingPid = Binder.getCallingPid(); 11424 final int callingUid = Binder.getCallingUid(); 11425 final long origId = Binder.clearCallingIdentity(); 11426 int res = broadcastIntentLocked(callerApp, 11427 callerApp != null ? callerApp.info.packageName : null, 11428 intent, resolvedType, resultTo, 11429 resultCode, resultData, map, requiredPermission, serialized, sticky, 11430 callingPid, callingUid, userId); 11431 Binder.restoreCallingIdentity(origId); 11432 return res; 11433 } 11434 } 11435 11436 int broadcastIntentInPackage(String packageName, int uid, 11437 Intent intent, String resolvedType, IIntentReceiver resultTo, 11438 int resultCode, String resultData, Bundle map, 11439 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11440 synchronized(this) { 11441 intent = verifyBroadcastLocked(intent); 11442 11443 final long origId = Binder.clearCallingIdentity(); 11444 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11445 resultTo, resultCode, resultData, map, requiredPermission, 11446 serialized, sticky, -1, uid, userId); 11447 Binder.restoreCallingIdentity(origId); 11448 return res; 11449 } 11450 } 11451 11452 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11453 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11454 // Refuse possible leaked file descriptors 11455 if (intent != null && intent.hasFileDescriptors() == true) { 11456 throw new IllegalArgumentException("File descriptors passed in Intent"); 11457 } 11458 11459 synchronized(this) { 11460 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11461 != PackageManager.PERMISSION_GRANTED) { 11462 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11463 + Binder.getCallingPid() 11464 + ", uid=" + Binder.getCallingUid() 11465 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11466 Slog.w(TAG, msg); 11467 throw new SecurityException(msg); 11468 } 11469 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11470 if (list != null) { 11471 int N = list.size(); 11472 int i; 11473 for (i=0; i<N; i++) { 11474 if (intent.filterEquals(list.get(i))) { 11475 list.remove(i); 11476 break; 11477 } 11478 } 11479 } 11480 } 11481 } 11482 11483 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11484 String resultData, Bundle resultExtras, boolean resultAbort, 11485 boolean explicit) { 11486 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11487 if (r == null) { 11488 Slog.w(TAG, "finishReceiver called but not found on queue"); 11489 return false; 11490 } 11491 11492 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11493 explicit); 11494 } 11495 11496 public void finishReceiver(IBinder who, int resultCode, String resultData, 11497 Bundle resultExtras, boolean resultAbort) { 11498 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11499 11500 // Refuse possible leaked file descriptors 11501 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11502 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11503 } 11504 11505 final long origId = Binder.clearCallingIdentity(); 11506 try { 11507 boolean doNext = false; 11508 BroadcastRecord r = null; 11509 11510 synchronized(this) { 11511 r = broadcastRecordForReceiverLocked(who); 11512 if (r != null) { 11513 doNext = r.queue.finishReceiverLocked(r, resultCode, 11514 resultData, resultExtras, resultAbort, true); 11515 } 11516 } 11517 11518 if (doNext) { 11519 r.queue.processNextBroadcast(false); 11520 } 11521 trimApplications(); 11522 } finally { 11523 Binder.restoreCallingIdentity(origId); 11524 } 11525 } 11526 11527 // ========================================================= 11528 // INSTRUMENTATION 11529 // ========================================================= 11530 11531 public boolean startInstrumentation(ComponentName className, 11532 String profileFile, int flags, Bundle arguments, 11533 IInstrumentationWatcher watcher) { 11534 enforceNotIsolatedCaller("startInstrumentation"); 11535 // Refuse possible leaked file descriptors 11536 if (arguments != null && arguments.hasFileDescriptors()) { 11537 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11538 } 11539 11540 synchronized(this) { 11541 InstrumentationInfo ii = null; 11542 ApplicationInfo ai = null; 11543 try { 11544 ii = mContext.getPackageManager().getInstrumentationInfo( 11545 className, STOCK_PM_FLAGS); 11546 ai = mContext.getPackageManager().getApplicationInfo( 11547 ii.targetPackage, STOCK_PM_FLAGS); 11548 } catch (PackageManager.NameNotFoundException e) { 11549 } 11550 if (ii == null) { 11551 reportStartInstrumentationFailure(watcher, className, 11552 "Unable to find instrumentation info for: " + className); 11553 return false; 11554 } 11555 if (ai == null) { 11556 reportStartInstrumentationFailure(watcher, className, 11557 "Unable to find instrumentation target package: " + ii.targetPackage); 11558 return false; 11559 } 11560 11561 int match = mContext.getPackageManager().checkSignatures( 11562 ii.targetPackage, ii.packageName); 11563 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11564 String msg = "Permission Denial: starting instrumentation " 11565 + className + " from pid=" 11566 + Binder.getCallingPid() 11567 + ", uid=" + Binder.getCallingPid() 11568 + " not allowed because package " + ii.packageName 11569 + " does not have a signature matching the target " 11570 + ii.targetPackage; 11571 reportStartInstrumentationFailure(watcher, className, msg); 11572 throw new SecurityException(msg); 11573 } 11574 11575 int userId = UserHandle.getCallingUserId(); 11576 final long origId = Binder.clearCallingIdentity(); 11577 // Instrumentation can kill and relaunch even persistent processes 11578 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11579 ProcessRecord app = addAppLocked(ai, false); 11580 app.instrumentationClass = className; 11581 app.instrumentationInfo = ai; 11582 app.instrumentationProfileFile = profileFile; 11583 app.instrumentationArguments = arguments; 11584 app.instrumentationWatcher = watcher; 11585 app.instrumentationResultClass = className; 11586 Binder.restoreCallingIdentity(origId); 11587 } 11588 11589 return true; 11590 } 11591 11592 /** 11593 * Report errors that occur while attempting to start Instrumentation. Always writes the 11594 * error to the logs, but if somebody is watching, send the report there too. This enables 11595 * the "am" command to report errors with more information. 11596 * 11597 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11598 * @param cn The component name of the instrumentation. 11599 * @param report The error report. 11600 */ 11601 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11602 ComponentName cn, String report) { 11603 Slog.w(TAG, report); 11604 try { 11605 if (watcher != null) { 11606 Bundle results = new Bundle(); 11607 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11608 results.putString("Error", report); 11609 watcher.instrumentationStatus(cn, -1, results); 11610 } 11611 } catch (RemoteException e) { 11612 Slog.w(TAG, e); 11613 } 11614 } 11615 11616 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11617 if (app.instrumentationWatcher != null) { 11618 try { 11619 // NOTE: IInstrumentationWatcher *must* be oneway here 11620 app.instrumentationWatcher.instrumentationFinished( 11621 app.instrumentationClass, 11622 resultCode, 11623 results); 11624 } catch (RemoteException e) { 11625 } 11626 } 11627 app.instrumentationWatcher = null; 11628 app.instrumentationClass = null; 11629 app.instrumentationInfo = null; 11630 app.instrumentationProfileFile = null; 11631 app.instrumentationArguments = null; 11632 11633 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11634 } 11635 11636 public void finishInstrumentation(IApplicationThread target, 11637 int resultCode, Bundle results) { 11638 int userId = UserHandle.getCallingUserId(); 11639 // Refuse possible leaked file descriptors 11640 if (results != null && results.hasFileDescriptors()) { 11641 throw new IllegalArgumentException("File descriptors passed in Intent"); 11642 } 11643 11644 synchronized(this) { 11645 ProcessRecord app = getRecordForAppLocked(target); 11646 if (app == null) { 11647 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11648 return; 11649 } 11650 final long origId = Binder.clearCallingIdentity(); 11651 finishInstrumentationLocked(app, resultCode, results); 11652 Binder.restoreCallingIdentity(origId); 11653 } 11654 } 11655 11656 // ========================================================= 11657 // CONFIGURATION 11658 // ========================================================= 11659 11660 public ConfigurationInfo getDeviceConfigurationInfo() { 11661 ConfigurationInfo config = new ConfigurationInfo(); 11662 synchronized (this) { 11663 config.reqTouchScreen = mConfiguration.touchscreen; 11664 config.reqKeyboardType = mConfiguration.keyboard; 11665 config.reqNavigation = mConfiguration.navigation; 11666 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11667 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11668 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11669 } 11670 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11671 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11672 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11673 } 11674 config.reqGlEsVersion = GL_ES_VERSION; 11675 } 11676 return config; 11677 } 11678 11679 public Configuration getConfiguration() { 11680 Configuration ci; 11681 synchronized(this) { 11682 ci = new Configuration(mConfiguration); 11683 } 11684 return ci; 11685 } 11686 11687 public void updatePersistentConfiguration(Configuration values) { 11688 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11689 "updateConfiguration()"); 11690 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11691 "updateConfiguration()"); 11692 if (values == null) { 11693 throw new NullPointerException("Configuration must not be null"); 11694 } 11695 11696 synchronized(this) { 11697 final long origId = Binder.clearCallingIdentity(); 11698 updateConfigurationLocked(values, null, true, false); 11699 Binder.restoreCallingIdentity(origId); 11700 } 11701 } 11702 11703 public void updateConfiguration(Configuration values) { 11704 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11705 "updateConfiguration()"); 11706 11707 synchronized(this) { 11708 if (values == null && mWindowManager != null) { 11709 // sentinel: fetch the current configuration from the window manager 11710 values = mWindowManager.computeNewConfiguration(); 11711 } 11712 11713 if (mWindowManager != null) { 11714 mProcessList.applyDisplaySize(mWindowManager); 11715 } 11716 11717 final long origId = Binder.clearCallingIdentity(); 11718 if (values != null) { 11719 Settings.System.clearConfiguration(values); 11720 } 11721 updateConfigurationLocked(values, null, false, false); 11722 Binder.restoreCallingIdentity(origId); 11723 } 11724 } 11725 11726 /** 11727 * Do either or both things: (1) change the current configuration, and (2) 11728 * make sure the given activity is running with the (now) current 11729 * configuration. Returns true if the activity has been left running, or 11730 * false if <var>starting</var> is being destroyed to match the new 11731 * configuration. 11732 * @param persistent TODO 11733 */ 11734 boolean updateConfigurationLocked(Configuration values, 11735 ActivityRecord starting, boolean persistent, boolean initLocale) { 11736 // do nothing if we are headless 11737 if (mHeadless) return true; 11738 11739 int changes = 0; 11740 11741 boolean kept = true; 11742 11743 if (values != null) { 11744 Configuration newConfig = new Configuration(mConfiguration); 11745 changes = newConfig.updateFrom(values); 11746 if (changes != 0) { 11747 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11748 Slog.i(TAG, "Updating configuration to: " + values); 11749 } 11750 11751 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11752 11753 if (values.locale != null && !initLocale) { 11754 saveLocaleLocked(values.locale, 11755 !values.locale.equals(mConfiguration.locale), 11756 values.userSetLocale); 11757 } 11758 11759 mConfigurationSeq++; 11760 if (mConfigurationSeq <= 0) { 11761 mConfigurationSeq = 1; 11762 } 11763 newConfig.seq = mConfigurationSeq; 11764 mConfiguration = newConfig; 11765 Slog.i(TAG, "Config changed: " + newConfig); 11766 11767 final Configuration configCopy = new Configuration(mConfiguration); 11768 11769 // TODO: If our config changes, should we auto dismiss any currently 11770 // showing dialogs? 11771 mShowDialogs = shouldShowDialogs(newConfig); 11772 11773 AttributeCache ac = AttributeCache.instance(); 11774 if (ac != null) { 11775 ac.updateConfiguration(configCopy); 11776 } 11777 11778 // Make sure all resources in our process are updated 11779 // right now, so that anyone who is going to retrieve 11780 // resource values after we return will be sure to get 11781 // the new ones. This is especially important during 11782 // boot, where the first config change needs to guarantee 11783 // all resources have that config before following boot 11784 // code is executed. 11785 mSystemThread.applyConfigurationToResources(configCopy); 11786 11787 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11788 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11789 msg.obj = new Configuration(configCopy); 11790 mHandler.sendMessage(msg); 11791 } 11792 11793 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11794 ProcessRecord app = mLruProcesses.get(i); 11795 try { 11796 if (app.thread != null) { 11797 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11798 + app.processName + " new config " + mConfiguration); 11799 app.thread.scheduleConfigurationChanged(configCopy); 11800 } 11801 } catch (Exception e) { 11802 } 11803 } 11804 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11805 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11806 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11807 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11808 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11809 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11810 broadcastIntentLocked(null, null, 11811 new Intent(Intent.ACTION_LOCALE_CHANGED), 11812 null, null, 0, null, null, 11813 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11814 } 11815 } 11816 } 11817 11818 if (changes != 0 && starting == null) { 11819 // If the configuration changed, and the caller is not already 11820 // in the process of starting an activity, then find the top 11821 // activity to check if its configuration needs to change. 11822 starting = mMainStack.topRunningActivityLocked(null); 11823 } 11824 11825 if (starting != null) { 11826 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11827 // And we need to make sure at this point that all other activities 11828 // are made visible with the correct configuration. 11829 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11830 } 11831 11832 if (values != null && mWindowManager != null) { 11833 mWindowManager.setNewConfiguration(mConfiguration); 11834 } 11835 11836 return kept; 11837 } 11838 11839 /** 11840 * Decide based on the configuration whether we should shouw the ANR, 11841 * crash, etc dialogs. The idea is that if there is no affordnace to 11842 * press the on-screen buttons, we shouldn't show the dialog. 11843 * 11844 * A thought: SystemUI might also want to get told about this, the Power 11845 * dialog / global actions also might want different behaviors. 11846 */ 11847 private static final boolean shouldShowDialogs(Configuration config) { 11848 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11849 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11850 } 11851 11852 /** 11853 * Save the locale. You must be inside a synchronized (this) block. 11854 */ 11855 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11856 if(isDiff) { 11857 SystemProperties.set("user.language", l.getLanguage()); 11858 SystemProperties.set("user.region", l.getCountry()); 11859 } 11860 11861 if(isPersist) { 11862 SystemProperties.set("persist.sys.language", l.getLanguage()); 11863 SystemProperties.set("persist.sys.country", l.getCountry()); 11864 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11865 } 11866 } 11867 11868 @Override 11869 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11870 ActivityRecord srec = ActivityRecord.forToken(token); 11871 return srec != null && srec.task.affinity != null && 11872 srec.task.affinity.equals(destAffinity); 11873 } 11874 11875 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11876 Intent resultData) { 11877 ComponentName dest = destIntent.getComponent(); 11878 11879 synchronized (this) { 11880 ActivityRecord srec = ActivityRecord.forToken(token); 11881 if (srec == null) { 11882 return false; 11883 } 11884 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11885 final int start = history.indexOf(srec); 11886 if (start < 0) { 11887 // Current activity is not in history stack; do nothing. 11888 return false; 11889 } 11890 int finishTo = start - 1; 11891 ActivityRecord parent = null; 11892 boolean foundParentInTask = false; 11893 if (dest != null) { 11894 TaskRecord tr = srec.task; 11895 for (int i = start - 1; i >= 0; i--) { 11896 ActivityRecord r = history.get(i); 11897 if (tr != r.task) { 11898 // Couldn't find parent in the same task; stop at the one above this. 11899 // (Root of current task; in-app "home" behavior) 11900 // Always at least finish the current activity. 11901 finishTo = Math.min(start - 1, i + 1); 11902 parent = history.get(finishTo); 11903 break; 11904 } else if (r.info.packageName.equals(dest.getPackageName()) && 11905 r.info.name.equals(dest.getClassName())) { 11906 finishTo = i; 11907 parent = r; 11908 foundParentInTask = true; 11909 break; 11910 } 11911 } 11912 } 11913 11914 if (mController != null) { 11915 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11916 if (next != null) { 11917 // ask watcher if this is allowed 11918 boolean resumeOK = true; 11919 try { 11920 resumeOK = mController.activityResuming(next.packageName); 11921 } catch (RemoteException e) { 11922 mController = null; 11923 } 11924 11925 if (!resumeOK) { 11926 return false; 11927 } 11928 } 11929 } 11930 final long origId = Binder.clearCallingIdentity(); 11931 for (int i = start; i > finishTo; i--) { 11932 ActivityRecord r = history.get(i); 11933 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11934 "navigate-up"); 11935 // Only return the supplied result for the first activity finished 11936 resultCode = Activity.RESULT_CANCELED; 11937 resultData = null; 11938 } 11939 11940 if (parent != null && foundParentInTask) { 11941 final int parentLaunchMode = parent.info.launchMode; 11942 final int destIntentFlags = destIntent.getFlags(); 11943 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11944 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11945 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11946 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11947 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11948 } else { 11949 try { 11950 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11951 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 11952 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11953 null, aInfo, parent.appToken, null, 11954 0, -1, parent.launchedFromUid, 0, null, true, null); 11955 foundParentInTask = res == ActivityManager.START_SUCCESS; 11956 } catch (RemoteException e) { 11957 foundParentInTask = false; 11958 } 11959 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11960 resultData, "navigate-up"); 11961 } 11962 } 11963 Binder.restoreCallingIdentity(origId); 11964 return foundParentInTask; 11965 } 11966 } 11967 11968 public int getLaunchedFromUid(IBinder activityToken) { 11969 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11970 if (srec == null) { 11971 return -1; 11972 } 11973 return srec.launchedFromUid; 11974 } 11975 11976 // ========================================================= 11977 // LIFETIME MANAGEMENT 11978 // ========================================================= 11979 11980 // Returns which broadcast queue the app is the current [or imminent] receiver 11981 // on, or 'null' if the app is not an active broadcast recipient. 11982 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11983 BroadcastRecord r = app.curReceiver; 11984 if (r != null) { 11985 return r.queue; 11986 } 11987 11988 // It's not the current receiver, but it might be starting up to become one 11989 synchronized (this) { 11990 for (BroadcastQueue queue : mBroadcastQueues) { 11991 r = queue.mPendingBroadcast; 11992 if (r != null && r.curApp == app) { 11993 // found it; report which queue it's in 11994 return queue; 11995 } 11996 } 11997 } 11998 11999 return null; 12000 } 12001 12002 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12003 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12004 if (mAdjSeq == app.adjSeq) { 12005 // This adjustment has already been computed. If we are calling 12006 // from the top, we may have already computed our adjustment with 12007 // an earlier hidden adjustment that isn't really for us... if 12008 // so, use the new hidden adjustment. 12009 if (!recursed && app.hidden) { 12010 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12011 app.hasActivities ? hiddenAdj : emptyAdj; 12012 } 12013 return app.curRawAdj; 12014 } 12015 12016 if (app.thread == null) { 12017 app.adjSeq = mAdjSeq; 12018 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12019 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12020 } 12021 12022 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12023 app.adjSource = null; 12024 app.adjTarget = null; 12025 app.empty = false; 12026 app.hidden = false; 12027 12028 final int activitiesSize = app.activities.size(); 12029 12030 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12031 // The max adjustment doesn't allow this app to be anything 12032 // below foreground, so it is not worth doing work for it. 12033 app.adjType = "fixed"; 12034 app.adjSeq = mAdjSeq; 12035 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12036 app.hasActivities = false; 12037 app.foregroundActivities = false; 12038 app.keeping = true; 12039 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12040 // System process can do UI, and when they do we want to have 12041 // them trim their memory after the user leaves the UI. To 12042 // facilitate this, here we need to determine whether or not it 12043 // is currently showing UI. 12044 app.systemNoUi = true; 12045 if (app == TOP_APP) { 12046 app.systemNoUi = false; 12047 app.hasActivities = true; 12048 } else if (activitiesSize > 0) { 12049 for (int j = 0; j < activitiesSize; j++) { 12050 final ActivityRecord r = app.activities.get(j); 12051 if (r.visible) { 12052 app.systemNoUi = false; 12053 } 12054 if (r.app == app) { 12055 app.hasActivities = true; 12056 } 12057 } 12058 } 12059 return (app.curAdj=app.maxAdj); 12060 } 12061 12062 app.keeping = false; 12063 app.systemNoUi = false; 12064 app.hasActivities = false; 12065 12066 // Determine the importance of the process, starting with most 12067 // important to least, and assign an appropriate OOM adjustment. 12068 int adj; 12069 int schedGroup; 12070 boolean foregroundActivities = false; 12071 boolean interesting = false; 12072 BroadcastQueue queue; 12073 if (app == TOP_APP) { 12074 // The last app on the list is the foreground app. 12075 adj = ProcessList.FOREGROUND_APP_ADJ; 12076 schedGroup = Process.THREAD_GROUP_DEFAULT; 12077 app.adjType = "top-activity"; 12078 foregroundActivities = true; 12079 interesting = true; 12080 app.hasActivities = true; 12081 } else if (app.instrumentationClass != null) { 12082 // Don't want to kill running instrumentation. 12083 adj = ProcessList.FOREGROUND_APP_ADJ; 12084 schedGroup = Process.THREAD_GROUP_DEFAULT; 12085 app.adjType = "instrumentation"; 12086 interesting = true; 12087 } else if ((queue = isReceivingBroadcast(app)) != null) { 12088 // An app that is currently receiving a broadcast also 12089 // counts as being in the foreground for OOM killer purposes. 12090 // It's placed in a sched group based on the nature of the 12091 // broadcast as reflected by which queue it's active in. 12092 adj = ProcessList.FOREGROUND_APP_ADJ; 12093 schedGroup = (queue == mFgBroadcastQueue) 12094 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12095 app.adjType = "broadcast"; 12096 } else if (app.executingServices.size() > 0) { 12097 // An app that is currently executing a service callback also 12098 // counts as being in the foreground. 12099 adj = ProcessList.FOREGROUND_APP_ADJ; 12100 schedGroup = Process.THREAD_GROUP_DEFAULT; 12101 app.adjType = "exec-service"; 12102 } else { 12103 // Assume process is hidden (has activities); we will correct 12104 // later if this is not the case. 12105 adj = hiddenAdj; 12106 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12107 app.hidden = true; 12108 app.adjType = "bg-activities"; 12109 } 12110 12111 boolean hasStoppingActivities = false; 12112 12113 // Examine all activities if not already foreground. 12114 if (!foregroundActivities && activitiesSize > 0) { 12115 for (int j = 0; j < activitiesSize; j++) { 12116 final ActivityRecord r = app.activities.get(j); 12117 if (r.visible) { 12118 // App has a visible activity; only upgrade adjustment. 12119 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12120 adj = ProcessList.VISIBLE_APP_ADJ; 12121 app.adjType = "visible"; 12122 } 12123 schedGroup = Process.THREAD_GROUP_DEFAULT; 12124 app.hidden = false; 12125 app.hasActivities = true; 12126 foregroundActivities = true; 12127 break; 12128 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12129 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12130 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12131 app.adjType = "pausing"; 12132 } 12133 app.hidden = false; 12134 foregroundActivities = true; 12135 } else if (r.state == ActivityState.STOPPING) { 12136 // We will apply the actual adjustment later, because 12137 // we want to allow this process to immediately go through 12138 // any memory trimming that is in effect. 12139 app.hidden = false; 12140 foregroundActivities = true; 12141 hasStoppingActivities = true; 12142 } 12143 if (r.app == app) { 12144 app.hasActivities = true; 12145 } 12146 } 12147 } 12148 12149 if (adj == hiddenAdj && !app.hasActivities) { 12150 // Whoops, this process is completely empty as far as we know 12151 // at this point. 12152 adj = emptyAdj; 12153 app.empty = true; 12154 app.adjType = "bg-empty"; 12155 } 12156 12157 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12158 if (app.foregroundServices) { 12159 // The user is aware of this app, so make it visible. 12160 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12161 app.hidden = false; 12162 app.adjType = "foreground-service"; 12163 schedGroup = Process.THREAD_GROUP_DEFAULT; 12164 } else if (app.forcingToForeground != null) { 12165 // The user is aware of this app, so make it visible. 12166 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12167 app.hidden = false; 12168 app.adjType = "force-foreground"; 12169 app.adjSource = app.forcingToForeground; 12170 schedGroup = Process.THREAD_GROUP_DEFAULT; 12171 } 12172 } 12173 12174 if (app.foregroundServices) { 12175 interesting = true; 12176 } 12177 12178 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12179 // We don't want to kill the current heavy-weight process. 12180 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12181 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12182 app.hidden = false; 12183 app.adjType = "heavy"; 12184 } 12185 12186 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12187 // This process is hosting what we currently consider to be the 12188 // home app, so we don't want to let it go into the background. 12189 adj = ProcessList.HOME_APP_ADJ; 12190 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12191 app.hidden = false; 12192 app.adjType = "home"; 12193 } 12194 12195 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12196 && app.activities.size() > 0) { 12197 // This was the previous process that showed UI to the user. 12198 // We want to try to keep it around more aggressively, to give 12199 // a good experience around switching between two apps. 12200 adj = ProcessList.PREVIOUS_APP_ADJ; 12201 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12202 app.hidden = false; 12203 app.adjType = "previous"; 12204 } 12205 12206 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12207 + " reason=" + app.adjType); 12208 12209 // By default, we use the computed adjustment. It may be changed if 12210 // there are applications dependent on our services or providers, but 12211 // this gives us a baseline and makes sure we don't get into an 12212 // infinite recursion. 12213 app.adjSeq = mAdjSeq; 12214 app.curRawAdj = app.nonStoppingAdj = adj; 12215 12216 if (mBackupTarget != null && app == mBackupTarget.app) { 12217 // If possible we want to avoid killing apps while they're being backed up 12218 if (adj > ProcessList.BACKUP_APP_ADJ) { 12219 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12220 adj = ProcessList.BACKUP_APP_ADJ; 12221 app.adjType = "backup"; 12222 app.hidden = false; 12223 } 12224 } 12225 12226 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12227 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12228 final long now = SystemClock.uptimeMillis(); 12229 // This process is more important if the top activity is 12230 // bound to the service. 12231 Iterator<ServiceRecord> jt = app.services.iterator(); 12232 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12233 ServiceRecord s = jt.next(); 12234 if (s.startRequested) { 12235 if (app.hasShownUi && app != mHomeProcess) { 12236 // If this process has shown some UI, let it immediately 12237 // go to the LRU list because it may be pretty heavy with 12238 // UI stuff. We'll tag it with a label just to help 12239 // debug and understand what is going on. 12240 if (adj > ProcessList.SERVICE_ADJ) { 12241 app.adjType = "started-bg-ui-services"; 12242 } 12243 } else { 12244 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12245 // This service has seen some activity within 12246 // recent memory, so we will keep its process ahead 12247 // of the background processes. 12248 if (adj > ProcessList.SERVICE_ADJ) { 12249 adj = ProcessList.SERVICE_ADJ; 12250 app.adjType = "started-services"; 12251 app.hidden = false; 12252 } 12253 } 12254 // If we have let the service slide into the background 12255 // state, still have some text describing what it is doing 12256 // even though the service no longer has an impact. 12257 if (adj > ProcessList.SERVICE_ADJ) { 12258 app.adjType = "started-bg-services"; 12259 } 12260 } 12261 // Don't kill this process because it is doing work; it 12262 // has said it is doing work. 12263 app.keeping = true; 12264 } 12265 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12266 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12267 Iterator<ArrayList<ConnectionRecord>> kt 12268 = s.connections.values().iterator(); 12269 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12270 ArrayList<ConnectionRecord> clist = kt.next(); 12271 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12272 // XXX should compute this based on the max of 12273 // all connected clients. 12274 ConnectionRecord cr = clist.get(i); 12275 if (cr.binding.client == app) { 12276 // Binding to ourself is not interesting. 12277 continue; 12278 } 12279 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12280 ProcessRecord client = cr.binding.client; 12281 int clientAdj = adj; 12282 int myHiddenAdj = hiddenAdj; 12283 if (myHiddenAdj > client.hiddenAdj) { 12284 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12285 myHiddenAdj = client.hiddenAdj; 12286 } else { 12287 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12288 } 12289 } 12290 int myEmptyAdj = emptyAdj; 12291 if (myEmptyAdj > client.emptyAdj) { 12292 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12293 myEmptyAdj = client.emptyAdj; 12294 } else { 12295 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12296 } 12297 } 12298 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12299 myEmptyAdj, TOP_APP, true, doingAll); 12300 String adjType = null; 12301 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12302 // Not doing bind OOM management, so treat 12303 // this guy more like a started service. 12304 if (app.hasShownUi && app != mHomeProcess) { 12305 // If this process has shown some UI, let it immediately 12306 // go to the LRU list because it may be pretty heavy with 12307 // UI stuff. We'll tag it with a label just to help 12308 // debug and understand what is going on. 12309 if (adj > clientAdj) { 12310 adjType = "bound-bg-ui-services"; 12311 } 12312 app.hidden = false; 12313 clientAdj = adj; 12314 } else { 12315 if (now >= (s.lastActivity 12316 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12317 // This service has not seen activity within 12318 // recent memory, so allow it to drop to the 12319 // LRU list if there is no other reason to keep 12320 // it around. We'll also tag it with a label just 12321 // to help debug and undertand what is going on. 12322 if (adj > clientAdj) { 12323 adjType = "bound-bg-services"; 12324 } 12325 clientAdj = adj; 12326 } 12327 } 12328 } 12329 if (adj > clientAdj) { 12330 // If this process has recently shown UI, and 12331 // the process that is binding to it is less 12332 // important than being visible, then we don't 12333 // care about the binding as much as we care 12334 // about letting this process get into the LRU 12335 // list to be killed and restarted if needed for 12336 // memory. 12337 if (app.hasShownUi && app != mHomeProcess 12338 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12339 adjType = "bound-bg-ui-services"; 12340 } else { 12341 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12342 |Context.BIND_IMPORTANT)) != 0) { 12343 adj = clientAdj; 12344 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12345 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12346 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12347 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12348 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12349 adj = clientAdj; 12350 } else { 12351 app.pendingUiClean = true; 12352 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12353 adj = ProcessList.VISIBLE_APP_ADJ; 12354 } 12355 } 12356 if (!client.hidden) { 12357 app.hidden = false; 12358 } 12359 if (client.keeping) { 12360 app.keeping = true; 12361 } 12362 adjType = "service"; 12363 } 12364 } 12365 if (adjType != null) { 12366 app.adjType = adjType; 12367 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12368 .REASON_SERVICE_IN_USE; 12369 app.adjSource = cr.binding.client; 12370 app.adjSourceOom = clientAdj; 12371 app.adjTarget = s.name; 12372 } 12373 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12374 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12375 schedGroup = Process.THREAD_GROUP_DEFAULT; 12376 } 12377 } 12378 } 12379 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12380 ActivityRecord a = cr.activity; 12381 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12382 (a.visible || a.state == ActivityState.RESUMED 12383 || a.state == ActivityState.PAUSING)) { 12384 adj = ProcessList.FOREGROUND_APP_ADJ; 12385 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12386 schedGroup = Process.THREAD_GROUP_DEFAULT; 12387 } 12388 app.hidden = false; 12389 app.adjType = "service"; 12390 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12391 .REASON_SERVICE_IN_USE; 12392 app.adjSource = a; 12393 app.adjSourceOom = adj; 12394 app.adjTarget = s.name; 12395 } 12396 } 12397 } 12398 } 12399 } 12400 } 12401 12402 // Finally, if this process has active services running in it, we 12403 // would like to avoid killing it unless it would prevent the current 12404 // application from running. By default we put the process in 12405 // with the rest of the background processes; as we scan through 12406 // its services we may bump it up from there. 12407 if (adj > hiddenAdj) { 12408 adj = hiddenAdj; 12409 app.hidden = false; 12410 app.adjType = "bg-services"; 12411 } 12412 } 12413 12414 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12415 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12416 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12417 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12418 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12419 ContentProviderRecord cpr = jt.next(); 12420 for (int i = cpr.connections.size()-1; 12421 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12422 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12423 i--) { 12424 ContentProviderConnection conn = cpr.connections.get(i); 12425 ProcessRecord client = conn.client; 12426 if (client == app) { 12427 // Being our own client is not interesting. 12428 continue; 12429 } 12430 int myHiddenAdj = hiddenAdj; 12431 if (myHiddenAdj > client.hiddenAdj) { 12432 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12433 myHiddenAdj = client.hiddenAdj; 12434 } else { 12435 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12436 } 12437 } 12438 int myEmptyAdj = emptyAdj; 12439 if (myEmptyAdj > client.emptyAdj) { 12440 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12441 myEmptyAdj = client.emptyAdj; 12442 } else { 12443 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12444 } 12445 } 12446 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12447 myEmptyAdj, TOP_APP, true, doingAll); 12448 if (adj > clientAdj) { 12449 if (app.hasShownUi && app != mHomeProcess 12450 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12451 app.adjType = "bg-ui-provider"; 12452 } else { 12453 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12454 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12455 app.adjType = "provider"; 12456 } 12457 if (!client.hidden) { 12458 app.hidden = false; 12459 } 12460 if (client.keeping) { 12461 app.keeping = true; 12462 } 12463 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12464 .REASON_PROVIDER_IN_USE; 12465 app.adjSource = client; 12466 app.adjSourceOom = clientAdj; 12467 app.adjTarget = cpr.name; 12468 } 12469 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12470 schedGroup = Process.THREAD_GROUP_DEFAULT; 12471 } 12472 } 12473 // If the provider has external (non-framework) process 12474 // dependencies, ensure that its adjustment is at least 12475 // FOREGROUND_APP_ADJ. 12476 if (cpr.hasExternalProcessHandles()) { 12477 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12478 adj = ProcessList.FOREGROUND_APP_ADJ; 12479 schedGroup = Process.THREAD_GROUP_DEFAULT; 12480 app.hidden = false; 12481 app.keeping = true; 12482 app.adjType = "provider"; 12483 app.adjTarget = cpr.name; 12484 } 12485 } 12486 } 12487 } 12488 12489 if (adj == ProcessList.SERVICE_ADJ) { 12490 if (doingAll) { 12491 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12492 mNewNumServiceProcs++; 12493 } 12494 if (app.serviceb) { 12495 adj = ProcessList.SERVICE_B_ADJ; 12496 } 12497 } else { 12498 app.serviceb = false; 12499 } 12500 12501 app.nonStoppingAdj = adj; 12502 12503 if (hasStoppingActivities) { 12504 // Only upgrade adjustment. 12505 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12506 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12507 app.adjType = "stopping"; 12508 } 12509 } 12510 12511 app.curRawAdj = adj; 12512 12513 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12514 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12515 if (adj > app.maxAdj) { 12516 adj = app.maxAdj; 12517 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12518 schedGroup = Process.THREAD_GROUP_DEFAULT; 12519 } 12520 } 12521 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12522 app.keeping = true; 12523 } 12524 12525 if (app.hasAboveClient) { 12526 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12527 // then we need to drop its adjustment to be lower than the service's 12528 // in order to honor the request. We want to drop it by one adjustment 12529 // level... but there is special meaning applied to various levels so 12530 // we will skip some of them. 12531 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12532 // System process will not get dropped, ever 12533 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12534 adj = ProcessList.VISIBLE_APP_ADJ; 12535 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12536 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12537 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12538 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12539 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12540 adj++; 12541 } 12542 } 12543 12544 int importance = app.memImportance; 12545 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12546 app.curAdj = adj; 12547 app.curSchedGroup = schedGroup; 12548 if (!interesting) { 12549 // For this reporting, if there is not something explicitly 12550 // interesting in this process then we will push it to the 12551 // background importance. 12552 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12553 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12554 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12555 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12556 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12557 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12558 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12559 } else if (adj >= ProcessList.SERVICE_ADJ) { 12560 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12561 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12562 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12563 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12564 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12565 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12566 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12567 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12568 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12569 } else { 12570 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12571 } 12572 } 12573 12574 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12575 if (foregroundActivities != app.foregroundActivities) { 12576 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12577 } 12578 if (changes != 0) { 12579 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12580 app.memImportance = importance; 12581 app.foregroundActivities = foregroundActivities; 12582 int i = mPendingProcessChanges.size()-1; 12583 ProcessChangeItem item = null; 12584 while (i >= 0) { 12585 item = mPendingProcessChanges.get(i); 12586 if (item.pid == app.pid) { 12587 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12588 break; 12589 } 12590 i--; 12591 } 12592 if (i < 0) { 12593 // No existing item in pending changes; need a new one. 12594 final int NA = mAvailProcessChanges.size(); 12595 if (NA > 0) { 12596 item = mAvailProcessChanges.remove(NA-1); 12597 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12598 } else { 12599 item = new ProcessChangeItem(); 12600 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12601 } 12602 item.changes = 0; 12603 item.pid = app.pid; 12604 item.uid = app.info.uid; 12605 if (mPendingProcessChanges.size() == 0) { 12606 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12607 "*** Enqueueing dispatch processes changed!"); 12608 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12609 } 12610 mPendingProcessChanges.add(item); 12611 } 12612 item.changes |= changes; 12613 item.importance = importance; 12614 item.foregroundActivities = foregroundActivities; 12615 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12616 + Integer.toHexString(System.identityHashCode(item)) 12617 + " " + app.toShortString() + ": changes=" + item.changes 12618 + " importance=" + item.importance 12619 + " foreground=" + item.foregroundActivities 12620 + " type=" + app.adjType + " source=" + app.adjSource 12621 + " target=" + app.adjTarget); 12622 } 12623 12624 return app.curRawAdj; 12625 } 12626 12627 /** 12628 * Ask a given process to GC right now. 12629 */ 12630 final void performAppGcLocked(ProcessRecord app) { 12631 try { 12632 app.lastRequestedGc = SystemClock.uptimeMillis(); 12633 if (app.thread != null) { 12634 if (app.reportLowMemory) { 12635 app.reportLowMemory = false; 12636 app.thread.scheduleLowMemory(); 12637 } else { 12638 app.thread.processInBackground(); 12639 } 12640 } 12641 } catch (Exception e) { 12642 // whatever. 12643 } 12644 } 12645 12646 /** 12647 * Returns true if things are idle enough to perform GCs. 12648 */ 12649 private final boolean canGcNowLocked() { 12650 boolean processingBroadcasts = false; 12651 for (BroadcastQueue q : mBroadcastQueues) { 12652 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12653 processingBroadcasts = true; 12654 } 12655 } 12656 return !processingBroadcasts 12657 && (mSleeping || (mMainStack.mResumedActivity != null && 12658 mMainStack.mResumedActivity.idle)); 12659 } 12660 12661 /** 12662 * Perform GCs on all processes that are waiting for it, but only 12663 * if things are idle. 12664 */ 12665 final void performAppGcsLocked() { 12666 final int N = mProcessesToGc.size(); 12667 if (N <= 0) { 12668 return; 12669 } 12670 if (canGcNowLocked()) { 12671 while (mProcessesToGc.size() > 0) { 12672 ProcessRecord proc = mProcessesToGc.remove(0); 12673 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12674 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12675 <= SystemClock.uptimeMillis()) { 12676 // To avoid spamming the system, we will GC processes one 12677 // at a time, waiting a few seconds between each. 12678 performAppGcLocked(proc); 12679 scheduleAppGcsLocked(); 12680 return; 12681 } else { 12682 // It hasn't been long enough since we last GCed this 12683 // process... put it in the list to wait for its time. 12684 addProcessToGcListLocked(proc); 12685 break; 12686 } 12687 } 12688 } 12689 12690 scheduleAppGcsLocked(); 12691 } 12692 } 12693 12694 /** 12695 * If all looks good, perform GCs on all processes waiting for them. 12696 */ 12697 final void performAppGcsIfAppropriateLocked() { 12698 if (canGcNowLocked()) { 12699 performAppGcsLocked(); 12700 return; 12701 } 12702 // Still not idle, wait some more. 12703 scheduleAppGcsLocked(); 12704 } 12705 12706 /** 12707 * Schedule the execution of all pending app GCs. 12708 */ 12709 final void scheduleAppGcsLocked() { 12710 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12711 12712 if (mProcessesToGc.size() > 0) { 12713 // Schedule a GC for the time to the next process. 12714 ProcessRecord proc = mProcessesToGc.get(0); 12715 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12716 12717 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12718 long now = SystemClock.uptimeMillis(); 12719 if (when < (now+GC_TIMEOUT)) { 12720 when = now + GC_TIMEOUT; 12721 } 12722 mHandler.sendMessageAtTime(msg, when); 12723 } 12724 } 12725 12726 /** 12727 * Add a process to the array of processes waiting to be GCed. Keeps the 12728 * list in sorted order by the last GC time. The process can't already be 12729 * on the list. 12730 */ 12731 final void addProcessToGcListLocked(ProcessRecord proc) { 12732 boolean added = false; 12733 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12734 if (mProcessesToGc.get(i).lastRequestedGc < 12735 proc.lastRequestedGc) { 12736 added = true; 12737 mProcessesToGc.add(i+1, proc); 12738 break; 12739 } 12740 } 12741 if (!added) { 12742 mProcessesToGc.add(0, proc); 12743 } 12744 } 12745 12746 /** 12747 * Set up to ask a process to GC itself. This will either do it 12748 * immediately, or put it on the list of processes to gc the next 12749 * time things are idle. 12750 */ 12751 final void scheduleAppGcLocked(ProcessRecord app) { 12752 long now = SystemClock.uptimeMillis(); 12753 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12754 return; 12755 } 12756 if (!mProcessesToGc.contains(app)) { 12757 addProcessToGcListLocked(app); 12758 scheduleAppGcsLocked(); 12759 } 12760 } 12761 12762 final void checkExcessivePowerUsageLocked(boolean doKills) { 12763 updateCpuStatsNow(); 12764 12765 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12766 boolean doWakeKills = doKills; 12767 boolean doCpuKills = doKills; 12768 if (mLastPowerCheckRealtime == 0) { 12769 doWakeKills = false; 12770 } 12771 if (mLastPowerCheckUptime == 0) { 12772 doCpuKills = false; 12773 } 12774 if (stats.isScreenOn()) { 12775 doWakeKills = false; 12776 } 12777 final long curRealtime = SystemClock.elapsedRealtime(); 12778 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12779 final long curUptime = SystemClock.uptimeMillis(); 12780 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12781 mLastPowerCheckRealtime = curRealtime; 12782 mLastPowerCheckUptime = curUptime; 12783 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12784 doWakeKills = false; 12785 } 12786 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12787 doCpuKills = false; 12788 } 12789 int i = mLruProcesses.size(); 12790 while (i > 0) { 12791 i--; 12792 ProcessRecord app = mLruProcesses.get(i); 12793 if (!app.keeping) { 12794 long wtime; 12795 synchronized (stats) { 12796 wtime = stats.getProcessWakeTime(app.info.uid, 12797 app.pid, curRealtime); 12798 } 12799 long wtimeUsed = wtime - app.lastWakeTime; 12800 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12801 if (DEBUG_POWER) { 12802 StringBuilder sb = new StringBuilder(128); 12803 sb.append("Wake for "); 12804 app.toShortString(sb); 12805 sb.append(": over "); 12806 TimeUtils.formatDuration(realtimeSince, sb); 12807 sb.append(" used "); 12808 TimeUtils.formatDuration(wtimeUsed, sb); 12809 sb.append(" ("); 12810 sb.append((wtimeUsed*100)/realtimeSince); 12811 sb.append("%)"); 12812 Slog.i(TAG, sb.toString()); 12813 sb.setLength(0); 12814 sb.append("CPU for "); 12815 app.toShortString(sb); 12816 sb.append(": over "); 12817 TimeUtils.formatDuration(uptimeSince, sb); 12818 sb.append(" used "); 12819 TimeUtils.formatDuration(cputimeUsed, sb); 12820 sb.append(" ("); 12821 sb.append((cputimeUsed*100)/uptimeSince); 12822 sb.append("%)"); 12823 Slog.i(TAG, sb.toString()); 12824 } 12825 // If a process has held a wake lock for more 12826 // than 50% of the time during this period, 12827 // that sounds bad. Kill! 12828 if (doWakeKills && realtimeSince > 0 12829 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12830 synchronized (stats) { 12831 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12832 realtimeSince, wtimeUsed); 12833 } 12834 Slog.w(TAG, "Excessive wake lock in " + app.processName 12835 + " (pid " + app.pid + "): held " + wtimeUsed 12836 + " during " + realtimeSince); 12837 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12838 app.processName, app.setAdj, "excessive wake lock"); 12839 Process.killProcessQuiet(app.pid); 12840 } else if (doCpuKills && uptimeSince > 0 12841 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12842 synchronized (stats) { 12843 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12844 uptimeSince, cputimeUsed); 12845 } 12846 Slog.w(TAG, "Excessive CPU in " + app.processName 12847 + " (pid " + app.pid + "): used " + cputimeUsed 12848 + " during " + uptimeSince); 12849 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12850 app.processName, app.setAdj, "excessive cpu"); 12851 Process.killProcessQuiet(app.pid); 12852 } else { 12853 app.lastWakeTime = wtime; 12854 app.lastCpuTime = app.curCpuTime; 12855 } 12856 } 12857 } 12858 } 12859 12860 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12861 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12862 app.hiddenAdj = hiddenAdj; 12863 app.emptyAdj = emptyAdj; 12864 12865 if (app.thread == null) { 12866 return false; 12867 } 12868 12869 final boolean wasKeeping = app.keeping; 12870 12871 boolean success = true; 12872 12873 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12874 12875 if (app.curRawAdj != app.setRawAdj) { 12876 if (wasKeeping && !app.keeping) { 12877 // This app is no longer something we want to keep. Note 12878 // its current wake lock time to later know to kill it if 12879 // it is not behaving well. 12880 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12881 synchronized (stats) { 12882 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12883 app.pid, SystemClock.elapsedRealtime()); 12884 } 12885 app.lastCpuTime = app.curCpuTime; 12886 } 12887 12888 app.setRawAdj = app.curRawAdj; 12889 } 12890 12891 if (app.curAdj != app.setAdj) { 12892 if (Process.setOomAdj(app.pid, app.curAdj)) { 12893 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12894 TAG, "Set " + app.pid + " " + app.processName + 12895 " adj " + app.curAdj + ": " + app.adjType); 12896 app.setAdj = app.curAdj; 12897 } else { 12898 success = false; 12899 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12900 } 12901 } 12902 if (app.setSchedGroup != app.curSchedGroup) { 12903 app.setSchedGroup = app.curSchedGroup; 12904 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12905 "Setting process group of " + app.processName 12906 + " to " + app.curSchedGroup); 12907 if (app.waitingToKill != null && 12908 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12909 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12910 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12911 app.processName, app.setAdj, app.waitingToKill); 12912 app.killedBackground = true; 12913 Process.killProcessQuiet(app.pid); 12914 success = false; 12915 } else { 12916 if (true) { 12917 long oldId = Binder.clearCallingIdentity(); 12918 try { 12919 Process.setProcessGroup(app.pid, app.curSchedGroup); 12920 } catch (Exception e) { 12921 Slog.w(TAG, "Failed setting process group of " + app.pid 12922 + " to " + app.curSchedGroup); 12923 e.printStackTrace(); 12924 } finally { 12925 Binder.restoreCallingIdentity(oldId); 12926 } 12927 } else { 12928 if (app.thread != null) { 12929 try { 12930 app.thread.setSchedulingGroup(app.curSchedGroup); 12931 } catch (RemoteException e) { 12932 } 12933 } 12934 } 12935 } 12936 } 12937 return success; 12938 } 12939 12940 private final ActivityRecord resumedAppLocked() { 12941 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12942 if (resumedActivity == null || resumedActivity.app == null) { 12943 resumedActivity = mMainStack.mPausingActivity; 12944 if (resumedActivity == null || resumedActivity.app == null) { 12945 resumedActivity = mMainStack.topRunningActivityLocked(null); 12946 } 12947 } 12948 return resumedActivity; 12949 } 12950 12951 final boolean updateOomAdjLocked(ProcessRecord app) { 12952 final ActivityRecord TOP_ACT = resumedAppLocked(); 12953 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12954 int curAdj = app.curAdj; 12955 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12956 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12957 12958 mAdjSeq++; 12959 12960 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 12961 TOP_APP, false); 12962 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12963 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12964 if (nowHidden != wasHidden) { 12965 // Changed to/from hidden state, so apps after it in the LRU 12966 // list may also be changed. 12967 updateOomAdjLocked(); 12968 } 12969 return success; 12970 } 12971 12972 final void updateOomAdjLocked() { 12973 final ActivityRecord TOP_ACT = resumedAppLocked(); 12974 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12975 12976 if (false) { 12977 RuntimeException e = new RuntimeException(); 12978 e.fillInStackTrace(); 12979 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12980 } 12981 12982 mAdjSeq++; 12983 mNewNumServiceProcs = 0; 12984 12985 // Let's determine how many processes we have running vs. 12986 // how many slots we have for background processes; we may want 12987 // to put multiple processes in a slot of there are enough of 12988 // them. 12989 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 12990 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 12991 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 12992 if (emptyFactor < 1) emptyFactor = 1; 12993 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 12994 if (hiddenFactor < 1) hiddenFactor = 1; 12995 int stepHidden = 0; 12996 int stepEmpty = 0; 12997 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 12998 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 12999 int numHidden = 0; 13000 int numEmpty = 0; 13001 int numTrimming = 0; 13002 13003 mNumNonHiddenProcs = 0; 13004 mNumHiddenProcs = 0; 13005 13006 // First update the OOM adjustment for each of the 13007 // application processes based on their current state. 13008 int i = mLruProcesses.size(); 13009 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13010 int nextHiddenAdj = curHiddenAdj+1; 13011 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13012 int nextEmptyAdj = curEmptyAdj+2; 13013 while (i > 0) { 13014 i--; 13015 ProcessRecord app = mLruProcesses.get(i); 13016 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13017 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13018 if (!app.killedBackground) { 13019 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13020 // This process was assigned as a hidden process... step the 13021 // hidden level. 13022 mNumHiddenProcs++; 13023 if (curHiddenAdj != nextHiddenAdj) { 13024 stepHidden++; 13025 if (stepHidden >= hiddenFactor) { 13026 stepHidden = 0; 13027 curHiddenAdj = nextHiddenAdj; 13028 nextHiddenAdj += 2; 13029 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13030 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13031 } 13032 } 13033 } 13034 numHidden++; 13035 if (numHidden > hiddenProcessLimit) { 13036 Slog.i(TAG, "No longer want " + app.processName 13037 + " (pid " + app.pid + "): hidden #" + numHidden); 13038 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13039 app.processName, app.setAdj, "too many background"); 13040 app.killedBackground = true; 13041 Process.killProcessQuiet(app.pid); 13042 } 13043 } else { 13044 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13045 // This process was assigned as an empty process... step the 13046 // empty level. 13047 if (curEmptyAdj != nextEmptyAdj) { 13048 stepEmpty++; 13049 if (stepEmpty >= emptyFactor) { 13050 stepEmpty = 0; 13051 curEmptyAdj = nextEmptyAdj; 13052 nextEmptyAdj += 2; 13053 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13054 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13055 } 13056 } 13057 } 13058 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13059 mNumNonHiddenProcs++; 13060 } 13061 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13062 numEmpty++; 13063 if (numEmpty > emptyProcessLimit) { 13064 Slog.i(TAG, "No longer want " + app.processName 13065 + " (pid " + app.pid + "): empty #" + numEmpty); 13066 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13067 app.processName, app.setAdj, "too many background"); 13068 app.killedBackground = true; 13069 Process.killProcessQuiet(app.pid); 13070 } 13071 } 13072 } 13073 if (app.isolated && app.services.size() <= 0) { 13074 // If this is an isolated process, and there are no 13075 // services running in it, then the process is no longer 13076 // needed. We agressively kill these because we can by 13077 // definition not re-use the same process again, and it is 13078 // good to avoid having whatever code was running in them 13079 // left sitting around after no longer needed. 13080 Slog.i(TAG, "Isolated process " + app.processName 13081 + " (pid " + app.pid + ") no longer needed"); 13082 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13083 app.processName, app.setAdj, "isolated not needed"); 13084 app.killedBackground = true; 13085 Process.killProcessQuiet(app.pid); 13086 } 13087 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13088 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13089 && !app.killedBackground) { 13090 numTrimming++; 13091 } 13092 } 13093 } 13094 13095 mNumServiceProcs = mNewNumServiceProcs; 13096 13097 // Now determine the memory trimming level of background processes. 13098 // Unfortunately we need to start at the back of the list to do this 13099 // properly. We only do this if the number of background apps we 13100 // are managing to keep around is less than half the maximum we desire; 13101 // if we are keeping a good number around, we'll let them use whatever 13102 // memory they want. 13103 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13104 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13105 final int numHiddenAndEmpty = numHidden + numEmpty; 13106 final int N = mLruProcesses.size(); 13107 int factor = numTrimming/3; 13108 int minFactor = 2; 13109 if (mHomeProcess != null) minFactor++; 13110 if (mPreviousProcess != null) minFactor++; 13111 if (factor < minFactor) factor = minFactor; 13112 int step = 0; 13113 int fgTrimLevel; 13114 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13115 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13116 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13117 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13118 } else { 13119 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13120 } 13121 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13122 for (i=0; i<N; i++) { 13123 ProcessRecord app = mLruProcesses.get(i); 13124 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13125 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13126 && !app.killedBackground) { 13127 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13128 try { 13129 app.thread.scheduleTrimMemory(curLevel); 13130 } catch (RemoteException e) { 13131 } 13132 if (false) { 13133 // For now we won't do this; our memory trimming seems 13134 // to be good enough at this point that destroying 13135 // activities causes more harm than good. 13136 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13137 && app != mHomeProcess && app != mPreviousProcess) { 13138 // Need to do this on its own message because the stack may not 13139 // be in a consistent state at this point. 13140 // For these apps we will also finish their activities 13141 // to help them free memory. 13142 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13143 } 13144 } 13145 } 13146 app.trimMemoryLevel = curLevel; 13147 step++; 13148 if (step >= factor) { 13149 step = 0; 13150 switch (curLevel) { 13151 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13152 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13153 break; 13154 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13155 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13156 break; 13157 } 13158 } 13159 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13160 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13161 && app.thread != null) { 13162 try { 13163 app.thread.scheduleTrimMemory( 13164 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13165 } catch (RemoteException e) { 13166 } 13167 } 13168 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13169 } else { 13170 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13171 && app.pendingUiClean) { 13172 // If this application is now in the background and it 13173 // had done UI, then give it the special trim level to 13174 // have it free UI resources. 13175 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13176 if (app.trimMemoryLevel < level && app.thread != null) { 13177 try { 13178 app.thread.scheduleTrimMemory(level); 13179 } catch (RemoteException e) { 13180 } 13181 } 13182 app.pendingUiClean = false; 13183 } 13184 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13185 try { 13186 app.thread.scheduleTrimMemory(fgTrimLevel); 13187 } catch (RemoteException e) { 13188 } 13189 } 13190 app.trimMemoryLevel = fgTrimLevel; 13191 } 13192 } 13193 } else { 13194 final int N = mLruProcesses.size(); 13195 for (i=0; i<N; i++) { 13196 ProcessRecord app = mLruProcesses.get(i); 13197 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13198 && app.pendingUiClean) { 13199 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13200 && app.thread != null) { 13201 try { 13202 app.thread.scheduleTrimMemory( 13203 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13204 } catch (RemoteException e) { 13205 } 13206 } 13207 app.pendingUiClean = false; 13208 } 13209 app.trimMemoryLevel = 0; 13210 } 13211 } 13212 13213 if (mAlwaysFinishActivities) { 13214 // Need to do this on its own message because the stack may not 13215 // be in a consistent state at this point. 13216 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13217 } 13218 } 13219 13220 final void trimApplications() { 13221 synchronized (this) { 13222 int i; 13223 13224 // First remove any unused application processes whose package 13225 // has been removed. 13226 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13227 final ProcessRecord app = mRemovedProcesses.get(i); 13228 if (app.activities.size() == 0 13229 && app.curReceiver == null && app.services.size() == 0) { 13230 Slog.i( 13231 TAG, "Exiting empty application process " 13232 + app.processName + " (" 13233 + (app.thread != null ? app.thread.asBinder() : null) 13234 + ")\n"); 13235 if (app.pid > 0 && app.pid != MY_PID) { 13236 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13237 app.processName, app.setAdj, "empty"); 13238 Process.killProcessQuiet(app.pid); 13239 } else { 13240 try { 13241 app.thread.scheduleExit(); 13242 } catch (Exception e) { 13243 // Ignore exceptions. 13244 } 13245 } 13246 cleanUpApplicationRecordLocked(app, false, true, -1); 13247 mRemovedProcesses.remove(i); 13248 13249 if (app.persistent) { 13250 if (app.persistent) { 13251 addAppLocked(app.info, false); 13252 } 13253 } 13254 } 13255 } 13256 13257 // Now update the oom adj for all processes. 13258 updateOomAdjLocked(); 13259 } 13260 } 13261 13262 /** This method sends the specified signal to each of the persistent apps */ 13263 public void signalPersistentProcesses(int sig) throws RemoteException { 13264 if (sig != Process.SIGNAL_USR1) { 13265 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13266 } 13267 13268 synchronized (this) { 13269 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13270 != PackageManager.PERMISSION_GRANTED) { 13271 throw new SecurityException("Requires permission " 13272 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13273 } 13274 13275 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13276 ProcessRecord r = mLruProcesses.get(i); 13277 if (r.thread != null && r.persistent) { 13278 Process.sendSignal(r.pid, sig); 13279 } 13280 } 13281 } 13282 } 13283 13284 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13285 if (proc == null || proc == mProfileProc) { 13286 proc = mProfileProc; 13287 path = mProfileFile; 13288 profileType = mProfileType; 13289 clearProfilerLocked(); 13290 } 13291 if (proc == null) { 13292 return; 13293 } 13294 try { 13295 proc.thread.profilerControl(false, path, null, profileType); 13296 } catch (RemoteException e) { 13297 throw new IllegalStateException("Process disappeared"); 13298 } 13299 } 13300 13301 private void clearProfilerLocked() { 13302 if (mProfileFd != null) { 13303 try { 13304 mProfileFd.close(); 13305 } catch (IOException e) { 13306 } 13307 } 13308 mProfileApp = null; 13309 mProfileProc = null; 13310 mProfileFile = null; 13311 mProfileType = 0; 13312 mAutoStopProfiler = false; 13313 } 13314 13315 public boolean profileControl(String process, boolean start, 13316 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13317 13318 try { 13319 synchronized (this) { 13320 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13321 // its own permission. 13322 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13323 != PackageManager.PERMISSION_GRANTED) { 13324 throw new SecurityException("Requires permission " 13325 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13326 } 13327 13328 if (start && fd == null) { 13329 throw new IllegalArgumentException("null fd"); 13330 } 13331 13332 ProcessRecord proc = null; 13333 if (process != null) { 13334 try { 13335 int pid = Integer.parseInt(process); 13336 synchronized (mPidsSelfLocked) { 13337 proc = mPidsSelfLocked.get(pid); 13338 } 13339 } catch (NumberFormatException e) { 13340 } 13341 13342 if (proc == null) { 13343 HashMap<String, SparseArray<ProcessRecord>> all 13344 = mProcessNames.getMap(); 13345 SparseArray<ProcessRecord> procs = all.get(process); 13346 if (procs != null && procs.size() > 0) { 13347 proc = procs.valueAt(0); 13348 } 13349 } 13350 } 13351 13352 if (start && (proc == null || proc.thread == null)) { 13353 throw new IllegalArgumentException("Unknown process: " + process); 13354 } 13355 13356 if (start) { 13357 stopProfilerLocked(null, null, 0); 13358 setProfileApp(proc.info, proc.processName, path, fd, false); 13359 mProfileProc = proc; 13360 mProfileType = profileType; 13361 try { 13362 fd = fd.dup(); 13363 } catch (IOException e) { 13364 fd = null; 13365 } 13366 proc.thread.profilerControl(start, path, fd, profileType); 13367 fd = null; 13368 mProfileFd = null; 13369 } else { 13370 stopProfilerLocked(proc, path, profileType); 13371 if (fd != null) { 13372 try { 13373 fd.close(); 13374 } catch (IOException e) { 13375 } 13376 } 13377 } 13378 13379 return true; 13380 } 13381 } catch (RemoteException e) { 13382 throw new IllegalStateException("Process disappeared"); 13383 } finally { 13384 if (fd != null) { 13385 try { 13386 fd.close(); 13387 } catch (IOException e) { 13388 } 13389 } 13390 } 13391 } 13392 13393 public boolean dumpHeap(String process, boolean managed, 13394 String path, ParcelFileDescriptor fd) throws RemoteException { 13395 13396 try { 13397 synchronized (this) { 13398 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13399 // its own permission (same as profileControl). 13400 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13401 != PackageManager.PERMISSION_GRANTED) { 13402 throw new SecurityException("Requires permission " 13403 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13404 } 13405 13406 if (fd == null) { 13407 throw new IllegalArgumentException("null fd"); 13408 } 13409 13410 ProcessRecord proc = null; 13411 try { 13412 int pid = Integer.parseInt(process); 13413 synchronized (mPidsSelfLocked) { 13414 proc = mPidsSelfLocked.get(pid); 13415 } 13416 } catch (NumberFormatException e) { 13417 } 13418 13419 if (proc == null) { 13420 HashMap<String, SparseArray<ProcessRecord>> all 13421 = mProcessNames.getMap(); 13422 SparseArray<ProcessRecord> procs = all.get(process); 13423 if (procs != null && procs.size() > 0) { 13424 proc = procs.valueAt(0); 13425 } 13426 } 13427 13428 if (proc == null || proc.thread == null) { 13429 throw new IllegalArgumentException("Unknown process: " + process); 13430 } 13431 13432 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13433 if (!isDebuggable) { 13434 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13435 throw new SecurityException("Process not debuggable: " + proc); 13436 } 13437 } 13438 13439 proc.thread.dumpHeap(managed, path, fd); 13440 fd = null; 13441 return true; 13442 } 13443 } catch (RemoteException e) { 13444 throw new IllegalStateException("Process disappeared"); 13445 } finally { 13446 if (fd != null) { 13447 try { 13448 fd.close(); 13449 } catch (IOException e) { 13450 } 13451 } 13452 } 13453 } 13454 13455 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13456 public void monitor() { 13457 synchronized (this) { } 13458 } 13459 13460 void onCoreSettingsChange(Bundle settings) { 13461 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13462 ProcessRecord processRecord = mLruProcesses.get(i); 13463 try { 13464 if (processRecord.thread != null) { 13465 processRecord.thread.setCoreSettings(settings); 13466 } 13467 } catch (RemoteException re) { 13468 /* ignore */ 13469 } 13470 } 13471 } 13472 13473 // Multi-user methods 13474 13475 public boolean switchUser(int userId) { 13476 final int callingUid = Binder.getCallingUid(); 13477 if (callingUid != 0 && callingUid != Process.myUid()) { 13478 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13479 return false; 13480 } 13481 if (mCurrentUserId == userId) 13482 return true; 13483 13484 synchronized (this) { 13485 // Check if user is already logged in, otherwise check if user exists first before 13486 // adding to the list of logged in users. 13487 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13488 if (!userExists(userId)) { 13489 return false; 13490 } 13491 mLoggedInUsers.append(userId, userId); 13492 } 13493 13494 mCurrentUserId = userId; 13495 boolean haveActivities = mMainStack.switchUser(userId); 13496 if (!haveActivities) { 13497 startHomeActivityLocked(userId); 13498 } 13499 13500 } 13501 13502 // Inform of user switch 13503 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13504 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13505 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); 13506 13507 return true; 13508 } 13509 13510 @Override 13511 public UserInfo getCurrentUser() throws RemoteException { 13512 final int callingUid = Binder.getCallingUid(); 13513 if (callingUid != 0 && callingUid != Process.myUid()) { 13514 Slog.e(TAG, "Trying to get user from unauthorized app"); 13515 return null; 13516 } 13517 return getUserManager().getUserInfo(mCurrentUserId); 13518 } 13519 13520 private void onUserRemoved(Intent intent) { 13521 int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 13522 if (extraUserId < 1) return; 13523 13524 // Kill all the processes for the user 13525 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13526 synchronized (this) { 13527 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13528 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13529 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13530 for (int i = 0; i < uids.size(); i++) { 13531 if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) { 13532 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13533 } 13534 } 13535 } 13536 13537 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13538 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13539 false, false, true, true, extraUserId); 13540 } 13541 } 13542 } 13543 13544 private boolean userExists(int userId) { 13545 UserInfo user = getUserManager().getUserInfo(userId); 13546 return user != null; 13547 } 13548 13549 UserManager getUserManager() { 13550 if (mUserManager == null) { 13551 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13552 } 13553 return mUserManager; 13554 } 13555 13556 private void checkValidCaller(int uid, int userId) { 13557 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13558 13559 throw new SecurityException("Caller uid=" + uid 13560 + " is not privileged to communicate with user=" + userId); 13561 } 13562 13563 private int applyUserId(int uid, int userId) { 13564 return UserHandle.getUid(userId, uid); 13565 } 13566 13567 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13568 if (info == null) return null; 13569 ApplicationInfo newInfo = new ApplicationInfo(info); 13570 newInfo.uid = applyUserId(info.uid, userId); 13571 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13572 + info.packageName; 13573 return newInfo; 13574 } 13575 13576 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13577 if (aInfo == null 13578 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13579 return aInfo; 13580 } 13581 13582 ActivityInfo info = new ActivityInfo(aInfo); 13583 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13584 return info; 13585 } 13586} 13587