ActivityManagerService.java revision 0c3804950236fe170ebf6cc7a5f1e3e305b8f315
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 if (pm.checkPermission( 1986 android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName) 1987 == PERMISSION_GRANTED) { 1988 if (Environment.isExternalStorageEmulated()) { 1989 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 1990 } else { 1991 mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER; 1992 } 1993 } 1994 } catch (PackageManager.NameNotFoundException e) { 1995 Slog.w(TAG, "Unable to retrieve gids", e); 1996 } 1997 } 1998 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1999 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2000 && mTopComponent != null 2001 && app.processName.equals(mTopComponent.getPackageName())) { 2002 uid = 0; 2003 } 2004 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2005 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2006 uid = 0; 2007 } 2008 } 2009 int debugFlags = 0; 2010 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2011 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2012 // Also turn on CheckJNI for debuggable apps. It's quite 2013 // awkward to turn on otherwise. 2014 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2015 } 2016 // Run the app in safe mode if its manifest requests so or the 2017 // system is booted in safe mode. 2018 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2019 Zygote.systemInSafeMode == true) { 2020 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2021 } 2022 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2023 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2024 } 2025 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2026 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2027 } 2028 if ("1".equals(SystemProperties.get("debug.assert"))) { 2029 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2030 } 2031 2032 // Start the process. It will either succeed and return a result containing 2033 // the PID of the new process, or else throw a RuntimeException. 2034 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2035 app.processName, uid, uid, gids, debugFlags, mountExternal, 2036 app.info.targetSdkVersion, null, null); 2037 2038 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2039 synchronized (bs) { 2040 if (bs.isOnBattery()) { 2041 app.batteryStats.incStartsLocked(); 2042 } 2043 } 2044 2045 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2046 app.processName, hostingType, 2047 hostingNameStr != null ? hostingNameStr : ""); 2048 2049 if (app.persistent) { 2050 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2051 } 2052 2053 StringBuilder buf = mStringBuilder; 2054 buf.setLength(0); 2055 buf.append("Start proc "); 2056 buf.append(app.processName); 2057 buf.append(" for "); 2058 buf.append(hostingType); 2059 if (hostingNameStr != null) { 2060 buf.append(" "); 2061 buf.append(hostingNameStr); 2062 } 2063 buf.append(": pid="); 2064 buf.append(startResult.pid); 2065 buf.append(" uid="); 2066 buf.append(uid); 2067 buf.append(" gids={"); 2068 if (gids != null) { 2069 for (int gi=0; gi<gids.length; gi++) { 2070 if (gi != 0) buf.append(", "); 2071 buf.append(gids[gi]); 2072 2073 } 2074 } 2075 buf.append("}"); 2076 Slog.i(TAG, buf.toString()); 2077 app.setPid(startResult.pid); 2078 app.usingWrapper = startResult.usingWrapper; 2079 app.removed = false; 2080 synchronized (mPidsSelfLocked) { 2081 this.mPidsSelfLocked.put(startResult.pid, app); 2082 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2083 msg.obj = app; 2084 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2085 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2086 } 2087 } catch (RuntimeException e) { 2088 // XXX do better error recovery. 2089 app.setPid(0); 2090 Slog.e(TAG, "Failure starting process " + app.processName, e); 2091 } 2092 } 2093 2094 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2095 if (resumed) { 2096 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2097 } else { 2098 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2099 } 2100 } 2101 2102 boolean startHomeActivityLocked(int userId) { 2103 if (mHeadless) { 2104 // Added because none of the other calls to ensureBootCompleted seem to fire 2105 // when running headless. 2106 ensureBootCompleted(); 2107 return false; 2108 } 2109 2110 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2111 && mTopAction == null) { 2112 // We are running in factory test mode, but unable to find 2113 // the factory test app, so just sit around displaying the 2114 // error message and don't try to start anything. 2115 return false; 2116 } 2117 Intent intent = new Intent( 2118 mTopAction, 2119 mTopData != null ? Uri.parse(mTopData) : null); 2120 intent.setComponent(mTopComponent); 2121 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2122 intent.addCategory(Intent.CATEGORY_HOME); 2123 } 2124 ActivityInfo aInfo = 2125 intent.resolveActivityInfo(mContext.getPackageManager(), 2126 STOCK_PM_FLAGS); 2127 if (aInfo != null) { 2128 intent.setComponent(new ComponentName( 2129 aInfo.applicationInfo.packageName, aInfo.name)); 2130 // Don't do this if the home app is currently being 2131 // instrumented. 2132 aInfo = new ActivityInfo(aInfo); 2133 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2134 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2135 aInfo.applicationInfo.uid); 2136 if (app == null || app.instrumentationClass == null) { 2137 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2138 mMainStack.startActivityLocked(null, intent, null, aInfo, 2139 null, null, 0, 0, 0, 0, null, false, null); 2140 } 2141 } 2142 2143 return true; 2144 } 2145 2146 /** 2147 * Starts the "new version setup screen" if appropriate. 2148 */ 2149 void startSetupActivityLocked() { 2150 // Only do this once per boot. 2151 if (mCheckedForSetup) { 2152 return; 2153 } 2154 2155 // We will show this screen if the current one is a different 2156 // version than the last one shown, and we are not running in 2157 // low-level factory test mode. 2158 final ContentResolver resolver = mContext.getContentResolver(); 2159 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2160 Settings.Secure.getInt(resolver, 2161 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2162 mCheckedForSetup = true; 2163 2164 // See if we should be showing the platform update setup UI. 2165 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2166 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2167 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2168 2169 // We don't allow third party apps to replace this. 2170 ResolveInfo ri = null; 2171 for (int i=0; ris != null && i<ris.size(); i++) { 2172 if ((ris.get(i).activityInfo.applicationInfo.flags 2173 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2174 ri = ris.get(i); 2175 break; 2176 } 2177 } 2178 2179 if (ri != null) { 2180 String vers = ri.activityInfo.metaData != null 2181 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2182 : null; 2183 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2184 vers = ri.activityInfo.applicationInfo.metaData.getString( 2185 Intent.METADATA_SETUP_VERSION); 2186 } 2187 String lastVers = Settings.Secure.getString( 2188 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2189 if (vers != null && !vers.equals(lastVers)) { 2190 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2191 intent.setComponent(new ComponentName( 2192 ri.activityInfo.packageName, ri.activityInfo.name)); 2193 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2194 null, null, 0, 0, 0, 0, null, false, null); 2195 } 2196 } 2197 } 2198 } 2199 2200 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2201 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2202 } 2203 2204 void enforceNotIsolatedCaller(String caller) { 2205 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2206 throw new SecurityException("Isolated process not allowed to call " + caller); 2207 } 2208 } 2209 2210 public int getFrontActivityScreenCompatMode() { 2211 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2212 synchronized (this) { 2213 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2214 } 2215 } 2216 2217 public void setFrontActivityScreenCompatMode(int mode) { 2218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2219 "setFrontActivityScreenCompatMode"); 2220 synchronized (this) { 2221 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2222 } 2223 } 2224 2225 public int getPackageScreenCompatMode(String packageName) { 2226 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2227 synchronized (this) { 2228 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2229 } 2230 } 2231 2232 public void setPackageScreenCompatMode(String packageName, int mode) { 2233 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2234 "setPackageScreenCompatMode"); 2235 synchronized (this) { 2236 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2237 } 2238 } 2239 2240 public boolean getPackageAskScreenCompat(String packageName) { 2241 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2242 synchronized (this) { 2243 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2244 } 2245 } 2246 2247 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2248 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2249 "setPackageAskScreenCompat"); 2250 synchronized (this) { 2251 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2252 } 2253 } 2254 2255 void reportResumedActivityLocked(ActivityRecord r) { 2256 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2257 updateUsageStats(r, true); 2258 } 2259 2260 private void dispatchProcessesChanged() { 2261 int N; 2262 synchronized (this) { 2263 N = mPendingProcessChanges.size(); 2264 if (mActiveProcessChanges.length < N) { 2265 mActiveProcessChanges = new ProcessChangeItem[N]; 2266 } 2267 mPendingProcessChanges.toArray(mActiveProcessChanges); 2268 mAvailProcessChanges.addAll(mPendingProcessChanges); 2269 mPendingProcessChanges.clear(); 2270 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2271 } 2272 int i = mProcessObservers.beginBroadcast(); 2273 while (i > 0) { 2274 i--; 2275 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2276 if (observer != null) { 2277 try { 2278 for (int j=0; j<N; j++) { 2279 ProcessChangeItem item = mActiveProcessChanges[j]; 2280 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2282 + item.pid + " uid=" + item.uid + ": " 2283 + item.foregroundActivities); 2284 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2285 item.foregroundActivities); 2286 } 2287 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2289 + item.pid + " uid=" + item.uid + ": " + item.importance); 2290 observer.onImportanceChanged(item.pid, item.uid, 2291 item.importance); 2292 } 2293 } 2294 } catch (RemoteException e) { 2295 } 2296 } 2297 } 2298 mProcessObservers.finishBroadcast(); 2299 } 2300 2301 private void dispatchProcessDied(int pid, int uid) { 2302 int i = mProcessObservers.beginBroadcast(); 2303 while (i > 0) { 2304 i--; 2305 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2306 if (observer != null) { 2307 try { 2308 observer.onProcessDied(pid, uid); 2309 } catch (RemoteException e) { 2310 } 2311 } 2312 } 2313 mProcessObservers.finishBroadcast(); 2314 } 2315 2316 final void doPendingActivityLaunchesLocked(boolean doResume) { 2317 final int N = mPendingActivityLaunches.size(); 2318 if (N <= 0) { 2319 return; 2320 } 2321 for (int i=0; i<N; i++) { 2322 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2323 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2324 pal.startFlags, doResume && i == (N-1), null); 2325 } 2326 mPendingActivityLaunches.clear(); 2327 } 2328 2329 public final int startActivity(IApplicationThread caller, 2330 Intent intent, String resolvedType, IBinder resultTo, 2331 String resultWho, int requestCode, int startFlags, 2332 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2333 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2334 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2335 } 2336 2337 public final int startActivityAsUser(IApplicationThread caller, 2338 Intent intent, String resolvedType, IBinder resultTo, 2339 String resultWho, int requestCode, int startFlags, 2340 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2341 enforceNotIsolatedCaller("startActivity"); 2342 if (userId != UserHandle.getCallingUserId()) { 2343 // Requesting a different user, make sure that they have the permission 2344 if (checkComponentPermission( 2345 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2346 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2347 == PackageManager.PERMISSION_GRANTED) { 2348 // Translate to the current user id, if caller wasn't aware 2349 if (userId == UserHandle.USER_CURRENT) { 2350 userId = mCurrentUserId; 2351 } 2352 } else { 2353 String msg = "Permission Denial: " 2354 + "Request to startActivity as user " + userId 2355 + " but is calling from user " + UserHandle.getCallingUserId() 2356 + "; this requires " 2357 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2358 Slog.w(TAG, msg); 2359 throw new SecurityException(msg); 2360 } 2361 } else { 2362 if (intent.getCategories() != null 2363 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2364 // Requesting home, set the identity to the current user 2365 // HACK! 2366 userId = mCurrentUserId; 2367 } else { 2368 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2369 // the current user's userId 2370 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2371 userId = 0; 2372 } else { 2373 userId = Binder.getOrigCallingUser(); 2374 } 2375 } 2376 } 2377 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2378 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2379 null, null, options, userId); 2380 } 2381 2382 public final WaitResult startActivityAndWait(IApplicationThread caller, 2383 Intent intent, String resolvedType, IBinder resultTo, 2384 String resultWho, int requestCode, int startFlags, String profileFile, 2385 ParcelFileDescriptor profileFd, Bundle options) { 2386 enforceNotIsolatedCaller("startActivityAndWait"); 2387 WaitResult res = new WaitResult(); 2388 int userId = Binder.getOrigCallingUser(); 2389 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2390 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2391 res, null, options, userId); 2392 return res; 2393 } 2394 2395 public final int startActivityWithConfig(IApplicationThread caller, 2396 Intent intent, String resolvedType, IBinder resultTo, 2397 String resultWho, int requestCode, int startFlags, Configuration config, 2398 Bundle options) { 2399 enforceNotIsolatedCaller("startActivityWithConfig"); 2400 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2401 resultTo, resultWho, requestCode, startFlags, 2402 null, null, null, config, options, Binder.getOrigCallingUser()); 2403 return ret; 2404 } 2405 2406 public int startActivityIntentSender(IApplicationThread caller, 2407 IntentSender intent, Intent fillInIntent, String resolvedType, 2408 IBinder resultTo, String resultWho, int requestCode, 2409 int flagsMask, int flagsValues, Bundle options) { 2410 enforceNotIsolatedCaller("startActivityIntentSender"); 2411 // Refuse possible leaked file descriptors 2412 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2413 throw new IllegalArgumentException("File descriptors passed in Intent"); 2414 } 2415 2416 IIntentSender sender = intent.getTarget(); 2417 if (!(sender instanceof PendingIntentRecord)) { 2418 throw new IllegalArgumentException("Bad PendingIntent object"); 2419 } 2420 2421 PendingIntentRecord pir = (PendingIntentRecord)sender; 2422 2423 synchronized (this) { 2424 // If this is coming from the currently resumed activity, it is 2425 // effectively saying that app switches are allowed at this point. 2426 if (mMainStack.mResumedActivity != null 2427 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2428 Binder.getCallingUid()) { 2429 mAppSwitchesAllowedTime = 0; 2430 } 2431 } 2432 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2433 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2434 return ret; 2435 } 2436 2437 public boolean startNextMatchingActivity(IBinder callingActivity, 2438 Intent intent, Bundle options) { 2439 // Refuse possible leaked file descriptors 2440 if (intent != null && intent.hasFileDescriptors() == true) { 2441 throw new IllegalArgumentException("File descriptors passed in Intent"); 2442 } 2443 2444 synchronized (this) { 2445 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2446 if (r == null) { 2447 ActivityOptions.abort(options); 2448 return false; 2449 } 2450 if (r.app == null || r.app.thread == null) { 2451 // The caller is not running... d'oh! 2452 ActivityOptions.abort(options); 2453 return false; 2454 } 2455 intent = new Intent(intent); 2456 // The caller is not allowed to change the data. 2457 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2458 // And we are resetting to find the next component... 2459 intent.setComponent(null); 2460 2461 ActivityInfo aInfo = null; 2462 try { 2463 List<ResolveInfo> resolves = 2464 AppGlobals.getPackageManager().queryIntentActivities( 2465 intent, r.resolvedType, 2466 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2467 UserHandle.getCallingUserId()); 2468 2469 // Look for the original activity in the list... 2470 final int N = resolves != null ? resolves.size() : 0; 2471 for (int i=0; i<N; i++) { 2472 ResolveInfo rInfo = resolves.get(i); 2473 if (rInfo.activityInfo.packageName.equals(r.packageName) 2474 && rInfo.activityInfo.name.equals(r.info.name)) { 2475 // We found the current one... the next matching is 2476 // after it. 2477 i++; 2478 if (i<N) { 2479 aInfo = resolves.get(i).activityInfo; 2480 } 2481 break; 2482 } 2483 } 2484 } catch (RemoteException e) { 2485 } 2486 2487 if (aInfo == null) { 2488 // Nobody who is next! 2489 ActivityOptions.abort(options); 2490 return false; 2491 } 2492 2493 intent.setComponent(new ComponentName( 2494 aInfo.applicationInfo.packageName, aInfo.name)); 2495 intent.setFlags(intent.getFlags()&~( 2496 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2497 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2498 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2499 Intent.FLAG_ACTIVITY_NEW_TASK)); 2500 2501 // Okay now we need to start the new activity, replacing the 2502 // currently running activity. This is a little tricky because 2503 // we want to start the new one as if the current one is finished, 2504 // but not finish the current one first so that there is no flicker. 2505 // And thus... 2506 final boolean wasFinishing = r.finishing; 2507 r.finishing = true; 2508 2509 // Propagate reply information over to the new activity. 2510 final ActivityRecord resultTo = r.resultTo; 2511 final String resultWho = r.resultWho; 2512 final int requestCode = r.requestCode; 2513 r.resultTo = null; 2514 if (resultTo != null) { 2515 resultTo.removeResultsLocked(r, resultWho, requestCode); 2516 } 2517 2518 final long origId = Binder.clearCallingIdentity(); 2519 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2520 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2521 resultWho, requestCode, -1, r.launchedFromUid, 0, 2522 options, false, null); 2523 Binder.restoreCallingIdentity(origId); 2524 2525 r.finishing = wasFinishing; 2526 if (res != ActivityManager.START_SUCCESS) { 2527 return false; 2528 } 2529 return true; 2530 } 2531 } 2532 2533 public final int startActivityInPackage(int uid, 2534 Intent intent, String resolvedType, IBinder resultTo, 2535 String resultWho, int requestCode, int startFlags, Bundle options) { 2536 2537 // This is so super not safe, that only the system (or okay root) 2538 // can do it. 2539 final int callingUid = Binder.getCallingUid(); 2540 if (callingUid != 0 && callingUid != Process.myUid()) { 2541 throw new SecurityException( 2542 "startActivityInPackage only available to the system"); 2543 } 2544 2545 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2546 resultTo, resultWho, requestCode, startFlags, 2547 null, null, null, null, options, UserHandle.getUserId(uid)); 2548 return ret; 2549 } 2550 2551 public final int startActivities(IApplicationThread caller, 2552 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2553 enforceNotIsolatedCaller("startActivities"); 2554 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2555 options, Binder.getOrigCallingUser()); 2556 return ret; 2557 } 2558 2559 public final int startActivitiesInPackage(int uid, 2560 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2561 Bundle options) { 2562 2563 // This is so super not safe, that only the system (or okay root) 2564 // can do it. 2565 final int callingUid = Binder.getCallingUid(); 2566 if (callingUid != 0 && callingUid != Process.myUid()) { 2567 throw new SecurityException( 2568 "startActivityInPackage only available to the system"); 2569 } 2570 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2571 options, UserHandle.getUserId(uid)); 2572 return ret; 2573 } 2574 2575 final void addRecentTaskLocked(TaskRecord task) { 2576 int N = mRecentTasks.size(); 2577 // Quick case: check if the top-most recent task is the same. 2578 if (N > 0 && mRecentTasks.get(0) == task) { 2579 return; 2580 } 2581 // Remove any existing entries that are the same kind of task. 2582 for (int i=0; i<N; i++) { 2583 TaskRecord tr = mRecentTasks.get(i); 2584 if (task.userId == tr.userId 2585 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2586 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2587 mRecentTasks.remove(i); 2588 i--; 2589 N--; 2590 if (task.intent == null) { 2591 // If the new recent task we are adding is not fully 2592 // specified, then replace it with the existing recent task. 2593 task = tr; 2594 } 2595 } 2596 } 2597 if (N >= MAX_RECENT_TASKS) { 2598 mRecentTasks.remove(N-1); 2599 } 2600 mRecentTasks.add(0, task); 2601 } 2602 2603 public void setRequestedOrientation(IBinder token, 2604 int requestedOrientation) { 2605 synchronized (this) { 2606 ActivityRecord r = mMainStack.isInStackLocked(token); 2607 if (r == null) { 2608 return; 2609 } 2610 final long origId = Binder.clearCallingIdentity(); 2611 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2612 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2613 mConfiguration, 2614 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2615 if (config != null) { 2616 r.frozenBeforeDestroy = true; 2617 if (!updateConfigurationLocked(config, r, false, false)) { 2618 mMainStack.resumeTopActivityLocked(null); 2619 } 2620 } 2621 Binder.restoreCallingIdentity(origId); 2622 } 2623 } 2624 2625 public int getRequestedOrientation(IBinder token) { 2626 synchronized (this) { 2627 ActivityRecord r = mMainStack.isInStackLocked(token); 2628 if (r == null) { 2629 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2630 } 2631 return mWindowManager.getAppOrientation(r.appToken); 2632 } 2633 } 2634 2635 /** 2636 * This is the internal entry point for handling Activity.finish(). 2637 * 2638 * @param token The Binder token referencing the Activity we want to finish. 2639 * @param resultCode Result code, if any, from this Activity. 2640 * @param resultData Result data (Intent), if any, from this Activity. 2641 * 2642 * @return Returns true if the activity successfully finished, or false if it is still running. 2643 */ 2644 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2645 // Refuse possible leaked file descriptors 2646 if (resultData != null && resultData.hasFileDescriptors() == true) { 2647 throw new IllegalArgumentException("File descriptors passed in Intent"); 2648 } 2649 2650 synchronized(this) { 2651 if (mController != null) { 2652 // Find the first activity that is not finishing. 2653 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2654 if (next != null) { 2655 // ask watcher if this is allowed 2656 boolean resumeOK = true; 2657 try { 2658 resumeOK = mController.activityResuming(next.packageName); 2659 } catch (RemoteException e) { 2660 mController = null; 2661 } 2662 2663 if (!resumeOK) { 2664 return false; 2665 } 2666 } 2667 } 2668 final long origId = Binder.clearCallingIdentity(); 2669 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2670 resultData, "app-request"); 2671 Binder.restoreCallingIdentity(origId); 2672 return res; 2673 } 2674 } 2675 2676 public final void finishHeavyWeightApp() { 2677 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2678 != PackageManager.PERMISSION_GRANTED) { 2679 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2680 + Binder.getCallingPid() 2681 + ", uid=" + Binder.getCallingUid() 2682 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2683 Slog.w(TAG, msg); 2684 throw new SecurityException(msg); 2685 } 2686 2687 synchronized(this) { 2688 if (mHeavyWeightProcess == null) { 2689 return; 2690 } 2691 2692 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2693 mHeavyWeightProcess.activities); 2694 for (int i=0; i<activities.size(); i++) { 2695 ActivityRecord r = activities.get(i); 2696 if (!r.finishing) { 2697 int index = mMainStack.indexOfTokenLocked(r.appToken); 2698 if (index >= 0) { 2699 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2700 null, "finish-heavy"); 2701 } 2702 } 2703 } 2704 2705 mHeavyWeightProcess = null; 2706 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2707 } 2708 } 2709 2710 public void crashApplication(int uid, int initialPid, String packageName, 2711 String message) { 2712 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2713 != PackageManager.PERMISSION_GRANTED) { 2714 String msg = "Permission Denial: crashApplication() from pid=" 2715 + Binder.getCallingPid() 2716 + ", uid=" + Binder.getCallingUid() 2717 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2718 Slog.w(TAG, msg); 2719 throw new SecurityException(msg); 2720 } 2721 2722 synchronized(this) { 2723 ProcessRecord proc = null; 2724 2725 // Figure out which process to kill. We don't trust that initialPid 2726 // still has any relation to current pids, so must scan through the 2727 // list. 2728 synchronized (mPidsSelfLocked) { 2729 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2730 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2731 if (p.uid != uid) { 2732 continue; 2733 } 2734 if (p.pid == initialPid) { 2735 proc = p; 2736 break; 2737 } 2738 for (String str : p.pkgList) { 2739 if (str.equals(packageName)) { 2740 proc = p; 2741 } 2742 } 2743 } 2744 } 2745 2746 if (proc == null) { 2747 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2748 + " initialPid=" + initialPid 2749 + " packageName=" + packageName); 2750 return; 2751 } 2752 2753 if (proc.thread != null) { 2754 if (proc.pid == Process.myPid()) { 2755 Log.w(TAG, "crashApplication: trying to crash self!"); 2756 return; 2757 } 2758 long ident = Binder.clearCallingIdentity(); 2759 try { 2760 proc.thread.scheduleCrash(message); 2761 } catch (RemoteException e) { 2762 } 2763 Binder.restoreCallingIdentity(ident); 2764 } 2765 } 2766 } 2767 2768 public final void finishSubActivity(IBinder token, String resultWho, 2769 int requestCode) { 2770 synchronized(this) { 2771 final long origId = Binder.clearCallingIdentity(); 2772 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2773 Binder.restoreCallingIdentity(origId); 2774 } 2775 } 2776 2777 public boolean finishActivityAffinity(IBinder token) { 2778 synchronized(this) { 2779 final long origId = Binder.clearCallingIdentity(); 2780 boolean res = mMainStack.finishActivityAffinityLocked(token); 2781 Binder.restoreCallingIdentity(origId); 2782 return res; 2783 } 2784 } 2785 2786 public boolean willActivityBeVisible(IBinder token) { 2787 synchronized(this) { 2788 int i; 2789 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2790 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2791 if (r.appToken == token) { 2792 return true; 2793 } 2794 if (r.fullscreen && !r.finishing) { 2795 return false; 2796 } 2797 } 2798 return true; 2799 } 2800 } 2801 2802 public void overridePendingTransition(IBinder token, String packageName, 2803 int enterAnim, int exitAnim) { 2804 synchronized(this) { 2805 ActivityRecord self = mMainStack.isInStackLocked(token); 2806 if (self == null) { 2807 return; 2808 } 2809 2810 final long origId = Binder.clearCallingIdentity(); 2811 2812 if (self.state == ActivityState.RESUMED 2813 || self.state == ActivityState.PAUSING) { 2814 mWindowManager.overridePendingAppTransition(packageName, 2815 enterAnim, exitAnim, null); 2816 } 2817 2818 Binder.restoreCallingIdentity(origId); 2819 } 2820 } 2821 2822 /** 2823 * Main function for removing an existing process from the activity manager 2824 * as a result of that process going away. Clears out all connections 2825 * to the process. 2826 */ 2827 private final void handleAppDiedLocked(ProcessRecord app, 2828 boolean restarting, boolean allowRestart) { 2829 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2830 if (!restarting) { 2831 mLruProcesses.remove(app); 2832 } 2833 2834 if (mProfileProc == app) { 2835 clearProfilerLocked(); 2836 } 2837 2838 // Just in case... 2839 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2840 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2841 mMainStack.mPausingActivity = null; 2842 } 2843 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2844 mMainStack.mLastPausedActivity = null; 2845 } 2846 2847 // Remove this application's activities from active lists. 2848 mMainStack.removeHistoryRecordsForAppLocked(app); 2849 2850 boolean atTop = true; 2851 boolean hasVisibleActivities = false; 2852 2853 // Clean out the history list. 2854 int i = mMainStack.mHistory.size(); 2855 if (localLOGV) Slog.v( 2856 TAG, "Removing app " + app + " from history with " + i + " entries"); 2857 while (i > 0) { 2858 i--; 2859 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2860 if (localLOGV) Slog.v( 2861 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2862 if (r.app == app) { 2863 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2864 if (ActivityStack.DEBUG_ADD_REMOVE) { 2865 RuntimeException here = new RuntimeException("here"); 2866 here.fillInStackTrace(); 2867 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2868 + ": haveState=" + r.haveState 2869 + " stateNotNeeded=" + r.stateNotNeeded 2870 + " finishing=" + r.finishing 2871 + " state=" + r.state, here); 2872 } 2873 if (!r.finishing) { 2874 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2875 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2876 System.identityHashCode(r), 2877 r.task.taskId, r.shortComponentName, 2878 "proc died without state saved"); 2879 } 2880 mMainStack.removeActivityFromHistoryLocked(r); 2881 2882 } else { 2883 // We have the current state for this activity, so 2884 // it can be restarted later when needed. 2885 if (localLOGV) Slog.v( 2886 TAG, "Keeping entry, setting app to null"); 2887 if (r.visible) { 2888 hasVisibleActivities = true; 2889 } 2890 r.app = null; 2891 r.nowVisible = false; 2892 if (!r.haveState) { 2893 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2894 "App died, clearing saved state of " + r); 2895 r.icicle = null; 2896 } 2897 } 2898 2899 r.stack.cleanUpActivityLocked(r, true, true); 2900 } 2901 atTop = false; 2902 } 2903 2904 app.activities.clear(); 2905 2906 if (app.instrumentationClass != null) { 2907 Slog.w(TAG, "Crash of app " + app.processName 2908 + " running instrumentation " + app.instrumentationClass); 2909 Bundle info = new Bundle(); 2910 info.putString("shortMsg", "Process crashed."); 2911 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2912 } 2913 2914 if (!restarting) { 2915 if (!mMainStack.resumeTopActivityLocked(null)) { 2916 // If there was nothing to resume, and we are not already 2917 // restarting this process, but there is a visible activity that 2918 // is hosted by the process... then make sure all visible 2919 // activities are running, taking care of restarting this 2920 // process. 2921 if (hasVisibleActivities) { 2922 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2923 } 2924 } 2925 } 2926 } 2927 2928 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2929 IBinder threadBinder = thread.asBinder(); 2930 // Find the application record. 2931 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2932 ProcessRecord rec = mLruProcesses.get(i); 2933 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2934 return i; 2935 } 2936 } 2937 return -1; 2938 } 2939 2940 final ProcessRecord getRecordForAppLocked( 2941 IApplicationThread thread) { 2942 if (thread == null) { 2943 return null; 2944 } 2945 2946 int appIndex = getLRURecordIndexForAppLocked(thread); 2947 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2948 } 2949 2950 final void appDiedLocked(ProcessRecord app, int pid, 2951 IApplicationThread thread) { 2952 2953 mProcDeaths[0]++; 2954 2955 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2956 synchronized (stats) { 2957 stats.noteProcessDiedLocked(app.info.uid, pid); 2958 } 2959 2960 // Clean up already done if the process has been re-started. 2961 if (app.pid == pid && app.thread != null && 2962 app.thread.asBinder() == thread.asBinder()) { 2963 if (!app.killedBackground) { 2964 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2965 + ") has died."); 2966 } 2967 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2968 if (localLOGV) Slog.v( 2969 TAG, "Dying app: " + app + ", pid: " + pid 2970 + ", thread: " + thread.asBinder()); 2971 boolean doLowMem = app.instrumentationClass == null; 2972 handleAppDiedLocked(app, false, true); 2973 2974 if (doLowMem) { 2975 // If there are no longer any background processes running, 2976 // and the app that died was not running instrumentation, 2977 // then tell everyone we are now low on memory. 2978 boolean haveBg = false; 2979 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2980 ProcessRecord rec = mLruProcesses.get(i); 2981 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2982 haveBg = true; 2983 break; 2984 } 2985 } 2986 2987 if (!haveBg) { 2988 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2989 long now = SystemClock.uptimeMillis(); 2990 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2991 ProcessRecord rec = mLruProcesses.get(i); 2992 if (rec != app && rec.thread != null && 2993 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2994 // The low memory report is overriding any current 2995 // state for a GC request. Make sure to do 2996 // heavy/important/visible/foreground processes first. 2997 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2998 rec.lastRequestedGc = 0; 2999 } else { 3000 rec.lastRequestedGc = rec.lastLowMemory; 3001 } 3002 rec.reportLowMemory = true; 3003 rec.lastLowMemory = now; 3004 mProcessesToGc.remove(rec); 3005 addProcessToGcListLocked(rec); 3006 } 3007 } 3008 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3009 scheduleAppGcsLocked(); 3010 } 3011 } 3012 } else if (app.pid != pid) { 3013 // A new process has already been started. 3014 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3015 + ") has died and restarted (pid " + app.pid + ")."); 3016 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3017 } else if (DEBUG_PROCESSES) { 3018 Slog.d(TAG, "Received spurious death notification for thread " 3019 + thread.asBinder()); 3020 } 3021 } 3022 3023 /** 3024 * If a stack trace dump file is configured, dump process stack traces. 3025 * @param clearTraces causes the dump file to be erased prior to the new 3026 * traces being written, if true; when false, the new traces will be 3027 * appended to any existing file content. 3028 * @param firstPids of dalvik VM processes to dump stack traces for first 3029 * @param lastPids of dalvik VM processes to dump stack traces for last 3030 * @param nativeProcs optional list of native process names to dump stack crawls 3031 * @return file containing stack traces, or null if no dump file is configured 3032 */ 3033 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3034 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3035 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3036 if (tracesPath == null || tracesPath.length() == 0) { 3037 return null; 3038 } 3039 3040 File tracesFile = new File(tracesPath); 3041 try { 3042 File tracesDir = tracesFile.getParentFile(); 3043 if (!tracesDir.exists()) tracesFile.mkdirs(); 3044 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3045 3046 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3047 tracesFile.createNewFile(); 3048 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3049 } catch (IOException e) { 3050 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3051 return null; 3052 } 3053 3054 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3055 return tracesFile; 3056 } 3057 3058 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3059 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3060 // Use a FileObserver to detect when traces finish writing. 3061 // The order of traces is considered important to maintain for legibility. 3062 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3063 public synchronized void onEvent(int event, String path) { notify(); } 3064 }; 3065 3066 try { 3067 observer.startWatching(); 3068 3069 // First collect all of the stacks of the most important pids. 3070 if (firstPids != null) { 3071 try { 3072 int num = firstPids.size(); 3073 for (int i = 0; i < num; i++) { 3074 synchronized (observer) { 3075 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3076 observer.wait(200); // Wait for write-close, give up after 200msec 3077 } 3078 } 3079 } catch (InterruptedException e) { 3080 Log.wtf(TAG, e); 3081 } 3082 } 3083 3084 // Next measure CPU usage. 3085 if (processStats != null) { 3086 processStats.init(); 3087 System.gc(); 3088 processStats.update(); 3089 try { 3090 synchronized (processStats) { 3091 processStats.wait(500); // measure over 1/2 second. 3092 } 3093 } catch (InterruptedException e) { 3094 } 3095 processStats.update(); 3096 3097 // We'll take the stack crawls of just the top apps using CPU. 3098 final int N = processStats.countWorkingStats(); 3099 int numProcs = 0; 3100 for (int i=0; i<N && numProcs<5; i++) { 3101 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3102 if (lastPids.indexOfKey(stats.pid) >= 0) { 3103 numProcs++; 3104 try { 3105 synchronized (observer) { 3106 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3107 observer.wait(200); // Wait for write-close, give up after 200msec 3108 } 3109 } catch (InterruptedException e) { 3110 Log.wtf(TAG, e); 3111 } 3112 3113 } 3114 } 3115 } 3116 3117 } finally { 3118 observer.stopWatching(); 3119 } 3120 3121 if (nativeProcs != null) { 3122 int[] pids = Process.getPidsForCommands(nativeProcs); 3123 if (pids != null) { 3124 for (int pid : pids) { 3125 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3126 } 3127 } 3128 } 3129 } 3130 3131 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3132 if (true || IS_USER_BUILD) { 3133 return; 3134 } 3135 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3136 if (tracesPath == null || tracesPath.length() == 0) { 3137 return; 3138 } 3139 3140 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3141 StrictMode.allowThreadDiskWrites(); 3142 try { 3143 final File tracesFile = new File(tracesPath); 3144 final File tracesDir = tracesFile.getParentFile(); 3145 final File tracesTmp = new File(tracesDir, "__tmp__"); 3146 try { 3147 if (!tracesDir.exists()) tracesFile.mkdirs(); 3148 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3149 3150 if (tracesFile.exists()) { 3151 tracesTmp.delete(); 3152 tracesFile.renameTo(tracesTmp); 3153 } 3154 StringBuilder sb = new StringBuilder(); 3155 Time tobj = new Time(); 3156 tobj.set(System.currentTimeMillis()); 3157 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3158 sb.append(": "); 3159 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3160 sb.append(" since "); 3161 sb.append(msg); 3162 FileOutputStream fos = new FileOutputStream(tracesFile); 3163 fos.write(sb.toString().getBytes()); 3164 if (app == null) { 3165 fos.write("\n*** No application process!".getBytes()); 3166 } 3167 fos.close(); 3168 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3169 } catch (IOException e) { 3170 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3171 return; 3172 } 3173 3174 if (app != null) { 3175 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3176 firstPids.add(app.pid); 3177 dumpStackTraces(tracesPath, firstPids, null, null, null); 3178 } 3179 3180 File lastTracesFile = null; 3181 File curTracesFile = null; 3182 for (int i=9; i>=0; i--) { 3183 String name = String.format("slow%02d.txt", i); 3184 curTracesFile = new File(tracesDir, name); 3185 if (curTracesFile.exists()) { 3186 if (lastTracesFile != null) { 3187 curTracesFile.renameTo(lastTracesFile); 3188 } else { 3189 curTracesFile.delete(); 3190 } 3191 } 3192 lastTracesFile = curTracesFile; 3193 } 3194 tracesFile.renameTo(curTracesFile); 3195 if (tracesTmp.exists()) { 3196 tracesTmp.renameTo(tracesFile); 3197 } 3198 } finally { 3199 StrictMode.setThreadPolicy(oldPolicy); 3200 } 3201 } 3202 3203 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3204 ActivityRecord parent, final String annotation) { 3205 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3206 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3207 3208 if (mController != null) { 3209 try { 3210 // 0 == continue, -1 = kill process immediately 3211 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3212 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3213 } catch (RemoteException e) { 3214 mController = null; 3215 } 3216 } 3217 3218 long anrTime = SystemClock.uptimeMillis(); 3219 if (MONITOR_CPU_USAGE) { 3220 updateCpuStatsNow(); 3221 } 3222 3223 synchronized (this) { 3224 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3225 if (mShuttingDown) { 3226 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3227 return; 3228 } else if (app.notResponding) { 3229 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3230 return; 3231 } else if (app.crashing) { 3232 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3233 return; 3234 } 3235 3236 // In case we come through here for the same app before completing 3237 // this one, mark as anring now so we will bail out. 3238 app.notResponding = true; 3239 3240 // Log the ANR to the event log. 3241 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3242 annotation); 3243 3244 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3245 firstPids.add(app.pid); 3246 3247 int parentPid = app.pid; 3248 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3249 if (parentPid != app.pid) firstPids.add(parentPid); 3250 3251 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3252 3253 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3254 ProcessRecord r = mLruProcesses.get(i); 3255 if (r != null && r.thread != null) { 3256 int pid = r.pid; 3257 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3258 if (r.persistent) { 3259 firstPids.add(pid); 3260 } else { 3261 lastPids.put(pid, Boolean.TRUE); 3262 } 3263 } 3264 } 3265 } 3266 } 3267 3268 // Log the ANR to the main log. 3269 StringBuilder info = new StringBuilder(); 3270 info.setLength(0); 3271 info.append("ANR in ").append(app.processName); 3272 if (activity != null && activity.shortComponentName != null) { 3273 info.append(" (").append(activity.shortComponentName).append(")"); 3274 } 3275 info.append("\n"); 3276 if (annotation != null) { 3277 info.append("Reason: ").append(annotation).append("\n"); 3278 } 3279 if (parent != null && parent != activity) { 3280 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3281 } 3282 3283 final ProcessStats processStats = new ProcessStats(true); 3284 3285 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3286 3287 String cpuInfo = null; 3288 if (MONITOR_CPU_USAGE) { 3289 updateCpuStatsNow(); 3290 synchronized (mProcessStatsThread) { 3291 cpuInfo = mProcessStats.printCurrentState(anrTime); 3292 } 3293 info.append(processStats.printCurrentLoad()); 3294 info.append(cpuInfo); 3295 } 3296 3297 info.append(processStats.printCurrentState(anrTime)); 3298 3299 Slog.e(TAG, info.toString()); 3300 if (tracesFile == null) { 3301 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3302 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3303 } 3304 3305 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3306 cpuInfo, tracesFile, null); 3307 3308 if (mController != null) { 3309 try { 3310 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3311 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3312 if (res != 0) { 3313 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3314 return; 3315 } 3316 } catch (RemoteException e) { 3317 mController = null; 3318 } 3319 } 3320 3321 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3322 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3323 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3324 3325 synchronized (this) { 3326 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3327 Slog.w(TAG, "Killing " + app + ": background ANR"); 3328 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3329 app.processName, app.setAdj, "background ANR"); 3330 Process.killProcessQuiet(app.pid); 3331 return; 3332 } 3333 3334 // Set the app's notResponding state, and look up the errorReportReceiver 3335 makeAppNotRespondingLocked(app, 3336 activity != null ? activity.shortComponentName : null, 3337 annotation != null ? "ANR " + annotation : "ANR", 3338 info.toString()); 3339 3340 // Bring up the infamous App Not Responding dialog 3341 Message msg = Message.obtain(); 3342 HashMap map = new HashMap(); 3343 msg.what = SHOW_NOT_RESPONDING_MSG; 3344 msg.obj = map; 3345 map.put("app", app); 3346 if (activity != null) { 3347 map.put("activity", activity); 3348 } 3349 3350 mHandler.sendMessage(msg); 3351 } 3352 } 3353 3354 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3355 if (!mLaunchWarningShown) { 3356 mLaunchWarningShown = true; 3357 mHandler.post(new Runnable() { 3358 @Override 3359 public void run() { 3360 synchronized (ActivityManagerService.this) { 3361 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3362 d.show(); 3363 mHandler.postDelayed(new Runnable() { 3364 @Override 3365 public void run() { 3366 synchronized (ActivityManagerService.this) { 3367 d.dismiss(); 3368 mLaunchWarningShown = false; 3369 } 3370 } 3371 }, 4000); 3372 } 3373 } 3374 }); 3375 } 3376 } 3377 3378 public boolean clearApplicationUserData(final String packageName, 3379 final IPackageDataObserver observer, final int userId) { 3380 enforceNotIsolatedCaller("clearApplicationUserData"); 3381 int uid = Binder.getCallingUid(); 3382 int pid = Binder.getCallingPid(); 3383 long callingId = Binder.clearCallingIdentity(); 3384 try { 3385 IPackageManager pm = AppGlobals.getPackageManager(); 3386 int pkgUid = -1; 3387 synchronized(this) { 3388 try { 3389 pkgUid = pm.getPackageUid(packageName, userId); 3390 } catch (RemoteException e) { 3391 } 3392 if (pkgUid == -1) { 3393 Slog.w(TAG, "Invalid packageName:" + packageName); 3394 return false; 3395 } 3396 if (uid == pkgUid || checkComponentPermission( 3397 android.Manifest.permission.CLEAR_APP_USER_DATA, 3398 pid, uid, -1, true) 3399 == PackageManager.PERMISSION_GRANTED) { 3400 forceStopPackageLocked(packageName, pkgUid); 3401 } else { 3402 throw new SecurityException(pid+" does not have permission:"+ 3403 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3404 "for process:"+packageName); 3405 } 3406 } 3407 3408 try { 3409 //clear application user data 3410 pm.clearApplicationUserData(packageName, observer, userId); 3411 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3412 Uri.fromParts("package", packageName, null)); 3413 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3414 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3415 null, null, 0, null, null, null, false, false, userId); 3416 } catch (RemoteException e) { 3417 } 3418 } finally { 3419 Binder.restoreCallingIdentity(callingId); 3420 } 3421 return true; 3422 } 3423 3424 public void killBackgroundProcesses(final String packageName) { 3425 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3426 != PackageManager.PERMISSION_GRANTED && 3427 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3428 != PackageManager.PERMISSION_GRANTED) { 3429 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3430 + Binder.getCallingPid() 3431 + ", uid=" + Binder.getCallingUid() 3432 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3433 Slog.w(TAG, msg); 3434 throw new SecurityException(msg); 3435 } 3436 3437 int userId = UserHandle.getCallingUserId(); 3438 long callingId = Binder.clearCallingIdentity(); 3439 try { 3440 IPackageManager pm = AppGlobals.getPackageManager(); 3441 int pkgUid = -1; 3442 synchronized(this) { 3443 try { 3444 pkgUid = pm.getPackageUid(packageName, userId); 3445 } catch (RemoteException e) { 3446 } 3447 if (pkgUid == -1) { 3448 Slog.w(TAG, "Invalid packageName: " + packageName); 3449 return; 3450 } 3451 killPackageProcessesLocked(packageName, pkgUid, 3452 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3453 } 3454 } finally { 3455 Binder.restoreCallingIdentity(callingId); 3456 } 3457 } 3458 3459 public void killAllBackgroundProcesses() { 3460 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3461 != PackageManager.PERMISSION_GRANTED) { 3462 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3463 + Binder.getCallingPid() 3464 + ", uid=" + Binder.getCallingUid() 3465 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3466 Slog.w(TAG, msg); 3467 throw new SecurityException(msg); 3468 } 3469 3470 long callingId = Binder.clearCallingIdentity(); 3471 try { 3472 synchronized(this) { 3473 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3474 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3475 final int NA = apps.size(); 3476 for (int ia=0; ia<NA; ia++) { 3477 ProcessRecord app = apps.valueAt(ia); 3478 if (app.persistent) { 3479 // we don't kill persistent processes 3480 continue; 3481 } 3482 if (app.removed) { 3483 procs.add(app); 3484 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3485 app.removed = true; 3486 procs.add(app); 3487 } 3488 } 3489 } 3490 3491 int N = procs.size(); 3492 for (int i=0; i<N; i++) { 3493 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3494 } 3495 } 3496 } finally { 3497 Binder.restoreCallingIdentity(callingId); 3498 } 3499 } 3500 3501 public void forceStopPackage(final String packageName) { 3502 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3503 != PackageManager.PERMISSION_GRANTED) { 3504 String msg = "Permission Denial: forceStopPackage() from pid=" 3505 + Binder.getCallingPid() 3506 + ", uid=" + Binder.getCallingUid() 3507 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3508 Slog.w(TAG, msg); 3509 throw new SecurityException(msg); 3510 } 3511 final int userId = UserHandle.getCallingUserId(); 3512 long callingId = Binder.clearCallingIdentity(); 3513 try { 3514 IPackageManager pm = AppGlobals.getPackageManager(); 3515 int pkgUid = -1; 3516 synchronized(this) { 3517 try { 3518 pkgUid = pm.getPackageUid(packageName, userId); 3519 } catch (RemoteException e) { 3520 } 3521 if (pkgUid == -1) { 3522 Slog.w(TAG, "Invalid packageName: " + packageName); 3523 return; 3524 } 3525 forceStopPackageLocked(packageName, pkgUid); 3526 try { 3527 pm.setPackageStoppedState(packageName, true, userId); 3528 } catch (RemoteException e) { 3529 } catch (IllegalArgumentException e) { 3530 Slog.w(TAG, "Failed trying to unstop package " 3531 + packageName + ": " + e); 3532 } 3533 } 3534 } finally { 3535 Binder.restoreCallingIdentity(callingId); 3536 } 3537 } 3538 3539 /* 3540 * The pkg name and uid have to be specified. 3541 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3542 */ 3543 public void killApplicationWithUid(String pkg, int uid) { 3544 if (pkg == null) { 3545 return; 3546 } 3547 // Make sure the uid is valid. 3548 if (uid < 0) { 3549 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3550 return; 3551 } 3552 int callerUid = Binder.getCallingUid(); 3553 // Only the system server can kill an application 3554 if (callerUid == Process.SYSTEM_UID) { 3555 // Post an aysnc message to kill the application 3556 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3557 msg.arg1 = uid; 3558 msg.arg2 = 0; 3559 msg.obj = pkg; 3560 mHandler.sendMessage(msg); 3561 } else { 3562 throw new SecurityException(callerUid + " cannot kill pkg: " + 3563 pkg); 3564 } 3565 } 3566 3567 public void closeSystemDialogs(String reason) { 3568 enforceNotIsolatedCaller("closeSystemDialogs"); 3569 3570 final int uid = Binder.getCallingUid(); 3571 final long origId = Binder.clearCallingIdentity(); 3572 synchronized (this) { 3573 closeSystemDialogsLocked(uid, reason); 3574 } 3575 Binder.restoreCallingIdentity(origId); 3576 } 3577 3578 void closeSystemDialogsLocked(int callingUid, String reason) { 3579 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3580 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3581 if (reason != null) { 3582 intent.putExtra("reason", reason); 3583 } 3584 mWindowManager.closeSystemDialogs(reason); 3585 3586 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3587 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3588 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3589 r.stack.finishActivityLocked(r, i, 3590 Activity.RESULT_CANCELED, null, "close-sys"); 3591 } 3592 } 3593 3594 broadcastIntentLocked(null, null, intent, null, 3595 null, 0, null, null, null, false, false, -1, 3596 callingUid, 0 /* TODO: Verify */); 3597 } 3598 3599 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3600 throws RemoteException { 3601 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3602 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3603 for (int i=pids.length-1; i>=0; i--) { 3604 infos[i] = new Debug.MemoryInfo(); 3605 Debug.getMemoryInfo(pids[i], infos[i]); 3606 } 3607 return infos; 3608 } 3609 3610 public long[] getProcessPss(int[] pids) throws RemoteException { 3611 enforceNotIsolatedCaller("getProcessPss"); 3612 long[] pss = new long[pids.length]; 3613 for (int i=pids.length-1; i>=0; i--) { 3614 pss[i] = Debug.getPss(pids[i]); 3615 } 3616 return pss; 3617 } 3618 3619 public void killApplicationProcess(String processName, int uid) { 3620 if (processName == null) { 3621 return; 3622 } 3623 3624 int callerUid = Binder.getCallingUid(); 3625 // Only the system server can kill an application 3626 if (callerUid == Process.SYSTEM_UID) { 3627 synchronized (this) { 3628 ProcessRecord app = getProcessRecordLocked(processName, uid); 3629 if (app != null && app.thread != null) { 3630 try { 3631 app.thread.scheduleSuicide(); 3632 } catch (RemoteException e) { 3633 // If the other end already died, then our work here is done. 3634 } 3635 } else { 3636 Slog.w(TAG, "Process/uid not found attempting kill of " 3637 + processName + " / " + uid); 3638 } 3639 } 3640 } else { 3641 throw new SecurityException(callerUid + " cannot kill app process: " + 3642 processName); 3643 } 3644 } 3645 3646 private void forceStopPackageLocked(final String packageName, int uid) { 3647 forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid)); 3648 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3649 Uri.fromParts("package", packageName, null)); 3650 if (!mProcessesReady) { 3651 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3652 } 3653 intent.putExtra(Intent.EXTRA_UID, uid); 3654 broadcastIntentLocked(null, null, intent, 3655 null, null, 0, null, null, null, 3656 false, false, 3657 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3658 } 3659 3660 private final boolean killPackageProcessesLocked(String packageName, int uid, 3661 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3662 boolean evenPersistent, String reason) { 3663 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3664 3665 // Remove all processes this package may have touched: all with the 3666 // same UID (except for the system or root user), and all whose name 3667 // matches the package name. 3668 final String procNamePrefix = packageName + ":"; 3669 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3670 final int NA = apps.size(); 3671 for (int ia=0; ia<NA; ia++) { 3672 ProcessRecord app = apps.valueAt(ia); 3673 if (app.persistent && !evenPersistent) { 3674 // we don't kill persistent processes 3675 continue; 3676 } 3677 if (app.removed) { 3678 if (doit) { 3679 procs.add(app); 3680 } 3681 // If uid is specified and the uid and process name match 3682 // Or, the uid is not specified and the process name matches 3683 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3684 || ((app.processName.equals(packageName) 3685 || app.processName.startsWith(procNamePrefix)) 3686 && uid < 0))) { 3687 if (app.setAdj >= minOomAdj) { 3688 if (!doit) { 3689 return true; 3690 } 3691 app.removed = true; 3692 procs.add(app); 3693 } 3694 } 3695 } 3696 } 3697 3698 int N = procs.size(); 3699 for (int i=0; i<N; i++) { 3700 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3701 } 3702 return N > 0; 3703 } 3704 3705 private final boolean forceStopPackageLocked(String name, int uid, 3706 boolean callerWillRestart, boolean purgeCache, boolean doit, 3707 boolean evenPersistent, int userId) { 3708 int i; 3709 int N; 3710 3711 if (uid < 0) { 3712 try { 3713 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3714 } catch (RemoteException e) { 3715 } 3716 } 3717 3718 if (doit) { 3719 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3720 3721 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3722 while (badApps.hasNext()) { 3723 SparseArray<Long> ba = badApps.next(); 3724 if (ba.get(uid) != null) { 3725 badApps.remove(); 3726 } 3727 } 3728 } 3729 3730 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3731 callerWillRestart, false, doit, evenPersistent, "force stop"); 3732 3733 TaskRecord lastTask = null; 3734 for (i=0; i<mMainStack.mHistory.size(); i++) { 3735 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3736 final boolean samePackage = r.packageName.equals(name); 3737 if (r.userId == userId 3738 && (samePackage || r.task == lastTask) 3739 && (r.app == null || evenPersistent || !r.app.persistent)) { 3740 if (!doit) { 3741 if (r.finishing) { 3742 // If this activity is just finishing, then it is not 3743 // interesting as far as something to stop. 3744 continue; 3745 } 3746 return true; 3747 } 3748 didSomething = true; 3749 Slog.i(TAG, " Force finishing activity " + r); 3750 if (samePackage) { 3751 if (r.app != null) { 3752 r.app.removed = true; 3753 } 3754 r.app = null; 3755 } 3756 lastTask = r.task; 3757 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3758 null, "force-stop", true)) { 3759 i--; 3760 } 3761 } 3762 } 3763 3764 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3765 if (!doit) { 3766 return true; 3767 } 3768 didSomething = true; 3769 } 3770 3771 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3772 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3773 if (provider.info.packageName.equals(name) 3774 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3775 if (!doit) { 3776 return true; 3777 } 3778 didSomething = true; 3779 providers.add(provider); 3780 } 3781 } 3782 3783 N = providers.size(); 3784 for (i=0; i<N; i++) { 3785 removeDyingProviderLocked(null, providers.get(i), true); 3786 } 3787 3788 if (doit) { 3789 if (purgeCache) { 3790 AttributeCache ac = AttributeCache.instance(); 3791 if (ac != null) { 3792 ac.removePackage(name); 3793 } 3794 } 3795 if (mBooted) { 3796 mMainStack.resumeTopActivityLocked(null); 3797 mMainStack.scheduleIdleLocked(); 3798 } 3799 } 3800 3801 return didSomething; 3802 } 3803 3804 private final boolean removeProcessLocked(ProcessRecord app, 3805 boolean callerWillRestart, boolean allowRestart, String reason) { 3806 final String name = app.processName; 3807 final int uid = app.uid; 3808 if (DEBUG_PROCESSES) Slog.d( 3809 TAG, "Force removing proc " + app.toShortString() + " (" + name 3810 + "/" + uid + ")"); 3811 3812 mProcessNames.remove(name, uid); 3813 mIsolatedProcesses.remove(app.uid); 3814 if (mHeavyWeightProcess == app) { 3815 mHeavyWeightProcess = null; 3816 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3817 } 3818 boolean needRestart = false; 3819 if (app.pid > 0 && app.pid != MY_PID) { 3820 int pid = app.pid; 3821 synchronized (mPidsSelfLocked) { 3822 mPidsSelfLocked.remove(pid); 3823 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3824 } 3825 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3826 handleAppDiedLocked(app, true, allowRestart); 3827 mLruProcesses.remove(app); 3828 Process.killProcessQuiet(pid); 3829 3830 if (app.persistent && !app.isolated) { 3831 if (!callerWillRestart) { 3832 addAppLocked(app.info, false); 3833 } else { 3834 needRestart = true; 3835 } 3836 } 3837 } else { 3838 mRemovedProcesses.add(app); 3839 } 3840 3841 return needRestart; 3842 } 3843 3844 private final void processStartTimedOutLocked(ProcessRecord app) { 3845 final int pid = app.pid; 3846 boolean gone = false; 3847 synchronized (mPidsSelfLocked) { 3848 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3849 if (knownApp != null && knownApp.thread == null) { 3850 mPidsSelfLocked.remove(pid); 3851 gone = true; 3852 } 3853 } 3854 3855 if (gone) { 3856 Slog.w(TAG, "Process " + app + " failed to attach"); 3857 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3858 app.processName); 3859 mProcessNames.remove(app.processName, app.uid); 3860 mIsolatedProcesses.remove(app.uid); 3861 if (mHeavyWeightProcess == app) { 3862 mHeavyWeightProcess = null; 3863 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3864 } 3865 // Take care of any launching providers waiting for this process. 3866 checkAppInLaunchingProvidersLocked(app, true); 3867 // Take care of any services that are waiting for the process. 3868 mServices.processStartTimedOutLocked(app); 3869 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3870 app.processName, app.setAdj, "start timeout"); 3871 Process.killProcessQuiet(pid); 3872 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3873 Slog.w(TAG, "Unattached app died before backup, skipping"); 3874 try { 3875 IBackupManager bm = IBackupManager.Stub.asInterface( 3876 ServiceManager.getService(Context.BACKUP_SERVICE)); 3877 bm.agentDisconnected(app.info.packageName); 3878 } catch (RemoteException e) { 3879 // Can't happen; the backup manager is local 3880 } 3881 } 3882 if (isPendingBroadcastProcessLocked(pid)) { 3883 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3884 skipPendingBroadcastLocked(pid); 3885 } 3886 } else { 3887 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3888 } 3889 } 3890 3891 private final boolean attachApplicationLocked(IApplicationThread thread, 3892 int pid) { 3893 3894 // Find the application record that is being attached... either via 3895 // the pid if we are running in multiple processes, or just pull the 3896 // next app record if we are emulating process with anonymous threads. 3897 ProcessRecord app; 3898 if (pid != MY_PID && pid >= 0) { 3899 synchronized (mPidsSelfLocked) { 3900 app = mPidsSelfLocked.get(pid); 3901 } 3902 } else { 3903 app = null; 3904 } 3905 3906 if (app == null) { 3907 Slog.w(TAG, "No pending application record for pid " + pid 3908 + " (IApplicationThread " + thread + "); dropping process"); 3909 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3910 if (pid > 0 && pid != MY_PID) { 3911 Process.killProcessQuiet(pid); 3912 } else { 3913 try { 3914 thread.scheduleExit(); 3915 } catch (Exception e) { 3916 // Ignore exceptions. 3917 } 3918 } 3919 return false; 3920 } 3921 3922 // If this application record is still attached to a previous 3923 // process, clean it up now. 3924 if (app.thread != null) { 3925 handleAppDiedLocked(app, true, true); 3926 } 3927 3928 // Tell the process all about itself. 3929 3930 if (localLOGV) Slog.v( 3931 TAG, "Binding process pid " + pid + " to record " + app); 3932 3933 String processName = app.processName; 3934 try { 3935 AppDeathRecipient adr = new AppDeathRecipient( 3936 app, pid, thread); 3937 thread.asBinder().linkToDeath(adr, 0); 3938 app.deathRecipient = adr; 3939 } catch (RemoteException e) { 3940 app.resetPackageList(); 3941 startProcessLocked(app, "link fail", processName); 3942 return false; 3943 } 3944 3945 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3946 3947 app.thread = thread; 3948 app.curAdj = app.setAdj = -100; 3949 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3950 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3951 app.forcingToForeground = null; 3952 app.foregroundServices = false; 3953 app.hasShownUi = false; 3954 app.debugging = false; 3955 3956 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3957 3958 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3959 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3960 3961 if (!normalMode) { 3962 Slog.i(TAG, "Launching preboot mode app: " + app); 3963 } 3964 3965 if (localLOGV) Slog.v( 3966 TAG, "New app record " + app 3967 + " thread=" + thread.asBinder() + " pid=" + pid); 3968 try { 3969 int testMode = IApplicationThread.DEBUG_OFF; 3970 if (mDebugApp != null && mDebugApp.equals(processName)) { 3971 testMode = mWaitForDebugger 3972 ? IApplicationThread.DEBUG_WAIT 3973 : IApplicationThread.DEBUG_ON; 3974 app.debugging = true; 3975 if (mDebugTransient) { 3976 mDebugApp = mOrigDebugApp; 3977 mWaitForDebugger = mOrigWaitForDebugger; 3978 } 3979 } 3980 String profileFile = app.instrumentationProfileFile; 3981 ParcelFileDescriptor profileFd = null; 3982 boolean profileAutoStop = false; 3983 if (mProfileApp != null && mProfileApp.equals(processName)) { 3984 mProfileProc = app; 3985 profileFile = mProfileFile; 3986 profileFd = mProfileFd; 3987 profileAutoStop = mAutoStopProfiler; 3988 } 3989 boolean enableOpenGlTrace = false; 3990 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3991 enableOpenGlTrace = true; 3992 mOpenGlTraceApp = null; 3993 } 3994 3995 // If the app is being launched for restore or full backup, set it up specially 3996 boolean isRestrictedBackupMode = false; 3997 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3998 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3999 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4000 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4001 } 4002 4003 ensurePackageDexOpt(app.instrumentationInfo != null 4004 ? app.instrumentationInfo.packageName 4005 : app.info.packageName); 4006 if (app.instrumentationClass != null) { 4007 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4008 } 4009 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4010 + processName + " with config " + mConfiguration); 4011 ApplicationInfo appInfo = app.instrumentationInfo != null 4012 ? app.instrumentationInfo : app.info; 4013 app.compat = compatibilityInfoForPackageLocked(appInfo); 4014 if (profileFd != null) { 4015 profileFd = profileFd.dup(); 4016 } 4017 thread.bindApplication(processName, appInfo, providers, 4018 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4019 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4020 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4021 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4022 mCoreSettingsObserver.getCoreSettingsLocked()); 4023 updateLruProcessLocked(app, false, true); 4024 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4025 } catch (Exception e) { 4026 // todo: Yikes! What should we do? For now we will try to 4027 // start another process, but that could easily get us in 4028 // an infinite loop of restarting processes... 4029 Slog.w(TAG, "Exception thrown during bind!", e); 4030 4031 app.resetPackageList(); 4032 app.unlinkDeathRecipient(); 4033 startProcessLocked(app, "bind fail", processName); 4034 return false; 4035 } 4036 4037 // Remove this record from the list of starting applications. 4038 mPersistentStartingProcesses.remove(app); 4039 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4040 "Attach application locked removing on hold: " + app); 4041 mProcessesOnHold.remove(app); 4042 4043 boolean badApp = false; 4044 boolean didSomething = false; 4045 4046 // See if the top visible activity is waiting to run in this process... 4047 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4048 if (hr != null && normalMode) { 4049 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4050 && processName.equals(hr.processName)) { 4051 try { 4052 if (mHeadless) { 4053 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4054 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4055 didSomething = true; 4056 } 4057 } catch (Exception e) { 4058 Slog.w(TAG, "Exception in new application when starting activity " 4059 + hr.intent.getComponent().flattenToShortString(), e); 4060 badApp = true; 4061 } 4062 } else { 4063 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4064 } 4065 } 4066 4067 // Find any services that should be running in this process... 4068 if (!badApp) { 4069 try { 4070 didSomething |= mServices.attachApplicationLocked(app, processName); 4071 } catch (Exception e) { 4072 badApp = true; 4073 } 4074 } 4075 4076 // Check if a next-broadcast receiver is in this process... 4077 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4078 try { 4079 didSomething = sendPendingBroadcastsLocked(app); 4080 } catch (Exception e) { 4081 // If the app died trying to launch the receiver we declare it 'bad' 4082 badApp = true; 4083 } 4084 } 4085 4086 // Check whether the next backup agent is in this process... 4087 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4088 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4089 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4090 try { 4091 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4092 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4093 mBackupTarget.backupMode); 4094 } catch (Exception e) { 4095 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4096 e.printStackTrace(); 4097 } 4098 } 4099 4100 if (badApp) { 4101 // todo: Also need to kill application to deal with all 4102 // kinds of exceptions. 4103 handleAppDiedLocked(app, false, true); 4104 return false; 4105 } 4106 4107 if (!didSomething) { 4108 updateOomAdjLocked(); 4109 } 4110 4111 return true; 4112 } 4113 4114 public final void attachApplication(IApplicationThread thread) { 4115 synchronized (this) { 4116 int callingPid = Binder.getCallingPid(); 4117 final long origId = Binder.clearCallingIdentity(); 4118 attachApplicationLocked(thread, callingPid); 4119 Binder.restoreCallingIdentity(origId); 4120 } 4121 } 4122 4123 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4124 final long origId = Binder.clearCallingIdentity(); 4125 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4126 if (stopProfiling) { 4127 synchronized (this) { 4128 if (mProfileProc == r.app) { 4129 if (mProfileFd != null) { 4130 try { 4131 mProfileFd.close(); 4132 } catch (IOException e) { 4133 } 4134 clearProfilerLocked(); 4135 } 4136 } 4137 } 4138 } 4139 Binder.restoreCallingIdentity(origId); 4140 } 4141 4142 void enableScreenAfterBoot() { 4143 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4144 SystemClock.uptimeMillis()); 4145 mWindowManager.enableScreenAfterBoot(); 4146 4147 synchronized (this) { 4148 updateEventDispatchingLocked(); 4149 } 4150 } 4151 4152 public void showBootMessage(final CharSequence msg, final boolean always) { 4153 enforceNotIsolatedCaller("showBootMessage"); 4154 mWindowManager.showBootMessage(msg, always); 4155 } 4156 4157 public void dismissKeyguardOnNextActivity() { 4158 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4159 final long token = Binder.clearCallingIdentity(); 4160 try { 4161 synchronized (this) { 4162 if (mLockScreenShown) { 4163 mLockScreenShown = false; 4164 comeOutOfSleepIfNeededLocked(); 4165 } 4166 mMainStack.dismissKeyguardOnNextActivityLocked(); 4167 } 4168 } finally { 4169 Binder.restoreCallingIdentity(token); 4170 } 4171 } 4172 4173 final void finishBooting() { 4174 IntentFilter pkgFilter = new IntentFilter(); 4175 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4176 pkgFilter.addDataScheme("package"); 4177 mContext.registerReceiver(new BroadcastReceiver() { 4178 @Override 4179 public void onReceive(Context context, Intent intent) { 4180 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4181 if (pkgs != null) { 4182 for (String pkg : pkgs) { 4183 synchronized (ActivityManagerService.this) { 4184 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4185 setResultCode(Activity.RESULT_OK); 4186 return; 4187 } 4188 } 4189 } 4190 } 4191 } 4192 }, pkgFilter); 4193 4194 IntentFilter userFilter = new IntentFilter(); 4195 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4196 mContext.registerReceiver(new BroadcastReceiver() { 4197 @Override 4198 public void onReceive(Context context, Intent intent) { 4199 onUserRemoved(intent); 4200 } 4201 }, userFilter); 4202 4203 synchronized (this) { 4204 // Ensure that any processes we had put on hold are now started 4205 // up. 4206 final int NP = mProcessesOnHold.size(); 4207 if (NP > 0) { 4208 ArrayList<ProcessRecord> procs = 4209 new ArrayList<ProcessRecord>(mProcessesOnHold); 4210 for (int ip=0; ip<NP; ip++) { 4211 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4212 + procs.get(ip)); 4213 startProcessLocked(procs.get(ip), "on-hold", null); 4214 } 4215 } 4216 4217 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4218 // Start looking for apps that are abusing wake locks. 4219 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4220 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4221 // Tell anyone interested that we are done booting! 4222 SystemProperties.set("sys.boot_completed", "1"); 4223 SystemProperties.set("dev.bootcomplete", "1"); 4224 List<UserInfo> users = getUserManager().getUsers(); 4225 for (UserInfo user : users) { 4226 broadcastIntentLocked(null, null, 4227 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4228 null, null, 0, null, null, 4229 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4230 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4231 } 4232 } 4233 } 4234 } 4235 4236 final void ensureBootCompleted() { 4237 boolean booting; 4238 boolean enableScreen; 4239 synchronized (this) { 4240 booting = mBooting; 4241 mBooting = false; 4242 enableScreen = !mBooted; 4243 mBooted = true; 4244 } 4245 4246 if (booting) { 4247 finishBooting(); 4248 } 4249 4250 if (enableScreen) { 4251 enableScreenAfterBoot(); 4252 } 4253 } 4254 4255 public final void activityPaused(IBinder token) { 4256 final long origId = Binder.clearCallingIdentity(); 4257 mMainStack.activityPaused(token, false); 4258 Binder.restoreCallingIdentity(origId); 4259 } 4260 4261 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4262 CharSequence description) { 4263 if (localLOGV) Slog.v( 4264 TAG, "Activity stopped: token=" + token); 4265 4266 // Refuse possible leaked file descriptors 4267 if (icicle != null && icicle.hasFileDescriptors()) { 4268 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4269 } 4270 4271 ActivityRecord r = null; 4272 4273 final long origId = Binder.clearCallingIdentity(); 4274 4275 synchronized (this) { 4276 r = mMainStack.isInStackLocked(token); 4277 if (r != null) { 4278 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4279 } 4280 } 4281 4282 if (r != null) { 4283 sendPendingThumbnail(r, null, null, null, false); 4284 } 4285 4286 trimApplications(); 4287 4288 Binder.restoreCallingIdentity(origId); 4289 } 4290 4291 public final void activityDestroyed(IBinder token) { 4292 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4293 mMainStack.activityDestroyed(token); 4294 } 4295 4296 public String getCallingPackage(IBinder token) { 4297 synchronized (this) { 4298 ActivityRecord r = getCallingRecordLocked(token); 4299 return r != null && r.app != null ? r.info.packageName : null; 4300 } 4301 } 4302 4303 public ComponentName getCallingActivity(IBinder token) { 4304 synchronized (this) { 4305 ActivityRecord r = getCallingRecordLocked(token); 4306 return r != null ? r.intent.getComponent() : null; 4307 } 4308 } 4309 4310 private ActivityRecord getCallingRecordLocked(IBinder token) { 4311 ActivityRecord r = mMainStack.isInStackLocked(token); 4312 if (r == null) { 4313 return null; 4314 } 4315 return r.resultTo; 4316 } 4317 4318 public ComponentName getActivityClassForToken(IBinder token) { 4319 synchronized(this) { 4320 ActivityRecord r = mMainStack.isInStackLocked(token); 4321 if (r == null) { 4322 return null; 4323 } 4324 return r.intent.getComponent(); 4325 } 4326 } 4327 4328 public String getPackageForToken(IBinder token) { 4329 synchronized(this) { 4330 ActivityRecord r = mMainStack.isInStackLocked(token); 4331 if (r == null) { 4332 return null; 4333 } 4334 return r.packageName; 4335 } 4336 } 4337 4338 public IIntentSender getIntentSender(int type, 4339 String packageName, IBinder token, String resultWho, 4340 int requestCode, Intent[] intents, String[] resolvedTypes, 4341 int flags, Bundle options) { 4342 enforceNotIsolatedCaller("getIntentSender"); 4343 // Refuse possible leaked file descriptors 4344 if (intents != null) { 4345 if (intents.length < 1) { 4346 throw new IllegalArgumentException("Intents array length must be >= 1"); 4347 } 4348 for (int i=0; i<intents.length; i++) { 4349 Intent intent = intents[i]; 4350 if (intent != null) { 4351 if (intent.hasFileDescriptors()) { 4352 throw new IllegalArgumentException("File descriptors passed in Intent"); 4353 } 4354 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4355 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4356 throw new IllegalArgumentException( 4357 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4358 } 4359 intents[i] = new Intent(intent); 4360 } 4361 } 4362 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4363 throw new IllegalArgumentException( 4364 "Intent array length does not match resolvedTypes length"); 4365 } 4366 } 4367 if (options != null) { 4368 if (options.hasFileDescriptors()) { 4369 throw new IllegalArgumentException("File descriptors passed in options"); 4370 } 4371 } 4372 4373 synchronized(this) { 4374 int callingUid = Binder.getCallingUid(); 4375 try { 4376 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4377 int uid = AppGlobals.getPackageManager() 4378 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4379 if (!UserHandle.isSameApp(callingUid, uid)) { 4380 String msg = "Permission Denial: getIntentSender() from pid=" 4381 + Binder.getCallingPid() 4382 + ", uid=" + Binder.getCallingUid() 4383 + ", (need uid=" + uid + ")" 4384 + " is not allowed to send as package " + packageName; 4385 Slog.w(TAG, msg); 4386 throw new SecurityException(msg); 4387 } 4388 } 4389 4390 if (DEBUG_MU) 4391 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4392 + Binder.getOrigCallingUid()); 4393 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4394 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4395 4396 } catch (RemoteException e) { 4397 throw new SecurityException(e); 4398 } 4399 } 4400 } 4401 4402 IIntentSender getIntentSenderLocked(int type, 4403 String packageName, int callingUid, IBinder token, String resultWho, 4404 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4405 Bundle options) { 4406 if (DEBUG_MU) 4407 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4408 ActivityRecord activity = null; 4409 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4410 activity = mMainStack.isInStackLocked(token); 4411 if (activity == null) { 4412 return null; 4413 } 4414 if (activity.finishing) { 4415 return null; 4416 } 4417 } 4418 4419 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4420 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4421 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4422 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4423 |PendingIntent.FLAG_UPDATE_CURRENT); 4424 4425 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4426 type, packageName, activity, resultWho, 4427 requestCode, intents, resolvedTypes, flags, options); 4428 WeakReference<PendingIntentRecord> ref; 4429 ref = mIntentSenderRecords.get(key); 4430 PendingIntentRecord rec = ref != null ? ref.get() : null; 4431 if (rec != null) { 4432 if (!cancelCurrent) { 4433 if (updateCurrent) { 4434 if (rec.key.requestIntent != null) { 4435 rec.key.requestIntent.replaceExtras(intents != null ? 4436 intents[intents.length - 1] : null); 4437 } 4438 if (intents != null) { 4439 intents[intents.length-1] = rec.key.requestIntent; 4440 rec.key.allIntents = intents; 4441 rec.key.allResolvedTypes = resolvedTypes; 4442 } else { 4443 rec.key.allIntents = null; 4444 rec.key.allResolvedTypes = null; 4445 } 4446 } 4447 return rec; 4448 } 4449 rec.canceled = true; 4450 mIntentSenderRecords.remove(key); 4451 } 4452 if (noCreate) { 4453 return rec; 4454 } 4455 rec = new PendingIntentRecord(this, key, callingUid); 4456 mIntentSenderRecords.put(key, rec.ref); 4457 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4458 if (activity.pendingResults == null) { 4459 activity.pendingResults 4460 = new HashSet<WeakReference<PendingIntentRecord>>(); 4461 } 4462 activity.pendingResults.add(rec.ref); 4463 } 4464 return rec; 4465 } 4466 4467 public void cancelIntentSender(IIntentSender sender) { 4468 if (!(sender instanceof PendingIntentRecord)) { 4469 return; 4470 } 4471 synchronized(this) { 4472 PendingIntentRecord rec = (PendingIntentRecord)sender; 4473 try { 4474 int uid = AppGlobals.getPackageManager() 4475 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4476 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4477 String msg = "Permission Denial: cancelIntentSender() from pid=" 4478 + Binder.getCallingPid() 4479 + ", uid=" + Binder.getCallingUid() 4480 + " is not allowed to cancel packges " 4481 + rec.key.packageName; 4482 Slog.w(TAG, msg); 4483 throw new SecurityException(msg); 4484 } 4485 } catch (RemoteException e) { 4486 throw new SecurityException(e); 4487 } 4488 cancelIntentSenderLocked(rec, true); 4489 } 4490 } 4491 4492 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4493 rec.canceled = true; 4494 mIntentSenderRecords.remove(rec.key); 4495 if (cleanActivity && rec.key.activity != null) { 4496 rec.key.activity.pendingResults.remove(rec.ref); 4497 } 4498 } 4499 4500 public String getPackageForIntentSender(IIntentSender pendingResult) { 4501 if (!(pendingResult instanceof PendingIntentRecord)) { 4502 return null; 4503 } 4504 try { 4505 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4506 return res.key.packageName; 4507 } catch (ClassCastException e) { 4508 } 4509 return null; 4510 } 4511 4512 public int getUidForIntentSender(IIntentSender sender) { 4513 if (sender instanceof PendingIntentRecord) { 4514 try { 4515 PendingIntentRecord res = (PendingIntentRecord)sender; 4516 return res.uid; 4517 } catch (ClassCastException e) { 4518 } 4519 } 4520 return -1; 4521 } 4522 4523 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4524 if (!(pendingResult instanceof PendingIntentRecord)) { 4525 return false; 4526 } 4527 try { 4528 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4529 if (res.key.allIntents == null) { 4530 return false; 4531 } 4532 for (int i=0; i<res.key.allIntents.length; i++) { 4533 Intent intent = res.key.allIntents[i]; 4534 if (intent.getPackage() != null && intent.getComponent() != null) { 4535 return false; 4536 } 4537 } 4538 return true; 4539 } catch (ClassCastException e) { 4540 } 4541 return false; 4542 } 4543 4544 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4545 if (!(pendingResult instanceof PendingIntentRecord)) { 4546 return false; 4547 } 4548 try { 4549 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4550 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4551 return true; 4552 } 4553 return false; 4554 } catch (ClassCastException e) { 4555 } 4556 return false; 4557 } 4558 4559 public void setProcessLimit(int max) { 4560 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4561 "setProcessLimit()"); 4562 synchronized (this) { 4563 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4564 mProcessLimitOverride = max; 4565 } 4566 trimApplications(); 4567 } 4568 4569 public int getProcessLimit() { 4570 synchronized (this) { 4571 return mProcessLimitOverride; 4572 } 4573 } 4574 4575 void foregroundTokenDied(ForegroundToken token) { 4576 synchronized (ActivityManagerService.this) { 4577 synchronized (mPidsSelfLocked) { 4578 ForegroundToken cur 4579 = mForegroundProcesses.get(token.pid); 4580 if (cur != token) { 4581 return; 4582 } 4583 mForegroundProcesses.remove(token.pid); 4584 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4585 if (pr == null) { 4586 return; 4587 } 4588 pr.forcingToForeground = null; 4589 pr.foregroundServices = false; 4590 } 4591 updateOomAdjLocked(); 4592 } 4593 } 4594 4595 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4596 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4597 "setProcessForeground()"); 4598 synchronized(this) { 4599 boolean changed = false; 4600 4601 synchronized (mPidsSelfLocked) { 4602 ProcessRecord pr = mPidsSelfLocked.get(pid); 4603 if (pr == null && isForeground) { 4604 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4605 return; 4606 } 4607 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4608 if (oldToken != null) { 4609 oldToken.token.unlinkToDeath(oldToken, 0); 4610 mForegroundProcesses.remove(pid); 4611 if (pr != null) { 4612 pr.forcingToForeground = null; 4613 } 4614 changed = true; 4615 } 4616 if (isForeground && token != null) { 4617 ForegroundToken newToken = new ForegroundToken() { 4618 public void binderDied() { 4619 foregroundTokenDied(this); 4620 } 4621 }; 4622 newToken.pid = pid; 4623 newToken.token = token; 4624 try { 4625 token.linkToDeath(newToken, 0); 4626 mForegroundProcesses.put(pid, newToken); 4627 pr.forcingToForeground = token; 4628 changed = true; 4629 } catch (RemoteException e) { 4630 // If the process died while doing this, we will later 4631 // do the cleanup with the process death link. 4632 } 4633 } 4634 } 4635 4636 if (changed) { 4637 updateOomAdjLocked(); 4638 } 4639 } 4640 } 4641 4642 // ========================================================= 4643 // PERMISSIONS 4644 // ========================================================= 4645 4646 static class PermissionController extends IPermissionController.Stub { 4647 ActivityManagerService mActivityManagerService; 4648 PermissionController(ActivityManagerService activityManagerService) { 4649 mActivityManagerService = activityManagerService; 4650 } 4651 4652 public boolean checkPermission(String permission, int pid, int uid) { 4653 return mActivityManagerService.checkPermission(permission, pid, 4654 uid) == PackageManager.PERMISSION_GRANTED; 4655 } 4656 } 4657 4658 /** 4659 * This can be called with or without the global lock held. 4660 */ 4661 int checkComponentPermission(String permission, int pid, int uid, 4662 int owningUid, boolean exported) { 4663 // We might be performing an operation on behalf of an indirect binder 4664 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4665 // client identity accordingly before proceeding. 4666 Identity tlsIdentity = sCallerIdentity.get(); 4667 if (tlsIdentity != null) { 4668 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4669 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4670 uid = tlsIdentity.uid; 4671 pid = tlsIdentity.pid; 4672 } 4673 4674 if (pid == MY_PID) { 4675 return PackageManager.PERMISSION_GRANTED; 4676 } 4677 4678 return ActivityManager.checkComponentPermission(permission, uid, 4679 owningUid, exported); 4680 } 4681 4682 /** 4683 * As the only public entry point for permissions checking, this method 4684 * can enforce the semantic that requesting a check on a null global 4685 * permission is automatically denied. (Internally a null permission 4686 * string is used when calling {@link #checkComponentPermission} in cases 4687 * when only uid-based security is needed.) 4688 * 4689 * This can be called with or without the global lock held. 4690 */ 4691 public int checkPermission(String permission, int pid, int uid) { 4692 if (permission == null) { 4693 return PackageManager.PERMISSION_DENIED; 4694 } 4695 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4696 } 4697 4698 /** 4699 * Binder IPC calls go through the public entry point. 4700 * This can be called with or without the global lock held. 4701 */ 4702 int checkCallingPermission(String permission) { 4703 return checkPermission(permission, 4704 Binder.getCallingPid(), 4705 UserHandle.getAppId(Binder.getCallingUid())); 4706 } 4707 4708 /** 4709 * This can be called with or without the global lock held. 4710 */ 4711 void enforceCallingPermission(String permission, String func) { 4712 if (checkCallingPermission(permission) 4713 == PackageManager.PERMISSION_GRANTED) { 4714 return; 4715 } 4716 4717 String msg = "Permission Denial: " + func + " from pid=" 4718 + Binder.getCallingPid() 4719 + ", uid=" + Binder.getCallingUid() 4720 + " requires " + permission; 4721 Slog.w(TAG, msg); 4722 throw new SecurityException(msg); 4723 } 4724 4725 /** 4726 * Determine if UID is holding permissions required to access {@link Uri} in 4727 * the given {@link ProviderInfo}. Final permission checking is always done 4728 * in {@link ContentProvider}. 4729 */ 4730 private final boolean checkHoldingPermissionsLocked( 4731 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4732 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4733 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4734 4735 if (pi.applicationInfo.uid == uid) { 4736 return true; 4737 } else if (!pi.exported) { 4738 return false; 4739 } 4740 4741 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4742 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4743 try { 4744 // check if target holds top-level <provider> permissions 4745 if (!readMet && pi.readPermission != null 4746 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4747 readMet = true; 4748 } 4749 if (!writeMet && pi.writePermission != null 4750 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4751 writeMet = true; 4752 } 4753 4754 // track if unprotected read/write is allowed; any denied 4755 // <path-permission> below removes this ability 4756 boolean allowDefaultRead = pi.readPermission == null; 4757 boolean allowDefaultWrite = pi.writePermission == null; 4758 4759 // check if target holds any <path-permission> that match uri 4760 final PathPermission[] pps = pi.pathPermissions; 4761 if (pps != null) { 4762 final String path = uri.getPath(); 4763 int i = pps.length; 4764 while (i > 0 && (!readMet || !writeMet)) { 4765 i--; 4766 PathPermission pp = pps[i]; 4767 if (pp.match(path)) { 4768 if (!readMet) { 4769 final String pprperm = pp.getReadPermission(); 4770 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4771 + pprperm + " for " + pp.getPath() 4772 + ": match=" + pp.match(path) 4773 + " check=" + pm.checkUidPermission(pprperm, uid)); 4774 if (pprperm != null) { 4775 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4776 readMet = true; 4777 } else { 4778 allowDefaultRead = false; 4779 } 4780 } 4781 } 4782 if (!writeMet) { 4783 final String ppwperm = pp.getWritePermission(); 4784 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4785 + ppwperm + " for " + pp.getPath() 4786 + ": match=" + pp.match(path) 4787 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4788 if (ppwperm != null) { 4789 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4790 writeMet = true; 4791 } else { 4792 allowDefaultWrite = false; 4793 } 4794 } 4795 } 4796 } 4797 } 4798 } 4799 4800 // grant unprotected <provider> read/write, if not blocked by 4801 // <path-permission> above 4802 if (allowDefaultRead) readMet = true; 4803 if (allowDefaultWrite) writeMet = true; 4804 4805 } catch (RemoteException e) { 4806 return false; 4807 } 4808 4809 return readMet && writeMet; 4810 } 4811 4812 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4813 int modeFlags) { 4814 // Root gets to do everything. 4815 if (uid == 0) { 4816 return true; 4817 } 4818 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4819 if (perms == null) return false; 4820 UriPermission perm = perms.get(uri); 4821 if (perm == null) return false; 4822 return (modeFlags&perm.modeFlags) == modeFlags; 4823 } 4824 4825 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4826 enforceNotIsolatedCaller("checkUriPermission"); 4827 4828 // Another redirected-binder-call permissions check as in 4829 // {@link checkComponentPermission}. 4830 Identity tlsIdentity = sCallerIdentity.get(); 4831 if (tlsIdentity != null) { 4832 uid = tlsIdentity.uid; 4833 pid = tlsIdentity.pid; 4834 } 4835 4836 uid = UserHandle.getAppId(uid); 4837 // Our own process gets to do everything. 4838 if (pid == MY_PID) { 4839 return PackageManager.PERMISSION_GRANTED; 4840 } 4841 synchronized(this) { 4842 return checkUriPermissionLocked(uri, uid, modeFlags) 4843 ? PackageManager.PERMISSION_GRANTED 4844 : PackageManager.PERMISSION_DENIED; 4845 } 4846 } 4847 4848 /** 4849 * Check if the targetPkg can be granted permission to access uri by 4850 * the callingUid using the given modeFlags. Throws a security exception 4851 * if callingUid is not allowed to do this. Returns the uid of the target 4852 * if the URI permission grant should be performed; returns -1 if it is not 4853 * needed (for example targetPkg already has permission to access the URI). 4854 * If you already know the uid of the target, you can supply it in 4855 * lastTargetUid else set that to -1. 4856 */ 4857 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4858 Uri uri, int modeFlags, int lastTargetUid) { 4859 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4860 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4861 if (modeFlags == 0) { 4862 return -1; 4863 } 4864 4865 if (targetPkg != null) { 4866 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4867 "Checking grant " + targetPkg + " permission to " + uri); 4868 } 4869 4870 final IPackageManager pm = AppGlobals.getPackageManager(); 4871 4872 // If this is not a content: uri, we can't do anything with it. 4873 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4874 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4875 "Can't grant URI permission for non-content URI: " + uri); 4876 return -1; 4877 } 4878 4879 String name = uri.getAuthority(); 4880 ProviderInfo pi = null; 4881 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4882 UserHandle.getUserId(callingUid)); 4883 if (cpr != null) { 4884 pi = cpr.info; 4885 } else { 4886 try { 4887 pi = pm.resolveContentProvider(name, 4888 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4889 } catch (RemoteException ex) { 4890 } 4891 } 4892 if (pi == null) { 4893 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4894 return -1; 4895 } 4896 4897 int targetUid = lastTargetUid; 4898 if (targetUid < 0 && targetPkg != null) { 4899 try { 4900 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4901 if (targetUid < 0) { 4902 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4903 "Can't grant URI permission no uid for: " + targetPkg); 4904 return -1; 4905 } 4906 } catch (RemoteException ex) { 4907 return -1; 4908 } 4909 } 4910 4911 if (targetUid >= 0) { 4912 // First... does the target actually need this permission? 4913 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4914 // No need to grant the target this permission. 4915 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4916 "Target " + targetPkg + " already has full permission to " + uri); 4917 return -1; 4918 } 4919 } else { 4920 // First... there is no target package, so can anyone access it? 4921 boolean allowed = pi.exported; 4922 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4923 if (pi.readPermission != null) { 4924 allowed = false; 4925 } 4926 } 4927 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4928 if (pi.writePermission != null) { 4929 allowed = false; 4930 } 4931 } 4932 if (allowed) { 4933 return -1; 4934 } 4935 } 4936 4937 // Second... is the provider allowing granting of URI permissions? 4938 if (!pi.grantUriPermissions) { 4939 throw new SecurityException("Provider " + pi.packageName 4940 + "/" + pi.name 4941 + " does not allow granting of Uri permissions (uri " 4942 + uri + ")"); 4943 } 4944 if (pi.uriPermissionPatterns != null) { 4945 final int N = pi.uriPermissionPatterns.length; 4946 boolean allowed = false; 4947 for (int i=0; i<N; i++) { 4948 if (pi.uriPermissionPatterns[i] != null 4949 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4950 allowed = true; 4951 break; 4952 } 4953 } 4954 if (!allowed) { 4955 throw new SecurityException("Provider " + pi.packageName 4956 + "/" + pi.name 4957 + " does not allow granting of permission to path of Uri " 4958 + uri); 4959 } 4960 } 4961 4962 // Third... does the caller itself have permission to access 4963 // this uri? 4964 if (callingUid != Process.myUid()) { 4965 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4966 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4967 throw new SecurityException("Uid " + callingUid 4968 + " does not have permission to uri " + uri); 4969 } 4970 } 4971 } 4972 4973 return targetUid; 4974 } 4975 4976 public int checkGrantUriPermission(int callingUid, String targetPkg, 4977 Uri uri, int modeFlags) { 4978 enforceNotIsolatedCaller("checkGrantUriPermission"); 4979 synchronized(this) { 4980 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4981 } 4982 } 4983 4984 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4985 Uri uri, int modeFlags, UriPermissionOwner owner) { 4986 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4987 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4988 if (modeFlags == 0) { 4989 return; 4990 } 4991 4992 // So here we are: the caller has the assumed permission 4993 // to the uri, and the target doesn't. Let's now give this to 4994 // the target. 4995 4996 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4997 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4998 4999 HashMap<Uri, UriPermission> targetUris 5000 = mGrantedUriPermissions.get(targetUid); 5001 if (targetUris == null) { 5002 targetUris = new HashMap<Uri, UriPermission>(); 5003 mGrantedUriPermissions.put(targetUid, targetUris); 5004 } 5005 5006 UriPermission perm = targetUris.get(uri); 5007 if (perm == null) { 5008 perm = new UriPermission(targetUid, uri); 5009 targetUris.put(uri, perm); 5010 } 5011 5012 perm.modeFlags |= modeFlags; 5013 if (owner == null) { 5014 perm.globalModeFlags |= modeFlags; 5015 } else { 5016 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5017 perm.readOwners.add(owner); 5018 owner.addReadPermission(perm); 5019 } 5020 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5021 perm.writeOwners.add(owner); 5022 owner.addWritePermission(perm); 5023 } 5024 } 5025 } 5026 5027 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5028 int modeFlags, UriPermissionOwner owner) { 5029 if (targetPkg == null) { 5030 throw new NullPointerException("targetPkg"); 5031 } 5032 5033 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5034 if (targetUid < 0) { 5035 return; 5036 } 5037 5038 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5039 } 5040 5041 static class NeededUriGrants extends ArrayList<Uri> { 5042 final String targetPkg; 5043 final int targetUid; 5044 final int flags; 5045 5046 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5047 targetPkg = _targetPkg; 5048 targetUid = _targetUid; 5049 flags = _flags; 5050 } 5051 } 5052 5053 /** 5054 * Like checkGrantUriPermissionLocked, but takes an Intent. 5055 */ 5056 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5057 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5058 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5059 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5060 + " clip=" + (intent != null ? intent.getClipData() : null) 5061 + " from " + intent + "; flags=0x" 5062 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5063 5064 if (targetPkg == null) { 5065 throw new NullPointerException("targetPkg"); 5066 } 5067 5068 if (intent == null) { 5069 return null; 5070 } 5071 Uri data = intent.getData(); 5072 ClipData clip = intent.getClipData(); 5073 if (data == null && clip == null) { 5074 return null; 5075 } 5076 if (data != null) { 5077 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5078 mode, needed != null ? needed.targetUid : -1); 5079 if (target > 0) { 5080 if (needed == null) { 5081 needed = new NeededUriGrants(targetPkg, target, mode); 5082 } 5083 needed.add(data); 5084 } 5085 } 5086 if (clip != null) { 5087 for (int i=0; i<clip.getItemCount(); i++) { 5088 Uri uri = clip.getItemAt(i).getUri(); 5089 if (uri != null) { 5090 int target = -1; 5091 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5092 mode, needed != null ? needed.targetUid : -1); 5093 if (target > 0) { 5094 if (needed == null) { 5095 needed = new NeededUriGrants(targetPkg, target, mode); 5096 } 5097 needed.add(uri); 5098 } 5099 } else { 5100 Intent clipIntent = clip.getItemAt(i).getIntent(); 5101 if (clipIntent != null) { 5102 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5103 callingUid, targetPkg, clipIntent, mode, needed); 5104 if (newNeeded != null) { 5105 needed = newNeeded; 5106 } 5107 } 5108 } 5109 } 5110 } 5111 5112 return needed; 5113 } 5114 5115 /** 5116 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5117 */ 5118 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5119 UriPermissionOwner owner) { 5120 if (needed != null) { 5121 for (int i=0; i<needed.size(); i++) { 5122 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5123 needed.get(i), needed.flags, owner); 5124 } 5125 } 5126 } 5127 5128 void grantUriPermissionFromIntentLocked(int callingUid, 5129 String targetPkg, Intent intent, UriPermissionOwner owner) { 5130 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5131 intent, intent != null ? intent.getFlags() : 0, null); 5132 if (needed == null) { 5133 return; 5134 } 5135 5136 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5137 } 5138 5139 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5140 Uri uri, int modeFlags) { 5141 enforceNotIsolatedCaller("grantUriPermission"); 5142 synchronized(this) { 5143 final ProcessRecord r = getRecordForAppLocked(caller); 5144 if (r == null) { 5145 throw new SecurityException("Unable to find app for caller " 5146 + caller 5147 + " when granting permission to uri " + uri); 5148 } 5149 if (targetPkg == null) { 5150 throw new IllegalArgumentException("null target"); 5151 } 5152 if (uri == null) { 5153 throw new IllegalArgumentException("null uri"); 5154 } 5155 5156 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5157 null); 5158 } 5159 } 5160 5161 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5162 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5163 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5164 HashMap<Uri, UriPermission> perms 5165 = mGrantedUriPermissions.get(perm.uid); 5166 if (perms != null) { 5167 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5168 "Removing " + perm.uid + " permission to " + perm.uri); 5169 perms.remove(perm.uri); 5170 if (perms.size() == 0) { 5171 mGrantedUriPermissions.remove(perm.uid); 5172 } 5173 } 5174 } 5175 } 5176 5177 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5178 int modeFlags) { 5179 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5180 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5181 if (modeFlags == 0) { 5182 return; 5183 } 5184 5185 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5186 "Revoking all granted permissions to " + uri); 5187 5188 final IPackageManager pm = AppGlobals.getPackageManager(); 5189 5190 final String authority = uri.getAuthority(); 5191 ProviderInfo pi = null; 5192 int userId = UserHandle.getUserId(callingUid); 5193 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5194 if (cpr != null) { 5195 pi = cpr.info; 5196 } else { 5197 try { 5198 pi = pm.resolveContentProvider(authority, 5199 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5200 } catch (RemoteException ex) { 5201 } 5202 } 5203 if (pi == null) { 5204 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5205 return; 5206 } 5207 5208 // Does the caller have this permission on the URI? 5209 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5210 // Right now, if you are not the original owner of the permission, 5211 // you are not allowed to revoke it. 5212 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5213 throw new SecurityException("Uid " + callingUid 5214 + " does not have permission to uri " + uri); 5215 //} 5216 } 5217 5218 // Go through all of the permissions and remove any that match. 5219 final List<String> SEGMENTS = uri.getPathSegments(); 5220 if (SEGMENTS != null) { 5221 final int NS = SEGMENTS.size(); 5222 int N = mGrantedUriPermissions.size(); 5223 for (int i=0; i<N; i++) { 5224 HashMap<Uri, UriPermission> perms 5225 = mGrantedUriPermissions.valueAt(i); 5226 Iterator<UriPermission> it = perms.values().iterator(); 5227 toploop: 5228 while (it.hasNext()) { 5229 UriPermission perm = it.next(); 5230 Uri targetUri = perm.uri; 5231 if (!authority.equals(targetUri.getAuthority())) { 5232 continue; 5233 } 5234 List<String> targetSegments = targetUri.getPathSegments(); 5235 if (targetSegments == null) { 5236 continue; 5237 } 5238 if (targetSegments.size() < NS) { 5239 continue; 5240 } 5241 for (int j=0; j<NS; j++) { 5242 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5243 continue toploop; 5244 } 5245 } 5246 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5247 "Revoking " + perm.uid + " permission to " + perm.uri); 5248 perm.clearModes(modeFlags); 5249 if (perm.modeFlags == 0) { 5250 it.remove(); 5251 } 5252 } 5253 if (perms.size() == 0) { 5254 mGrantedUriPermissions.remove( 5255 mGrantedUriPermissions.keyAt(i)); 5256 N--; 5257 i--; 5258 } 5259 } 5260 } 5261 } 5262 5263 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5264 int modeFlags) { 5265 enforceNotIsolatedCaller("revokeUriPermission"); 5266 synchronized(this) { 5267 final ProcessRecord r = getRecordForAppLocked(caller); 5268 if (r == null) { 5269 throw new SecurityException("Unable to find app for caller " 5270 + caller 5271 + " when revoking permission to uri " + uri); 5272 } 5273 if (uri == null) { 5274 Slog.w(TAG, "revokeUriPermission: null uri"); 5275 return; 5276 } 5277 5278 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5279 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5280 if (modeFlags == 0) { 5281 return; 5282 } 5283 5284 final IPackageManager pm = AppGlobals.getPackageManager(); 5285 5286 final String authority = uri.getAuthority(); 5287 ProviderInfo pi = null; 5288 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5289 if (cpr != null) { 5290 pi = cpr.info; 5291 } else { 5292 try { 5293 pi = pm.resolveContentProvider(authority, 5294 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5295 } catch (RemoteException ex) { 5296 } 5297 } 5298 if (pi == null) { 5299 Slog.w(TAG, "No content provider found for permission revoke: " 5300 + uri.toSafeString()); 5301 return; 5302 } 5303 5304 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5305 } 5306 } 5307 5308 @Override 5309 public IBinder newUriPermissionOwner(String name) { 5310 enforceNotIsolatedCaller("newUriPermissionOwner"); 5311 synchronized(this) { 5312 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5313 return owner.getExternalTokenLocked(); 5314 } 5315 } 5316 5317 @Override 5318 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5319 Uri uri, int modeFlags) { 5320 synchronized(this) { 5321 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5322 if (owner == null) { 5323 throw new IllegalArgumentException("Unknown owner: " + token); 5324 } 5325 if (fromUid != Binder.getCallingUid()) { 5326 if (Binder.getCallingUid() != Process.myUid()) { 5327 // Only system code can grant URI permissions on behalf 5328 // of other users. 5329 throw new SecurityException("nice try"); 5330 } 5331 } 5332 if (targetPkg == null) { 5333 throw new IllegalArgumentException("null target"); 5334 } 5335 if (uri == null) { 5336 throw new IllegalArgumentException("null uri"); 5337 } 5338 5339 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5340 } 5341 } 5342 5343 @Override 5344 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5345 synchronized(this) { 5346 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5347 if (owner == null) { 5348 throw new IllegalArgumentException("Unknown owner: " + token); 5349 } 5350 5351 if (uri == null) { 5352 owner.removeUriPermissionsLocked(mode); 5353 } else { 5354 owner.removeUriPermissionLocked(uri, mode); 5355 } 5356 } 5357 } 5358 5359 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5360 synchronized (this) { 5361 ProcessRecord app = 5362 who != null ? getRecordForAppLocked(who) : null; 5363 if (app == null) return; 5364 5365 Message msg = Message.obtain(); 5366 msg.what = WAIT_FOR_DEBUGGER_MSG; 5367 msg.obj = app; 5368 msg.arg1 = waiting ? 1 : 0; 5369 mHandler.sendMessage(msg); 5370 } 5371 } 5372 5373 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5374 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5375 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5376 outInfo.availMem = Process.getFreeMemory(); 5377 outInfo.totalMem = Process.getTotalMemory(); 5378 outInfo.threshold = homeAppMem; 5379 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5380 outInfo.hiddenAppThreshold = hiddenAppMem; 5381 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5382 ProcessList.SERVICE_ADJ); 5383 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5384 ProcessList.VISIBLE_APP_ADJ); 5385 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5386 ProcessList.FOREGROUND_APP_ADJ); 5387 } 5388 5389 // ========================================================= 5390 // TASK MANAGEMENT 5391 // ========================================================= 5392 5393 public List getTasks(int maxNum, int flags, 5394 IThumbnailReceiver receiver) { 5395 ArrayList list = new ArrayList(); 5396 5397 PendingThumbnailsRecord pending = null; 5398 IApplicationThread topThumbnail = null; 5399 ActivityRecord topRecord = null; 5400 5401 synchronized(this) { 5402 if (localLOGV) Slog.v( 5403 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5404 + ", receiver=" + receiver); 5405 5406 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5407 != PackageManager.PERMISSION_GRANTED) { 5408 if (receiver != null) { 5409 // If the caller wants to wait for pending thumbnails, 5410 // it ain't gonna get them. 5411 try { 5412 receiver.finished(); 5413 } catch (RemoteException ex) { 5414 } 5415 } 5416 String msg = "Permission Denial: getTasks() from pid=" 5417 + Binder.getCallingPid() 5418 + ", uid=" + Binder.getCallingUid() 5419 + " requires " + android.Manifest.permission.GET_TASKS; 5420 Slog.w(TAG, msg); 5421 throw new SecurityException(msg); 5422 } 5423 5424 int pos = mMainStack.mHistory.size()-1; 5425 ActivityRecord next = 5426 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5427 ActivityRecord top = null; 5428 TaskRecord curTask = null; 5429 int numActivities = 0; 5430 int numRunning = 0; 5431 while (pos >= 0 && maxNum > 0) { 5432 final ActivityRecord r = next; 5433 pos--; 5434 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5435 5436 // Initialize state for next task if needed. 5437 if (top == null || 5438 (top.state == ActivityState.INITIALIZING 5439 && top.task == r.task)) { 5440 top = r; 5441 curTask = r.task; 5442 numActivities = numRunning = 0; 5443 } 5444 5445 // Add 'r' into the current task. 5446 numActivities++; 5447 if (r.app != null && r.app.thread != null) { 5448 numRunning++; 5449 } 5450 5451 if (localLOGV) Slog.v( 5452 TAG, r.intent.getComponent().flattenToShortString() 5453 + ": task=" + r.task); 5454 5455 // If the next one is a different task, generate a new 5456 // TaskInfo entry for what we have. 5457 if (next == null || next.task != curTask) { 5458 ActivityManager.RunningTaskInfo ci 5459 = new ActivityManager.RunningTaskInfo(); 5460 ci.id = curTask.taskId; 5461 ci.baseActivity = r.intent.getComponent(); 5462 ci.topActivity = top.intent.getComponent(); 5463 if (top.thumbHolder != null) { 5464 ci.description = top.thumbHolder.lastDescription; 5465 } 5466 ci.numActivities = numActivities; 5467 ci.numRunning = numRunning; 5468 //System.out.println( 5469 // "#" + maxNum + ": " + " descr=" + ci.description); 5470 if (ci.thumbnail == null && receiver != null) { 5471 if (localLOGV) Slog.v( 5472 TAG, "State=" + top.state + "Idle=" + top.idle 5473 + " app=" + top.app 5474 + " thr=" + (top.app != null ? top.app.thread : null)); 5475 if (top.state == ActivityState.RESUMED 5476 || top.state == ActivityState.PAUSING) { 5477 if (top.idle && top.app != null 5478 && top.app.thread != null) { 5479 topRecord = top; 5480 topThumbnail = top.app.thread; 5481 } else { 5482 top.thumbnailNeeded = true; 5483 } 5484 } 5485 if (pending == null) { 5486 pending = new PendingThumbnailsRecord(receiver); 5487 } 5488 pending.pendingRecords.add(top); 5489 } 5490 list.add(ci); 5491 maxNum--; 5492 top = null; 5493 } 5494 } 5495 5496 if (pending != null) { 5497 mPendingThumbnails.add(pending); 5498 } 5499 } 5500 5501 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5502 5503 if (topThumbnail != null) { 5504 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5505 try { 5506 topThumbnail.requestThumbnail(topRecord.appToken); 5507 } catch (Exception e) { 5508 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5509 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5510 } 5511 } 5512 5513 if (pending == null && receiver != null) { 5514 // In this case all thumbnails were available and the client 5515 // is being asked to be told when the remaining ones come in... 5516 // which is unusually, since the top-most currently running 5517 // activity should never have a canned thumbnail! Oh well. 5518 try { 5519 receiver.finished(); 5520 } catch (RemoteException ex) { 5521 } 5522 } 5523 5524 return list; 5525 } 5526 5527 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5528 int flags, int userId) { 5529 final int callingUid = Binder.getCallingUid(); 5530 if (userId != UserHandle.getCallingUserId()) { 5531 // Check if the caller is holding permissions for cross-user requests. 5532 if (checkComponentPermission( 5533 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5534 Binder.getCallingPid(), callingUid, -1, true) 5535 != PackageManager.PERMISSION_GRANTED) { 5536 String msg = "Permission Denial: " 5537 + "Request to get recent tasks for user " + userId 5538 + " but is calling from user " + UserHandle.getUserId(callingUid) 5539 + "; this requires " 5540 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5541 Slog.w(TAG, msg); 5542 throw new SecurityException(msg); 5543 } else { 5544 if (userId == UserHandle.USER_CURRENT) { 5545 userId = mCurrentUserId; 5546 } 5547 } 5548 } 5549 5550 synchronized (this) { 5551 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5552 "getRecentTasks()"); 5553 final boolean detailed = checkCallingPermission( 5554 android.Manifest.permission.GET_DETAILED_TASKS) 5555 == PackageManager.PERMISSION_GRANTED; 5556 5557 IPackageManager pm = AppGlobals.getPackageManager(); 5558 5559 final int N = mRecentTasks.size(); 5560 ArrayList<ActivityManager.RecentTaskInfo> res 5561 = new ArrayList<ActivityManager.RecentTaskInfo>( 5562 maxNum < N ? maxNum : N); 5563 for (int i=0; i<N && maxNum > 0; i++) { 5564 TaskRecord tr = mRecentTasks.get(i); 5565 // Only add calling user's recent tasks 5566 if (tr.userId != userId) continue; 5567 // Return the entry if desired by the caller. We always return 5568 // the first entry, because callers always expect this to be the 5569 // foreground app. We may filter others if the caller has 5570 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5571 // we should exclude the entry. 5572 5573 if (i == 0 5574 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5575 || (tr.intent == null) 5576 || ((tr.intent.getFlags() 5577 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5578 ActivityManager.RecentTaskInfo rti 5579 = new ActivityManager.RecentTaskInfo(); 5580 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5581 rti.persistentId = tr.taskId; 5582 rti.baseIntent = new Intent( 5583 tr.intent != null ? tr.intent : tr.affinityIntent); 5584 if (!detailed) { 5585 rti.baseIntent.replaceExtras((Bundle)null); 5586 } 5587 rti.origActivity = tr.origActivity; 5588 rti.description = tr.lastDescription; 5589 5590 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5591 // Check whether this activity is currently available. 5592 try { 5593 if (rti.origActivity != null) { 5594 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5595 == null) { 5596 continue; 5597 } 5598 } else if (rti.baseIntent != null) { 5599 if (pm.queryIntentActivities(rti.baseIntent, 5600 null, 0, userId) == null) { 5601 continue; 5602 } 5603 } 5604 } catch (RemoteException e) { 5605 // Will never happen. 5606 } 5607 } 5608 5609 res.add(rti); 5610 maxNum--; 5611 } 5612 } 5613 return res; 5614 } 5615 } 5616 5617 private TaskRecord taskForIdLocked(int id) { 5618 final int N = mRecentTasks.size(); 5619 for (int i=0; i<N; i++) { 5620 TaskRecord tr = mRecentTasks.get(i); 5621 if (tr.taskId == id) { 5622 return tr; 5623 } 5624 } 5625 return null; 5626 } 5627 5628 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5629 synchronized (this) { 5630 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5631 "getTaskThumbnails()"); 5632 TaskRecord tr = taskForIdLocked(id); 5633 if (tr != null) { 5634 return mMainStack.getTaskThumbnailsLocked(tr); 5635 } 5636 } 5637 return null; 5638 } 5639 5640 public boolean removeSubTask(int taskId, int subTaskIndex) { 5641 synchronized (this) { 5642 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5643 "removeSubTask()"); 5644 long ident = Binder.clearCallingIdentity(); 5645 try { 5646 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5647 true) != null; 5648 } finally { 5649 Binder.restoreCallingIdentity(ident); 5650 } 5651 } 5652 } 5653 5654 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5655 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5656 Intent baseIntent = new Intent( 5657 tr.intent != null ? tr.intent : tr.affinityIntent); 5658 ComponentName component = baseIntent.getComponent(); 5659 if (component == null) { 5660 Slog.w(TAG, "Now component for base intent of task: " + tr); 5661 return; 5662 } 5663 5664 // Find any running services associated with this app. 5665 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5666 5667 if (killProcesses) { 5668 // Find any running processes associated with this app. 5669 final String pkg = component.getPackageName(); 5670 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5671 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5672 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5673 for (int i=0; i<uids.size(); i++) { 5674 ProcessRecord proc = uids.valueAt(i); 5675 if (proc.userId != tr.userId) { 5676 continue; 5677 } 5678 if (!proc.pkgList.contains(pkg)) { 5679 continue; 5680 } 5681 procs.add(proc); 5682 } 5683 } 5684 5685 // Kill the running processes. 5686 for (int i=0; i<procs.size(); i++) { 5687 ProcessRecord pr = procs.get(i); 5688 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5689 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5690 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5691 pr.processName, pr.setAdj, "remove task"); 5692 pr.killedBackground = true; 5693 Process.killProcessQuiet(pr.pid); 5694 } else { 5695 pr.waitingToKill = "remove task"; 5696 } 5697 } 5698 } 5699 } 5700 5701 public boolean removeTask(int taskId, int flags) { 5702 synchronized (this) { 5703 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5704 "removeTask()"); 5705 long ident = Binder.clearCallingIdentity(); 5706 try { 5707 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5708 false); 5709 if (r != null) { 5710 mRecentTasks.remove(r.task); 5711 cleanUpRemovedTaskLocked(r.task, flags); 5712 return true; 5713 } else { 5714 TaskRecord tr = null; 5715 int i=0; 5716 while (i < mRecentTasks.size()) { 5717 TaskRecord t = mRecentTasks.get(i); 5718 if (t.taskId == taskId) { 5719 tr = t; 5720 break; 5721 } 5722 i++; 5723 } 5724 if (tr != null) { 5725 if (tr.numActivities <= 0) { 5726 // Caller is just removing a recent task that is 5727 // not actively running. That is easy! 5728 mRecentTasks.remove(i); 5729 cleanUpRemovedTaskLocked(tr, flags); 5730 return true; 5731 } else { 5732 Slog.w(TAG, "removeTask: task " + taskId 5733 + " does not have activities to remove, " 5734 + " but numActivities=" + tr.numActivities 5735 + ": " + tr); 5736 } 5737 } 5738 } 5739 } finally { 5740 Binder.restoreCallingIdentity(ident); 5741 } 5742 } 5743 return false; 5744 } 5745 5746 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5747 int j; 5748 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5749 TaskRecord jt = startTask; 5750 5751 // First look backwards 5752 for (j=startIndex-1; j>=0; j--) { 5753 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5754 if (r.task != jt) { 5755 jt = r.task; 5756 if (affinity.equals(jt.affinity)) { 5757 return j; 5758 } 5759 } 5760 } 5761 5762 // Now look forwards 5763 final int N = mMainStack.mHistory.size(); 5764 jt = startTask; 5765 for (j=startIndex+1; j<N; j++) { 5766 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5767 if (r.task != jt) { 5768 if (affinity.equals(jt.affinity)) { 5769 return j; 5770 } 5771 jt = r.task; 5772 } 5773 } 5774 5775 // Might it be at the top? 5776 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5777 return N-1; 5778 } 5779 5780 return -1; 5781 } 5782 5783 /** 5784 * TODO: Add mController hook 5785 */ 5786 public void moveTaskToFront(int task, int flags, Bundle options) { 5787 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5788 "moveTaskToFront()"); 5789 5790 synchronized(this) { 5791 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5792 Binder.getCallingUid(), "Task to front")) { 5793 ActivityOptions.abort(options); 5794 return; 5795 } 5796 final long origId = Binder.clearCallingIdentity(); 5797 try { 5798 TaskRecord tr = taskForIdLocked(task); 5799 if (tr != null) { 5800 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5801 mMainStack.mUserLeaving = true; 5802 } 5803 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5804 // Caller wants the home activity moved with it. To accomplish this, 5805 // we'll just move the home task to the top first. 5806 mMainStack.moveHomeToFrontLocked(); 5807 } 5808 mMainStack.moveTaskToFrontLocked(tr, null, options); 5809 return; 5810 } 5811 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5812 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5813 if (hr.task.taskId == task) { 5814 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5815 mMainStack.mUserLeaving = true; 5816 } 5817 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5818 // Caller wants the home activity moved with it. To accomplish this, 5819 // we'll just move the home task to the top first. 5820 mMainStack.moveHomeToFrontLocked(); 5821 } 5822 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5823 return; 5824 } 5825 } 5826 } finally { 5827 Binder.restoreCallingIdentity(origId); 5828 } 5829 ActivityOptions.abort(options); 5830 } 5831 } 5832 5833 public void moveTaskToBack(int task) { 5834 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5835 "moveTaskToBack()"); 5836 5837 synchronized(this) { 5838 if (mMainStack.mResumedActivity != null 5839 && mMainStack.mResumedActivity.task.taskId == task) { 5840 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5841 Binder.getCallingUid(), "Task to back")) { 5842 return; 5843 } 5844 } 5845 final long origId = Binder.clearCallingIdentity(); 5846 mMainStack.moveTaskToBackLocked(task, null); 5847 Binder.restoreCallingIdentity(origId); 5848 } 5849 } 5850 5851 /** 5852 * Moves an activity, and all of the other activities within the same task, to the bottom 5853 * of the history stack. The activity's order within the task is unchanged. 5854 * 5855 * @param token A reference to the activity we wish to move 5856 * @param nonRoot If false then this only works if the activity is the root 5857 * of a task; if true it will work for any activity in a task. 5858 * @return Returns true if the move completed, false if not. 5859 */ 5860 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5861 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5862 synchronized(this) { 5863 final long origId = Binder.clearCallingIdentity(); 5864 int taskId = getTaskForActivityLocked(token, !nonRoot); 5865 if (taskId >= 0) { 5866 return mMainStack.moveTaskToBackLocked(taskId, null); 5867 } 5868 Binder.restoreCallingIdentity(origId); 5869 } 5870 return false; 5871 } 5872 5873 public void moveTaskBackwards(int task) { 5874 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5875 "moveTaskBackwards()"); 5876 5877 synchronized(this) { 5878 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5879 Binder.getCallingUid(), "Task backwards")) { 5880 return; 5881 } 5882 final long origId = Binder.clearCallingIdentity(); 5883 moveTaskBackwardsLocked(task); 5884 Binder.restoreCallingIdentity(origId); 5885 } 5886 } 5887 5888 private final void moveTaskBackwardsLocked(int task) { 5889 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5890 } 5891 5892 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5893 synchronized(this) { 5894 return getTaskForActivityLocked(token, onlyRoot); 5895 } 5896 } 5897 5898 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5899 final int N = mMainStack.mHistory.size(); 5900 TaskRecord lastTask = null; 5901 for (int i=0; i<N; i++) { 5902 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5903 if (r.appToken == token) { 5904 if (!onlyRoot || lastTask != r.task) { 5905 return r.task.taskId; 5906 } 5907 return -1; 5908 } 5909 lastTask = r.task; 5910 } 5911 5912 return -1; 5913 } 5914 5915 // ========================================================= 5916 // THUMBNAILS 5917 // ========================================================= 5918 5919 public void reportThumbnail(IBinder token, 5920 Bitmap thumbnail, CharSequence description) { 5921 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5922 final long origId = Binder.clearCallingIdentity(); 5923 sendPendingThumbnail(null, token, thumbnail, description, true); 5924 Binder.restoreCallingIdentity(origId); 5925 } 5926 5927 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5928 Bitmap thumbnail, CharSequence description, boolean always) { 5929 TaskRecord task = null; 5930 ArrayList receivers = null; 5931 5932 //System.out.println("Send pending thumbnail: " + r); 5933 5934 synchronized(this) { 5935 if (r == null) { 5936 r = mMainStack.isInStackLocked(token); 5937 if (r == null) { 5938 return; 5939 } 5940 } 5941 if (thumbnail == null && r.thumbHolder != null) { 5942 thumbnail = r.thumbHolder.lastThumbnail; 5943 description = r.thumbHolder.lastDescription; 5944 } 5945 if (thumbnail == null && !always) { 5946 // If there is no thumbnail, and this entry is not actually 5947 // going away, then abort for now and pick up the next 5948 // thumbnail we get. 5949 return; 5950 } 5951 task = r.task; 5952 5953 int N = mPendingThumbnails.size(); 5954 int i=0; 5955 while (i<N) { 5956 PendingThumbnailsRecord pr = 5957 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5958 //System.out.println("Looking in " + pr.pendingRecords); 5959 if (pr.pendingRecords.remove(r)) { 5960 if (receivers == null) { 5961 receivers = new ArrayList(); 5962 } 5963 receivers.add(pr); 5964 if (pr.pendingRecords.size() == 0) { 5965 pr.finished = true; 5966 mPendingThumbnails.remove(i); 5967 N--; 5968 continue; 5969 } 5970 } 5971 i++; 5972 } 5973 } 5974 5975 if (receivers != null) { 5976 final int N = receivers.size(); 5977 for (int i=0; i<N; i++) { 5978 try { 5979 PendingThumbnailsRecord pr = 5980 (PendingThumbnailsRecord)receivers.get(i); 5981 pr.receiver.newThumbnail( 5982 task != null ? task.taskId : -1, thumbnail, description); 5983 if (pr.finished) { 5984 pr.receiver.finished(); 5985 } 5986 } catch (Exception e) { 5987 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5988 } 5989 } 5990 } 5991 } 5992 5993 // ========================================================= 5994 // CONTENT PROVIDERS 5995 // ========================================================= 5996 5997 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5998 List<ProviderInfo> providers = null; 5999 try { 6000 providers = AppGlobals.getPackageManager(). 6001 queryContentProviders(app.processName, app.uid, 6002 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6003 } catch (RemoteException ex) { 6004 } 6005 if (DEBUG_MU) 6006 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6007 int userId = app.userId; 6008 if (providers != null) { 6009 int N = providers.size(); 6010 for (int i=0; i<N; i++) { 6011 ProviderInfo cpi = 6012 (ProviderInfo)providers.get(i); 6013 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6014 cpi.name, cpi.flags); 6015 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6016 // This is a singleton provider, but a user besides the 6017 // default user is asking to initialize a process it runs 6018 // in... well, no, it doesn't actually run in this process, 6019 // it runs in the process of the default user. Get rid of it. 6020 providers.remove(i); 6021 N--; 6022 continue; 6023 } 6024 6025 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6026 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6027 if (cpr == null) { 6028 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6029 mProviderMap.putProviderByClass(comp, cpr); 6030 } 6031 if (DEBUG_MU) 6032 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6033 app.pubProviders.put(cpi.name, cpr); 6034 app.addPackage(cpi.applicationInfo.packageName); 6035 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6036 } 6037 } 6038 return providers; 6039 } 6040 6041 /** 6042 * Check if {@link ProcessRecord} has a possible chance at accessing the 6043 * given {@link ProviderInfo}. Final permission checking is always done 6044 * in {@link ContentProvider}. 6045 */ 6046 private final String checkContentProviderPermissionLocked( 6047 ProviderInfo cpi, ProcessRecord r) { 6048 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6049 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6050 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6051 cpi.applicationInfo.uid, cpi.exported) 6052 == PackageManager.PERMISSION_GRANTED) { 6053 return null; 6054 } 6055 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6056 cpi.applicationInfo.uid, cpi.exported) 6057 == PackageManager.PERMISSION_GRANTED) { 6058 return null; 6059 } 6060 6061 PathPermission[] pps = cpi.pathPermissions; 6062 if (pps != null) { 6063 int i = pps.length; 6064 while (i > 0) { 6065 i--; 6066 PathPermission pp = pps[i]; 6067 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6068 cpi.applicationInfo.uid, cpi.exported) 6069 == PackageManager.PERMISSION_GRANTED) { 6070 return null; 6071 } 6072 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6073 cpi.applicationInfo.uid, cpi.exported) 6074 == PackageManager.PERMISSION_GRANTED) { 6075 return null; 6076 } 6077 } 6078 } 6079 6080 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6081 if (perms != null) { 6082 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6083 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6084 return null; 6085 } 6086 } 6087 } 6088 6089 String msg; 6090 if (!cpi.exported) { 6091 msg = "Permission Denial: opening provider " + cpi.name 6092 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6093 + ", uid=" + callingUid + ") that is not exported from uid " 6094 + cpi.applicationInfo.uid; 6095 } else { 6096 msg = "Permission Denial: opening provider " + cpi.name 6097 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6098 + ", uid=" + callingUid + ") requires " 6099 + cpi.readPermission + " or " + cpi.writePermission; 6100 } 6101 Slog.w(TAG, msg); 6102 return msg; 6103 } 6104 6105 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6106 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6107 if (r != null) { 6108 for (int i=0; i<r.conProviders.size(); i++) { 6109 ContentProviderConnection conn = r.conProviders.get(i); 6110 if (conn.provider == cpr) { 6111 if (DEBUG_PROVIDER) Slog.v(TAG, 6112 "Adding provider requested by " 6113 + r.processName + " from process " 6114 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6115 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6116 if (stable) { 6117 conn.stableCount++; 6118 conn.numStableIncs++; 6119 } else { 6120 conn.unstableCount++; 6121 conn.numUnstableIncs++; 6122 } 6123 return conn; 6124 } 6125 } 6126 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6127 if (stable) { 6128 conn.stableCount = 1; 6129 conn.numStableIncs = 1; 6130 } else { 6131 conn.unstableCount = 1; 6132 conn.numUnstableIncs = 1; 6133 } 6134 cpr.connections.add(conn); 6135 r.conProviders.add(conn); 6136 return conn; 6137 } 6138 cpr.addExternalProcessHandleLocked(externalProcessToken); 6139 return null; 6140 } 6141 6142 boolean decProviderCountLocked(ContentProviderConnection conn, 6143 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6144 if (conn != null) { 6145 cpr = conn.provider; 6146 if (DEBUG_PROVIDER) Slog.v(TAG, 6147 "Removing provider requested by " 6148 + conn.client.processName + " from process " 6149 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6150 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6151 if (stable) { 6152 conn.stableCount--; 6153 } else { 6154 conn.unstableCount--; 6155 } 6156 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6157 cpr.connections.remove(conn); 6158 conn.client.conProviders.remove(conn); 6159 return true; 6160 } 6161 return false; 6162 } 6163 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6164 return false; 6165 } 6166 6167 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6168 String name, IBinder token, boolean stable) { 6169 ContentProviderRecord cpr; 6170 ContentProviderConnection conn = null; 6171 ProviderInfo cpi = null; 6172 6173 synchronized(this) { 6174 ProcessRecord r = null; 6175 if (caller != null) { 6176 r = getRecordForAppLocked(caller); 6177 if (r == null) { 6178 throw new SecurityException( 6179 "Unable to find app for caller " + caller 6180 + " (pid=" + Binder.getCallingPid() 6181 + ") when getting content provider " + name); 6182 } 6183 } 6184 6185 // First check if this content provider has been published... 6186 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6187 cpr = mProviderMap.getProviderByName(name, userId); 6188 boolean providerRunning = cpr != null; 6189 if (providerRunning) { 6190 cpi = cpr.info; 6191 String msg; 6192 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6193 throw new SecurityException(msg); 6194 } 6195 6196 if (r != null && cpr.canRunHere(r)) { 6197 // This provider has been published or is in the process 6198 // of being published... but it is also allowed to run 6199 // in the caller's process, so don't make a connection 6200 // and just let the caller instantiate its own instance. 6201 ContentProviderHolder holder = cpr.newHolder(null); 6202 // don't give caller the provider object, it needs 6203 // to make its own. 6204 holder.provider = null; 6205 return holder; 6206 } 6207 6208 final long origId = Binder.clearCallingIdentity(); 6209 6210 // In this case the provider instance already exists, so we can 6211 // return it right away. 6212 conn = incProviderCountLocked(r, cpr, token, stable); 6213 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6214 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6215 // If this is a perceptible app accessing the provider, 6216 // make sure to count it as being accessed and thus 6217 // back up on the LRU list. This is good because 6218 // content providers are often expensive to start. 6219 updateLruProcessLocked(cpr.proc, false, true); 6220 } 6221 } 6222 6223 if (cpr.proc != null) { 6224 if (false) { 6225 if (cpr.name.flattenToShortString().equals( 6226 "com.android.providers.calendar/.CalendarProvider2")) { 6227 Slog.v(TAG, "****************** KILLING " 6228 + cpr.name.flattenToShortString()); 6229 Process.killProcess(cpr.proc.pid); 6230 } 6231 } 6232 boolean success = updateOomAdjLocked(cpr.proc); 6233 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6234 // NOTE: there is still a race here where a signal could be 6235 // pending on the process even though we managed to update its 6236 // adj level. Not sure what to do about this, but at least 6237 // the race is now smaller. 6238 if (!success) { 6239 // Uh oh... it looks like the provider's process 6240 // has been killed on us. We need to wait for a new 6241 // process to be started, and make sure its death 6242 // doesn't kill our process. 6243 Slog.i(TAG, 6244 "Existing provider " + cpr.name.flattenToShortString() 6245 + " is crashing; detaching " + r); 6246 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6247 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6248 if (!lastRef) { 6249 // This wasn't the last ref our process had on 6250 // the provider... we have now been killed, bail. 6251 return null; 6252 } 6253 providerRunning = false; 6254 conn = null; 6255 } 6256 } 6257 6258 Binder.restoreCallingIdentity(origId); 6259 } 6260 6261 boolean singleton; 6262 if (!providerRunning) { 6263 try { 6264 cpi = AppGlobals.getPackageManager(). 6265 resolveContentProvider(name, 6266 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6267 } catch (RemoteException ex) { 6268 } 6269 if (cpi == null) { 6270 return null; 6271 } 6272 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6273 cpi.name, cpi.flags); 6274 if (singleton) { 6275 userId = 0; 6276 } 6277 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6278 6279 String msg; 6280 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6281 throw new SecurityException(msg); 6282 } 6283 6284 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6285 && !cpi.processName.equals("system")) { 6286 // If this content provider does not run in the system 6287 // process, and the system is not yet ready to run other 6288 // processes, then fail fast instead of hanging. 6289 throw new IllegalArgumentException( 6290 "Attempt to launch content provider before system ready"); 6291 } 6292 6293 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6294 cpr = mProviderMap.getProviderByClass(comp, userId); 6295 final boolean firstClass = cpr == null; 6296 if (firstClass) { 6297 try { 6298 ApplicationInfo ai = 6299 AppGlobals.getPackageManager(). 6300 getApplicationInfo( 6301 cpi.applicationInfo.packageName, 6302 STOCK_PM_FLAGS, userId); 6303 if (ai == null) { 6304 Slog.w(TAG, "No package info for content provider " 6305 + cpi.name); 6306 return null; 6307 } 6308 ai = getAppInfoForUser(ai, userId); 6309 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6310 } catch (RemoteException ex) { 6311 // pm is in same process, this will never happen. 6312 } 6313 } 6314 6315 if (r != null && cpr.canRunHere(r)) { 6316 // If this is a multiprocess provider, then just return its 6317 // info and allow the caller to instantiate it. Only do 6318 // this if the provider is the same user as the caller's 6319 // process, or can run as root (so can be in any process). 6320 return cpr.newHolder(null); 6321 } 6322 6323 if (DEBUG_PROVIDER) { 6324 RuntimeException e = new RuntimeException("here"); 6325 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6326 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6327 } 6328 6329 // This is single process, and our app is now connecting to it. 6330 // See if we are already in the process of launching this 6331 // provider. 6332 final int N = mLaunchingProviders.size(); 6333 int i; 6334 for (i=0; i<N; i++) { 6335 if (mLaunchingProviders.get(i) == cpr) { 6336 break; 6337 } 6338 } 6339 6340 // If the provider is not already being launched, then get it 6341 // started. 6342 if (i >= N) { 6343 final long origId = Binder.clearCallingIdentity(); 6344 6345 try { 6346 // Content provider is now in use, its package can't be stopped. 6347 try { 6348 AppGlobals.getPackageManager().setPackageStoppedState( 6349 cpr.appInfo.packageName, false, userId); 6350 } catch (RemoteException e) { 6351 } catch (IllegalArgumentException e) { 6352 Slog.w(TAG, "Failed trying to unstop package " 6353 + cpr.appInfo.packageName + ": " + e); 6354 } 6355 6356 ProcessRecord proc = startProcessLocked(cpi.processName, 6357 cpr.appInfo, false, 0, "content provider", 6358 new ComponentName(cpi.applicationInfo.packageName, 6359 cpi.name), false, false); 6360 if (proc == null) { 6361 Slog.w(TAG, "Unable to launch app " 6362 + cpi.applicationInfo.packageName + "/" 6363 + cpi.applicationInfo.uid + " for provider " 6364 + name + ": process is bad"); 6365 return null; 6366 } 6367 cpr.launchingApp = proc; 6368 mLaunchingProviders.add(cpr); 6369 } finally { 6370 Binder.restoreCallingIdentity(origId); 6371 } 6372 } 6373 6374 // Make sure the provider is published (the same provider class 6375 // may be published under multiple names). 6376 if (firstClass) { 6377 mProviderMap.putProviderByClass(comp, cpr); 6378 } 6379 6380 mProviderMap.putProviderByName(name, cpr); 6381 conn = incProviderCountLocked(r, cpr, token, stable); 6382 if (conn != null) { 6383 conn.waiting = true; 6384 } 6385 } 6386 } 6387 6388 // Wait for the provider to be published... 6389 synchronized (cpr) { 6390 while (cpr.provider == null) { 6391 if (cpr.launchingApp == null) { 6392 Slog.w(TAG, "Unable to launch app " 6393 + cpi.applicationInfo.packageName + "/" 6394 + cpi.applicationInfo.uid + " for provider " 6395 + name + ": launching app became null"); 6396 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6397 cpi.applicationInfo.packageName, 6398 cpi.applicationInfo.uid, name); 6399 return null; 6400 } 6401 try { 6402 if (DEBUG_MU) { 6403 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6404 + cpr.launchingApp); 6405 } 6406 if (conn != null) { 6407 conn.waiting = true; 6408 } 6409 cpr.wait(); 6410 } catch (InterruptedException ex) { 6411 } finally { 6412 if (conn != null) { 6413 conn.waiting = false; 6414 } 6415 } 6416 } 6417 } 6418 return cpr != null ? cpr.newHolder(conn) : null; 6419 } 6420 6421 public final ContentProviderHolder getContentProvider( 6422 IApplicationThread caller, String name, boolean stable) { 6423 enforceNotIsolatedCaller("getContentProvider"); 6424 if (caller == null) { 6425 String msg = "null IApplicationThread when getting content provider " 6426 + name; 6427 Slog.w(TAG, msg); 6428 throw new SecurityException(msg); 6429 } 6430 6431 return getContentProviderImpl(caller, name, null, stable); 6432 } 6433 6434 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6435 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6436 "Do not have permission in call getContentProviderExternal()"); 6437 return getContentProviderExternalUnchecked(name, token); 6438 } 6439 6440 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6441 return getContentProviderImpl(null, name, token, true); 6442 } 6443 6444 /** 6445 * Drop a content provider from a ProcessRecord's bookkeeping 6446 * @param cpr 6447 */ 6448 public void removeContentProvider(IBinder connection, boolean stable) { 6449 enforceNotIsolatedCaller("removeContentProvider"); 6450 synchronized (this) { 6451 ContentProviderConnection conn; 6452 try { 6453 conn = (ContentProviderConnection)connection; 6454 } catch (ClassCastException e) { 6455 String msg ="removeContentProvider: " + connection 6456 + " not a ContentProviderConnection"; 6457 Slog.w(TAG, msg); 6458 throw new IllegalArgumentException(msg); 6459 } 6460 if (conn == null) { 6461 throw new NullPointerException("connection is null"); 6462 } 6463 if (decProviderCountLocked(conn, null, null, stable)) { 6464 updateOomAdjLocked(); 6465 } 6466 } 6467 } 6468 6469 public void removeContentProviderExternal(String name, IBinder token) { 6470 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6471 "Do not have permission in call removeContentProviderExternal()"); 6472 removeContentProviderExternalUnchecked(name, token); 6473 } 6474 6475 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6476 synchronized (this) { 6477 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6478 Binder.getOrigCallingUser()); 6479 if(cpr == null) { 6480 //remove from mProvidersByClass 6481 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6482 return; 6483 } 6484 6485 //update content provider record entry info 6486 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6487 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6488 Binder.getOrigCallingUser()); 6489 if (localCpr.hasExternalProcessHandles()) { 6490 if (localCpr.removeExternalProcessHandleLocked(token)) { 6491 updateOomAdjLocked(); 6492 } else { 6493 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6494 + " with no external reference for token: " 6495 + token + "."); 6496 } 6497 } else { 6498 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6499 + " with no external references."); 6500 } 6501 } 6502 } 6503 6504 public final void publishContentProviders(IApplicationThread caller, 6505 List<ContentProviderHolder> providers) { 6506 if (providers == null) { 6507 return; 6508 } 6509 6510 enforceNotIsolatedCaller("publishContentProviders"); 6511 synchronized (this) { 6512 final ProcessRecord r = getRecordForAppLocked(caller); 6513 if (DEBUG_MU) 6514 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6515 if (r == null) { 6516 throw new SecurityException( 6517 "Unable to find app for caller " + caller 6518 + " (pid=" + Binder.getCallingPid() 6519 + ") when publishing content providers"); 6520 } 6521 6522 final long origId = Binder.clearCallingIdentity(); 6523 6524 final int N = providers.size(); 6525 for (int i=0; i<N; i++) { 6526 ContentProviderHolder src = providers.get(i); 6527 if (src == null || src.info == null || src.provider == null) { 6528 continue; 6529 } 6530 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6531 if (DEBUG_MU) 6532 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6533 if (dst != null) { 6534 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6535 mProviderMap.putProviderByClass(comp, dst); 6536 String names[] = dst.info.authority.split(";"); 6537 for (int j = 0; j < names.length; j++) { 6538 mProviderMap.putProviderByName(names[j], dst); 6539 } 6540 6541 int NL = mLaunchingProviders.size(); 6542 int j; 6543 for (j=0; j<NL; j++) { 6544 if (mLaunchingProviders.get(j) == dst) { 6545 mLaunchingProviders.remove(j); 6546 j--; 6547 NL--; 6548 } 6549 } 6550 synchronized (dst) { 6551 dst.provider = src.provider; 6552 dst.proc = r; 6553 dst.notifyAll(); 6554 } 6555 updateOomAdjLocked(r); 6556 } 6557 } 6558 6559 Binder.restoreCallingIdentity(origId); 6560 } 6561 } 6562 6563 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6564 ContentProviderConnection conn; 6565 try { 6566 conn = (ContentProviderConnection)connection; 6567 } catch (ClassCastException e) { 6568 String msg ="refContentProvider: " + connection 6569 + " not a ContentProviderConnection"; 6570 Slog.w(TAG, msg); 6571 throw new IllegalArgumentException(msg); 6572 } 6573 if (conn == null) { 6574 throw new NullPointerException("connection is null"); 6575 } 6576 6577 synchronized (this) { 6578 if (stable > 0) { 6579 conn.numStableIncs += stable; 6580 } 6581 stable = conn.stableCount + stable; 6582 if (stable < 0) { 6583 throw new IllegalStateException("stableCount < 0: " + stable); 6584 } 6585 6586 if (unstable > 0) { 6587 conn.numUnstableIncs += unstable; 6588 } 6589 unstable = conn.unstableCount + unstable; 6590 if (unstable < 0) { 6591 throw new IllegalStateException("unstableCount < 0: " + unstable); 6592 } 6593 6594 if ((stable+unstable) <= 0) { 6595 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6596 + stable + " unstable=" + unstable); 6597 } 6598 conn.stableCount = stable; 6599 conn.unstableCount = unstable; 6600 return !conn.dead; 6601 } 6602 } 6603 6604 public void unstableProviderDied(IBinder connection) { 6605 ContentProviderConnection conn; 6606 try { 6607 conn = (ContentProviderConnection)connection; 6608 } catch (ClassCastException e) { 6609 String msg ="refContentProvider: " + connection 6610 + " not a ContentProviderConnection"; 6611 Slog.w(TAG, msg); 6612 throw new IllegalArgumentException(msg); 6613 } 6614 if (conn == null) { 6615 throw new NullPointerException("connection is null"); 6616 } 6617 6618 // Safely retrieve the content provider associated with the connection. 6619 IContentProvider provider; 6620 synchronized (this) { 6621 provider = conn.provider.provider; 6622 } 6623 6624 if (provider == null) { 6625 // Um, yeah, we're way ahead of you. 6626 return; 6627 } 6628 6629 // Make sure the caller is being honest with us. 6630 if (provider.asBinder().pingBinder()) { 6631 // Er, no, still looks good to us. 6632 synchronized (this) { 6633 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6634 + " says " + conn + " died, but we don't agree"); 6635 return; 6636 } 6637 } 6638 6639 // Well look at that! It's dead! 6640 synchronized (this) { 6641 if (conn.provider.provider != provider) { 6642 // But something changed... good enough. 6643 return; 6644 } 6645 6646 ProcessRecord proc = conn.provider.proc; 6647 if (proc == null || proc.thread == null) { 6648 // Seems like the process is already cleaned up. 6649 return; 6650 } 6651 6652 // As far as we're concerned, this is just like receiving a 6653 // death notification... just a bit prematurely. 6654 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6655 + ") early provider death"); 6656 final long ident = Binder.clearCallingIdentity(); 6657 try { 6658 appDiedLocked(proc, proc.pid, proc.thread); 6659 } finally { 6660 Binder.restoreCallingIdentity(ident); 6661 } 6662 } 6663 } 6664 6665 public static final void installSystemProviders() { 6666 List<ProviderInfo> providers; 6667 synchronized (mSelf) { 6668 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6669 providers = mSelf.generateApplicationProvidersLocked(app); 6670 if (providers != null) { 6671 for (int i=providers.size()-1; i>=0; i--) { 6672 ProviderInfo pi = (ProviderInfo)providers.get(i); 6673 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6674 Slog.w(TAG, "Not installing system proc provider " + pi.name 6675 + ": not system .apk"); 6676 providers.remove(i); 6677 } 6678 } 6679 } 6680 } 6681 if (providers != null) { 6682 mSystemThread.installSystemProviders(providers); 6683 } 6684 6685 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6686 6687 mSelf.mUsageStatsService.monitorPackages(); 6688 } 6689 6690 /** 6691 * Allows app to retrieve the MIME type of a URI without having permission 6692 * to access its content provider. 6693 * 6694 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6695 * 6696 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6697 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6698 */ 6699 public String getProviderMimeType(Uri uri) { 6700 enforceNotIsolatedCaller("getProviderMimeType"); 6701 final String name = uri.getAuthority(); 6702 final long ident = Binder.clearCallingIdentity(); 6703 ContentProviderHolder holder = null; 6704 6705 try { 6706 holder = getContentProviderExternalUnchecked(name, null); 6707 if (holder != null) { 6708 return holder.provider.getType(uri); 6709 } 6710 } catch (RemoteException e) { 6711 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6712 return null; 6713 } finally { 6714 if (holder != null) { 6715 removeContentProviderExternalUnchecked(name, null); 6716 } 6717 Binder.restoreCallingIdentity(ident); 6718 } 6719 6720 return null; 6721 } 6722 6723 // ========================================================= 6724 // GLOBAL MANAGEMENT 6725 // ========================================================= 6726 6727 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6728 ApplicationInfo info, String customProcess, boolean isolated) { 6729 String proc = customProcess != null ? customProcess : info.processName; 6730 BatteryStatsImpl.Uid.Proc ps = null; 6731 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6732 int uid = info.uid; 6733 if (isolated) { 6734 int userId = UserHandle.getUserId(uid); 6735 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6736 uid = 0; 6737 while (true) { 6738 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6739 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6740 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6741 } 6742 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6743 mNextIsolatedProcessUid++; 6744 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6745 // No process for this uid, use it. 6746 break; 6747 } 6748 stepsLeft--; 6749 if (stepsLeft <= 0) { 6750 return null; 6751 } 6752 } 6753 } 6754 synchronized (stats) { 6755 ps = stats.getProcessStatsLocked(info.uid, proc); 6756 } 6757 return new ProcessRecord(ps, thread, info, proc, uid); 6758 } 6759 6760 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6761 ProcessRecord app; 6762 if (!isolated) { 6763 app = getProcessRecordLocked(info.processName, info.uid); 6764 } else { 6765 app = null; 6766 } 6767 6768 if (app == null) { 6769 app = newProcessRecordLocked(null, info, null, isolated); 6770 mProcessNames.put(info.processName, app.uid, app); 6771 if (isolated) { 6772 mIsolatedProcesses.put(app.uid, app); 6773 } 6774 updateLruProcessLocked(app, true, true); 6775 } 6776 6777 // This package really, really can not be stopped. 6778 try { 6779 AppGlobals.getPackageManager().setPackageStoppedState( 6780 info.packageName, false, UserHandle.getUserId(app.uid)); 6781 } catch (RemoteException e) { 6782 } catch (IllegalArgumentException e) { 6783 Slog.w(TAG, "Failed trying to unstop package " 6784 + info.packageName + ": " + e); 6785 } 6786 6787 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6788 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6789 app.persistent = true; 6790 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6791 } 6792 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6793 mPersistentStartingProcesses.add(app); 6794 startProcessLocked(app, "added application", app.processName); 6795 } 6796 6797 return app; 6798 } 6799 6800 public void unhandledBack() { 6801 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6802 "unhandledBack()"); 6803 6804 synchronized(this) { 6805 int count = mMainStack.mHistory.size(); 6806 if (DEBUG_SWITCH) Slog.d( 6807 TAG, "Performing unhandledBack(): stack size = " + count); 6808 if (count > 1) { 6809 final long origId = Binder.clearCallingIdentity(); 6810 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6811 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6812 Binder.restoreCallingIdentity(origId); 6813 } 6814 } 6815 } 6816 6817 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6818 enforceNotIsolatedCaller("openContentUri"); 6819 String name = uri.getAuthority(); 6820 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6821 ParcelFileDescriptor pfd = null; 6822 if (cph != null) { 6823 // We record the binder invoker's uid in thread-local storage before 6824 // going to the content provider to open the file. Later, in the code 6825 // that handles all permissions checks, we look for this uid and use 6826 // that rather than the Activity Manager's own uid. The effect is that 6827 // we do the check against the caller's permissions even though it looks 6828 // to the content provider like the Activity Manager itself is making 6829 // the request. 6830 sCallerIdentity.set(new Identity( 6831 Binder.getCallingPid(), Binder.getCallingUid())); 6832 try { 6833 pfd = cph.provider.openFile(uri, "r"); 6834 } catch (FileNotFoundException e) { 6835 // do nothing; pfd will be returned null 6836 } finally { 6837 // Ensure that whatever happens, we clean up the identity state 6838 sCallerIdentity.remove(); 6839 } 6840 6841 // We've got the fd now, so we're done with the provider. 6842 removeContentProviderExternalUnchecked(name, null); 6843 } else { 6844 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6845 } 6846 return pfd; 6847 } 6848 6849 // Actually is sleeping or shutting down or whatever else in the future 6850 // is an inactive state. 6851 public boolean isSleeping() { 6852 return mSleeping || mShuttingDown; 6853 } 6854 6855 public void goingToSleep() { 6856 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6857 != PackageManager.PERMISSION_GRANTED) { 6858 throw new SecurityException("Requires permission " 6859 + android.Manifest.permission.DEVICE_POWER); 6860 } 6861 6862 synchronized(this) { 6863 mWentToSleep = true; 6864 updateEventDispatchingLocked(); 6865 6866 if (!mSleeping) { 6867 mSleeping = true; 6868 mMainStack.stopIfSleepingLocked(); 6869 6870 // Initialize the wake times of all processes. 6871 checkExcessivePowerUsageLocked(false); 6872 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6873 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6874 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6875 } 6876 } 6877 } 6878 6879 public boolean shutdown(int timeout) { 6880 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6881 != PackageManager.PERMISSION_GRANTED) { 6882 throw new SecurityException("Requires permission " 6883 + android.Manifest.permission.SHUTDOWN); 6884 } 6885 6886 boolean timedout = false; 6887 6888 synchronized(this) { 6889 mShuttingDown = true; 6890 updateEventDispatchingLocked(); 6891 6892 if (mMainStack.mResumedActivity != null) { 6893 mMainStack.stopIfSleepingLocked(); 6894 final long endTime = System.currentTimeMillis() + timeout; 6895 while (mMainStack.mResumedActivity != null 6896 || mMainStack.mPausingActivity != null) { 6897 long delay = endTime - System.currentTimeMillis(); 6898 if (delay <= 0) { 6899 Slog.w(TAG, "Activity manager shutdown timed out"); 6900 timedout = true; 6901 break; 6902 } 6903 try { 6904 this.wait(); 6905 } catch (InterruptedException e) { 6906 } 6907 } 6908 } 6909 } 6910 6911 mUsageStatsService.shutdown(); 6912 mBatteryStatsService.shutdown(); 6913 6914 return timedout; 6915 } 6916 6917 public final void activitySlept(IBinder token) { 6918 if (localLOGV) Slog.v( 6919 TAG, "Activity slept: token=" + token); 6920 6921 ActivityRecord r = null; 6922 6923 final long origId = Binder.clearCallingIdentity(); 6924 6925 synchronized (this) { 6926 r = mMainStack.isInStackLocked(token); 6927 if (r != null) { 6928 mMainStack.activitySleptLocked(r); 6929 } 6930 } 6931 6932 Binder.restoreCallingIdentity(origId); 6933 } 6934 6935 private void comeOutOfSleepIfNeededLocked() { 6936 if (!mWentToSleep && !mLockScreenShown) { 6937 if (mSleeping) { 6938 mSleeping = false; 6939 mMainStack.awakeFromSleepingLocked(); 6940 mMainStack.resumeTopActivityLocked(null); 6941 } 6942 } 6943 } 6944 6945 public void wakingUp() { 6946 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6947 != PackageManager.PERMISSION_GRANTED) { 6948 throw new SecurityException("Requires permission " 6949 + android.Manifest.permission.DEVICE_POWER); 6950 } 6951 6952 synchronized(this) { 6953 mWentToSleep = false; 6954 updateEventDispatchingLocked(); 6955 comeOutOfSleepIfNeededLocked(); 6956 } 6957 } 6958 6959 private void updateEventDispatchingLocked() { 6960 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6961 } 6962 6963 public void setLockScreenShown(boolean shown) { 6964 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6965 != PackageManager.PERMISSION_GRANTED) { 6966 throw new SecurityException("Requires permission " 6967 + android.Manifest.permission.DEVICE_POWER); 6968 } 6969 6970 synchronized(this) { 6971 mLockScreenShown = shown; 6972 comeOutOfSleepIfNeededLocked(); 6973 } 6974 } 6975 6976 public void stopAppSwitches() { 6977 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6978 != PackageManager.PERMISSION_GRANTED) { 6979 throw new SecurityException("Requires permission " 6980 + android.Manifest.permission.STOP_APP_SWITCHES); 6981 } 6982 6983 synchronized(this) { 6984 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6985 + APP_SWITCH_DELAY_TIME; 6986 mDidAppSwitch = false; 6987 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6988 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6989 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6990 } 6991 } 6992 6993 public void resumeAppSwitches() { 6994 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6995 != PackageManager.PERMISSION_GRANTED) { 6996 throw new SecurityException("Requires permission " 6997 + android.Manifest.permission.STOP_APP_SWITCHES); 6998 } 6999 7000 synchronized(this) { 7001 // Note that we don't execute any pending app switches... we will 7002 // let those wait until either the timeout, or the next start 7003 // activity request. 7004 mAppSwitchesAllowedTime = 0; 7005 } 7006 } 7007 7008 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7009 String name) { 7010 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7011 return true; 7012 } 7013 7014 final int perm = checkComponentPermission( 7015 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7016 callingUid, -1, true); 7017 if (perm == PackageManager.PERMISSION_GRANTED) { 7018 return true; 7019 } 7020 7021 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7022 return false; 7023 } 7024 7025 public void setDebugApp(String packageName, boolean waitForDebugger, 7026 boolean persistent) { 7027 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7028 "setDebugApp()"); 7029 7030 // Note that this is not really thread safe if there are multiple 7031 // callers into it at the same time, but that's not a situation we 7032 // care about. 7033 if (persistent) { 7034 final ContentResolver resolver = mContext.getContentResolver(); 7035 Settings.System.putString( 7036 resolver, Settings.System.DEBUG_APP, 7037 packageName); 7038 Settings.System.putInt( 7039 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7040 waitForDebugger ? 1 : 0); 7041 } 7042 7043 synchronized (this) { 7044 if (!persistent) { 7045 mOrigDebugApp = mDebugApp; 7046 mOrigWaitForDebugger = mWaitForDebugger; 7047 } 7048 mDebugApp = packageName; 7049 mWaitForDebugger = waitForDebugger; 7050 mDebugTransient = !persistent; 7051 if (packageName != null) { 7052 final long origId = Binder.clearCallingIdentity(); 7053 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7054 Binder.restoreCallingIdentity(origId); 7055 } 7056 } 7057 } 7058 7059 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7060 synchronized (this) { 7061 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7062 if (!isDebuggable) { 7063 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7064 throw new SecurityException("Process not debuggable: " + app.packageName); 7065 } 7066 } 7067 7068 mOpenGlTraceApp = processName; 7069 } 7070 } 7071 7072 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7073 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7074 synchronized (this) { 7075 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7076 if (!isDebuggable) { 7077 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7078 throw new SecurityException("Process not debuggable: " + app.packageName); 7079 } 7080 } 7081 mProfileApp = processName; 7082 mProfileFile = profileFile; 7083 if (mProfileFd != null) { 7084 try { 7085 mProfileFd.close(); 7086 } catch (IOException e) { 7087 } 7088 mProfileFd = null; 7089 } 7090 mProfileFd = profileFd; 7091 mProfileType = 0; 7092 mAutoStopProfiler = autoStopProfiler; 7093 } 7094 } 7095 7096 public void setAlwaysFinish(boolean enabled) { 7097 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7098 "setAlwaysFinish()"); 7099 7100 Settings.System.putInt( 7101 mContext.getContentResolver(), 7102 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7103 7104 synchronized (this) { 7105 mAlwaysFinishActivities = enabled; 7106 } 7107 } 7108 7109 public void setActivityController(IActivityController controller) { 7110 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7111 "setActivityController()"); 7112 synchronized (this) { 7113 mController = controller; 7114 } 7115 } 7116 7117 public boolean isUserAMonkey() { 7118 // For now the fact that there is a controller implies 7119 // we have a monkey. 7120 synchronized (this) { 7121 return mController != null; 7122 } 7123 } 7124 7125 public void registerProcessObserver(IProcessObserver observer) { 7126 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7127 "registerProcessObserver()"); 7128 synchronized (this) { 7129 mProcessObservers.register(observer); 7130 } 7131 } 7132 7133 public void unregisterProcessObserver(IProcessObserver observer) { 7134 synchronized (this) { 7135 mProcessObservers.unregister(observer); 7136 } 7137 } 7138 7139 public void setImmersive(IBinder token, boolean immersive) { 7140 synchronized(this) { 7141 ActivityRecord r = mMainStack.isInStackLocked(token); 7142 if (r == null) { 7143 throw new IllegalArgumentException(); 7144 } 7145 r.immersive = immersive; 7146 } 7147 } 7148 7149 public boolean isImmersive(IBinder token) { 7150 synchronized (this) { 7151 ActivityRecord r = mMainStack.isInStackLocked(token); 7152 if (r == null) { 7153 throw new IllegalArgumentException(); 7154 } 7155 return r.immersive; 7156 } 7157 } 7158 7159 public boolean isTopActivityImmersive() { 7160 enforceNotIsolatedCaller("startActivity"); 7161 synchronized (this) { 7162 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7163 return (r != null) ? r.immersive : false; 7164 } 7165 } 7166 7167 public final void enterSafeMode() { 7168 synchronized(this) { 7169 // It only makes sense to do this before the system is ready 7170 // and started launching other packages. 7171 if (!mSystemReady) { 7172 try { 7173 AppGlobals.getPackageManager().enterSafeMode(); 7174 } catch (RemoteException e) { 7175 } 7176 } 7177 } 7178 } 7179 7180 public final void showSafeModeOverlay() { 7181 View v = LayoutInflater.from(mContext).inflate( 7182 com.android.internal.R.layout.safe_mode, null); 7183 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7184 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7185 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7186 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7187 lp.gravity = Gravity.BOTTOM | Gravity.START; 7188 lp.format = v.getBackground().getOpacity(); 7189 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7190 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7191 ((WindowManager)mContext.getSystemService( 7192 Context.WINDOW_SERVICE)).addView(v, lp); 7193 } 7194 7195 public void noteWakeupAlarm(IIntentSender sender) { 7196 if (!(sender instanceof PendingIntentRecord)) { 7197 return; 7198 } 7199 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7200 synchronized (stats) { 7201 if (mBatteryStatsService.isOnBattery()) { 7202 mBatteryStatsService.enforceCallingPermission(); 7203 PendingIntentRecord rec = (PendingIntentRecord)sender; 7204 int MY_UID = Binder.getCallingUid(); 7205 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7206 BatteryStatsImpl.Uid.Pkg pkg = 7207 stats.getPackageStatsLocked(uid, rec.key.packageName); 7208 pkg.incWakeupsLocked(); 7209 } 7210 } 7211 } 7212 7213 public boolean killPids(int[] pids, String pReason, boolean secure) { 7214 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7215 throw new SecurityException("killPids only available to the system"); 7216 } 7217 String reason = (pReason == null) ? "Unknown" : pReason; 7218 // XXX Note: don't acquire main activity lock here, because the window 7219 // manager calls in with its locks held. 7220 7221 boolean killed = false; 7222 synchronized (mPidsSelfLocked) { 7223 int[] types = new int[pids.length]; 7224 int worstType = 0; 7225 for (int i=0; i<pids.length; i++) { 7226 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7227 if (proc != null) { 7228 int type = proc.setAdj; 7229 types[i] = type; 7230 if (type > worstType) { 7231 worstType = type; 7232 } 7233 } 7234 } 7235 7236 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7237 // then constrain it so we will kill all hidden procs. 7238 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7239 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7240 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7241 } 7242 7243 // If this is not a secure call, don't let it kill processes that 7244 // are important. 7245 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7246 worstType = ProcessList.SERVICE_ADJ; 7247 } 7248 7249 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7250 for (int i=0; i<pids.length; i++) { 7251 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7252 if (proc == null) { 7253 continue; 7254 } 7255 int adj = proc.setAdj; 7256 if (adj >= worstType && !proc.killedBackground) { 7257 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7258 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7259 proc.processName, adj, reason); 7260 killed = true; 7261 proc.killedBackground = true; 7262 Process.killProcessQuiet(pids[i]); 7263 } 7264 } 7265 } 7266 return killed; 7267 } 7268 7269 @Override 7270 public boolean killProcessesBelowForeground(String reason) { 7271 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7272 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7273 } 7274 7275 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7276 } 7277 7278 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7279 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7280 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7281 } 7282 7283 boolean killed = false; 7284 synchronized (mPidsSelfLocked) { 7285 final int size = mPidsSelfLocked.size(); 7286 for (int i = 0; i < size; i++) { 7287 final int pid = mPidsSelfLocked.keyAt(i); 7288 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7289 if (proc == null) continue; 7290 7291 final int adj = proc.setAdj; 7292 if (adj > belowAdj && !proc.killedBackground) { 7293 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7294 EventLog.writeEvent( 7295 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7296 killed = true; 7297 proc.killedBackground = true; 7298 Process.killProcessQuiet(pid); 7299 } 7300 } 7301 } 7302 return killed; 7303 } 7304 7305 public final void startRunning(String pkg, String cls, String action, 7306 String data) { 7307 synchronized(this) { 7308 if (mStartRunning) { 7309 return; 7310 } 7311 mStartRunning = true; 7312 mTopComponent = pkg != null && cls != null 7313 ? new ComponentName(pkg, cls) : null; 7314 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7315 mTopData = data; 7316 if (!mSystemReady) { 7317 return; 7318 } 7319 } 7320 7321 systemReady(null); 7322 } 7323 7324 private void retrieveSettings() { 7325 final ContentResolver resolver = mContext.getContentResolver(); 7326 String debugApp = Settings.System.getString( 7327 resolver, Settings.System.DEBUG_APP); 7328 boolean waitForDebugger = Settings.System.getInt( 7329 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7330 boolean alwaysFinishActivities = Settings.System.getInt( 7331 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7332 7333 Configuration configuration = new Configuration(); 7334 Settings.System.getConfiguration(resolver, configuration); 7335 7336 synchronized (this) { 7337 mDebugApp = mOrigDebugApp = debugApp; 7338 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7339 mAlwaysFinishActivities = alwaysFinishActivities; 7340 // This happens before any activities are started, so we can 7341 // change mConfiguration in-place. 7342 updateConfigurationLocked(configuration, null, false, true); 7343 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7344 } 7345 } 7346 7347 public boolean testIsSystemReady() { 7348 // no need to synchronize(this) just to read & return the value 7349 return mSystemReady; 7350 } 7351 7352 private static File getCalledPreBootReceiversFile() { 7353 File dataDir = Environment.getDataDirectory(); 7354 File systemDir = new File(dataDir, "system"); 7355 File fname = new File(systemDir, "called_pre_boots.dat"); 7356 return fname; 7357 } 7358 7359 static final int LAST_DONE_VERSION = 10000; 7360 7361 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7362 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7363 File file = getCalledPreBootReceiversFile(); 7364 FileInputStream fis = null; 7365 try { 7366 fis = new FileInputStream(file); 7367 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7368 int fvers = dis.readInt(); 7369 if (fvers == LAST_DONE_VERSION) { 7370 String vers = dis.readUTF(); 7371 String codename = dis.readUTF(); 7372 String build = dis.readUTF(); 7373 if (android.os.Build.VERSION.RELEASE.equals(vers) 7374 && android.os.Build.VERSION.CODENAME.equals(codename) 7375 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7376 int num = dis.readInt(); 7377 while (num > 0) { 7378 num--; 7379 String pkg = dis.readUTF(); 7380 String cls = dis.readUTF(); 7381 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7382 } 7383 } 7384 } 7385 } catch (FileNotFoundException e) { 7386 } catch (IOException e) { 7387 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7388 } finally { 7389 if (fis != null) { 7390 try { 7391 fis.close(); 7392 } catch (IOException e) { 7393 } 7394 } 7395 } 7396 return lastDoneReceivers; 7397 } 7398 7399 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7400 File file = getCalledPreBootReceiversFile(); 7401 FileOutputStream fos = null; 7402 DataOutputStream dos = null; 7403 try { 7404 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7405 fos = new FileOutputStream(file); 7406 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7407 dos.writeInt(LAST_DONE_VERSION); 7408 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7409 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7410 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7411 dos.writeInt(list.size()); 7412 for (int i=0; i<list.size(); i++) { 7413 dos.writeUTF(list.get(i).getPackageName()); 7414 dos.writeUTF(list.get(i).getClassName()); 7415 } 7416 } catch (IOException e) { 7417 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7418 file.delete(); 7419 } finally { 7420 FileUtils.sync(fos); 7421 if (dos != null) { 7422 try { 7423 dos.close(); 7424 } catch (IOException e) { 7425 // TODO Auto-generated catch block 7426 e.printStackTrace(); 7427 } 7428 } 7429 } 7430 } 7431 7432 public void systemReady(final Runnable goingCallback) { 7433 synchronized(this) { 7434 if (mSystemReady) { 7435 if (goingCallback != null) goingCallback.run(); 7436 return; 7437 } 7438 7439 // Check to see if there are any update receivers to run. 7440 if (!mDidUpdate) { 7441 if (mWaitingUpdate) { 7442 return; 7443 } 7444 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7445 List<ResolveInfo> ris = null; 7446 try { 7447 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7448 intent, null, 0, 0); 7449 } catch (RemoteException e) { 7450 } 7451 if (ris != null) { 7452 for (int i=ris.size()-1; i>=0; i--) { 7453 if ((ris.get(i).activityInfo.applicationInfo.flags 7454 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7455 ris.remove(i); 7456 } 7457 } 7458 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7459 7460 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7461 7462 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7463 for (int i=0; i<ris.size(); i++) { 7464 ActivityInfo ai = ris.get(i).activityInfo; 7465 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7466 if (lastDoneReceivers.contains(comp)) { 7467 ris.remove(i); 7468 i--; 7469 } 7470 } 7471 7472 for (int i=0; i<ris.size(); i++) { 7473 ActivityInfo ai = ris.get(i).activityInfo; 7474 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7475 doneReceivers.add(comp); 7476 intent.setComponent(comp); 7477 IIntentReceiver finisher = null; 7478 if (i == ris.size()-1) { 7479 finisher = new IIntentReceiver.Stub() { 7480 public void performReceive(Intent intent, int resultCode, 7481 String data, Bundle extras, boolean ordered, 7482 boolean sticky) { 7483 // The raw IIntentReceiver interface is called 7484 // with the AM lock held, so redispatch to 7485 // execute our code without the lock. 7486 mHandler.post(new Runnable() { 7487 public void run() { 7488 synchronized (ActivityManagerService.this) { 7489 mDidUpdate = true; 7490 } 7491 writeLastDonePreBootReceivers(doneReceivers); 7492 showBootMessage(mContext.getText( 7493 R.string.android_upgrading_complete), 7494 false); 7495 systemReady(goingCallback); 7496 } 7497 }); 7498 } 7499 }; 7500 } 7501 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7502 /* TODO: Send this to all users */ 7503 broadcastIntentLocked(null, null, intent, null, finisher, 7504 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7505 0 /* UserId zero */); 7506 if (finisher != null) { 7507 mWaitingUpdate = true; 7508 } 7509 } 7510 } 7511 if (mWaitingUpdate) { 7512 return; 7513 } 7514 mDidUpdate = true; 7515 } 7516 7517 mSystemReady = true; 7518 if (!mStartRunning) { 7519 return; 7520 } 7521 } 7522 7523 ArrayList<ProcessRecord> procsToKill = null; 7524 synchronized(mPidsSelfLocked) { 7525 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7526 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7527 if (!isAllowedWhileBooting(proc.info)){ 7528 if (procsToKill == null) { 7529 procsToKill = new ArrayList<ProcessRecord>(); 7530 } 7531 procsToKill.add(proc); 7532 } 7533 } 7534 } 7535 7536 synchronized(this) { 7537 if (procsToKill != null) { 7538 for (int i=procsToKill.size()-1; i>=0; i--) { 7539 ProcessRecord proc = procsToKill.get(i); 7540 Slog.i(TAG, "Removing system update proc: " + proc); 7541 removeProcessLocked(proc, true, false, "system update done"); 7542 } 7543 } 7544 7545 // Now that we have cleaned up any update processes, we 7546 // are ready to start launching real processes and know that 7547 // we won't trample on them any more. 7548 mProcessesReady = true; 7549 } 7550 7551 Slog.i(TAG, "System now ready"); 7552 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7553 SystemClock.uptimeMillis()); 7554 7555 synchronized(this) { 7556 // Make sure we have no pre-ready processes sitting around. 7557 7558 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7559 ResolveInfo ri = mContext.getPackageManager() 7560 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7561 STOCK_PM_FLAGS); 7562 CharSequence errorMsg = null; 7563 if (ri != null) { 7564 ActivityInfo ai = ri.activityInfo; 7565 ApplicationInfo app = ai.applicationInfo; 7566 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7567 mTopAction = Intent.ACTION_FACTORY_TEST; 7568 mTopData = null; 7569 mTopComponent = new ComponentName(app.packageName, 7570 ai.name); 7571 } else { 7572 errorMsg = mContext.getResources().getText( 7573 com.android.internal.R.string.factorytest_not_system); 7574 } 7575 } else { 7576 errorMsg = mContext.getResources().getText( 7577 com.android.internal.R.string.factorytest_no_action); 7578 } 7579 if (errorMsg != null) { 7580 mTopAction = null; 7581 mTopData = null; 7582 mTopComponent = null; 7583 Message msg = Message.obtain(); 7584 msg.what = SHOW_FACTORY_ERROR_MSG; 7585 msg.getData().putCharSequence("msg", errorMsg); 7586 mHandler.sendMessage(msg); 7587 } 7588 } 7589 } 7590 7591 retrieveSettings(); 7592 7593 if (goingCallback != null) goingCallback.run(); 7594 7595 synchronized (this) { 7596 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7597 try { 7598 List apps = AppGlobals.getPackageManager(). 7599 getPersistentApplications(STOCK_PM_FLAGS); 7600 if (apps != null) { 7601 int N = apps.size(); 7602 int i; 7603 for (i=0; i<N; i++) { 7604 ApplicationInfo info 7605 = (ApplicationInfo)apps.get(i); 7606 if (info != null && 7607 !info.packageName.equals("android")) { 7608 addAppLocked(info, false); 7609 } 7610 } 7611 } 7612 } catch (RemoteException ex) { 7613 // pm is in same process, this will never happen. 7614 } 7615 } 7616 7617 // Start up initial activity. 7618 mBooting = true; 7619 7620 try { 7621 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7622 Message msg = Message.obtain(); 7623 msg.what = SHOW_UID_ERROR_MSG; 7624 mHandler.sendMessage(msg); 7625 } 7626 } catch (RemoteException e) { 7627 } 7628 7629 mMainStack.resumeTopActivityLocked(null); 7630 } 7631 } 7632 7633 private boolean makeAppCrashingLocked(ProcessRecord app, 7634 String shortMsg, String longMsg, String stackTrace) { 7635 app.crashing = true; 7636 app.crashingReport = generateProcessError(app, 7637 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7638 startAppProblemLocked(app); 7639 app.stopFreezingAllLocked(); 7640 return handleAppCrashLocked(app); 7641 } 7642 7643 private void makeAppNotRespondingLocked(ProcessRecord app, 7644 String activity, String shortMsg, String longMsg) { 7645 app.notResponding = true; 7646 app.notRespondingReport = generateProcessError(app, 7647 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7648 activity, shortMsg, longMsg, null); 7649 startAppProblemLocked(app); 7650 app.stopFreezingAllLocked(); 7651 } 7652 7653 /** 7654 * Generate a process error record, suitable for attachment to a ProcessRecord. 7655 * 7656 * @param app The ProcessRecord in which the error occurred. 7657 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7658 * ActivityManager.AppErrorStateInfo 7659 * @param activity The activity associated with the crash, if known. 7660 * @param shortMsg Short message describing the crash. 7661 * @param longMsg Long message describing the crash. 7662 * @param stackTrace Full crash stack trace, may be null. 7663 * 7664 * @return Returns a fully-formed AppErrorStateInfo record. 7665 */ 7666 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7667 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7668 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7669 7670 report.condition = condition; 7671 report.processName = app.processName; 7672 report.pid = app.pid; 7673 report.uid = app.info.uid; 7674 report.tag = activity; 7675 report.shortMsg = shortMsg; 7676 report.longMsg = longMsg; 7677 report.stackTrace = stackTrace; 7678 7679 return report; 7680 } 7681 7682 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7683 synchronized (this) { 7684 app.crashing = false; 7685 app.crashingReport = null; 7686 app.notResponding = false; 7687 app.notRespondingReport = null; 7688 if (app.anrDialog == fromDialog) { 7689 app.anrDialog = null; 7690 } 7691 if (app.waitDialog == fromDialog) { 7692 app.waitDialog = null; 7693 } 7694 if (app.pid > 0 && app.pid != MY_PID) { 7695 handleAppCrashLocked(app); 7696 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7697 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7698 app.processName, app.setAdj, "user's request after error"); 7699 Process.killProcessQuiet(app.pid); 7700 } 7701 } 7702 } 7703 7704 private boolean handleAppCrashLocked(ProcessRecord app) { 7705 if (mHeadless) { 7706 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7707 return false; 7708 } 7709 long now = SystemClock.uptimeMillis(); 7710 7711 Long crashTime; 7712 if (!app.isolated) { 7713 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7714 } else { 7715 crashTime = null; 7716 } 7717 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7718 // This process loses! 7719 Slog.w(TAG, "Process " + app.info.processName 7720 + " has crashed too many times: killing!"); 7721 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7722 app.info.processName, app.uid); 7723 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7724 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7725 if (r.app == app) { 7726 Slog.w(TAG, " Force finishing activity " 7727 + r.intent.getComponent().flattenToShortString()); 7728 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7729 } 7730 } 7731 if (!app.persistent) { 7732 // We don't want to start this process again until the user 7733 // explicitly does so... but for persistent process, we really 7734 // need to keep it running. If a persistent process is actually 7735 // repeatedly crashing, then badness for everyone. 7736 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7737 app.info.processName); 7738 if (!app.isolated) { 7739 // XXX We don't have a way to mark isolated processes 7740 // as bad, since they don't have a peristent identity. 7741 mBadProcesses.put(app.info.processName, app.uid, now); 7742 mProcessCrashTimes.remove(app.info.processName, app.uid); 7743 } 7744 app.bad = true; 7745 app.removed = true; 7746 // Don't let services in this process be restarted and potentially 7747 // annoy the user repeatedly. Unless it is persistent, since those 7748 // processes run critical code. 7749 removeProcessLocked(app, false, false, "crash"); 7750 mMainStack.resumeTopActivityLocked(null); 7751 return false; 7752 } 7753 mMainStack.resumeTopActivityLocked(null); 7754 } else { 7755 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7756 if (r != null && r.app == app) { 7757 // If the top running activity is from this crashing 7758 // process, then terminate it to avoid getting in a loop. 7759 Slog.w(TAG, " Force finishing activity " 7760 + r.intent.getComponent().flattenToShortString()); 7761 int index = mMainStack.indexOfActivityLocked(r); 7762 r.stack.finishActivityLocked(r, index, 7763 Activity.RESULT_CANCELED, null, "crashed"); 7764 // Also terminate any activities below it that aren't yet 7765 // stopped, to avoid a situation where one will get 7766 // re-start our crashing activity once it gets resumed again. 7767 index--; 7768 if (index >= 0) { 7769 r = (ActivityRecord)mMainStack.mHistory.get(index); 7770 if (r.state == ActivityState.RESUMED 7771 || r.state == ActivityState.PAUSING 7772 || r.state == ActivityState.PAUSED) { 7773 if (!r.isHomeActivity || mHomeProcess != r.app) { 7774 Slog.w(TAG, " Force finishing activity " 7775 + r.intent.getComponent().flattenToShortString()); 7776 r.stack.finishActivityLocked(r, index, 7777 Activity.RESULT_CANCELED, null, "crashed"); 7778 } 7779 } 7780 } 7781 } 7782 } 7783 7784 // Bump up the crash count of any services currently running in the proc. 7785 if (app.services.size() != 0) { 7786 // Any services running in the application need to be placed 7787 // back in the pending list. 7788 Iterator<ServiceRecord> it = app.services.iterator(); 7789 while (it.hasNext()) { 7790 ServiceRecord sr = it.next(); 7791 sr.crashCount++; 7792 } 7793 } 7794 7795 // If the crashing process is what we consider to be the "home process" and it has been 7796 // replaced by a third-party app, clear the package preferred activities from packages 7797 // with a home activity running in the process to prevent a repeatedly crashing app 7798 // from blocking the user to manually clear the list. 7799 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7800 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7801 Iterator it = mHomeProcess.activities.iterator(); 7802 while (it.hasNext()) { 7803 ActivityRecord r = (ActivityRecord)it.next(); 7804 if (r.isHomeActivity) { 7805 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7806 try { 7807 ActivityThread.getPackageManager() 7808 .clearPackagePreferredActivities(r.packageName); 7809 } catch (RemoteException c) { 7810 // pm is in same process, this will never happen. 7811 } 7812 } 7813 } 7814 } 7815 7816 if (!app.isolated) { 7817 // XXX Can't keep track of crash times for isolated processes, 7818 // because they don't have a perisistent identity. 7819 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7820 } 7821 7822 return true; 7823 } 7824 7825 void startAppProblemLocked(ProcessRecord app) { 7826 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7827 mContext, app.info.packageName, app.info.flags); 7828 skipCurrentReceiverLocked(app); 7829 } 7830 7831 void skipCurrentReceiverLocked(ProcessRecord app) { 7832 for (BroadcastQueue queue : mBroadcastQueues) { 7833 queue.skipCurrentReceiverLocked(app); 7834 } 7835 } 7836 7837 /** 7838 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7839 * The application process will exit immediately after this call returns. 7840 * @param app object of the crashing app, null for the system server 7841 * @param crashInfo describing the exception 7842 */ 7843 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7844 ProcessRecord r = findAppProcess(app, "Crash"); 7845 final String processName = app == null ? "system_server" 7846 : (r == null ? "unknown" : r.processName); 7847 7848 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7849 processName, 7850 r == null ? -1 : r.info.flags, 7851 crashInfo.exceptionClassName, 7852 crashInfo.exceptionMessage, 7853 crashInfo.throwFileName, 7854 crashInfo.throwLineNumber); 7855 7856 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7857 7858 crashApplication(r, crashInfo); 7859 } 7860 7861 public void handleApplicationStrictModeViolation( 7862 IBinder app, 7863 int violationMask, 7864 StrictMode.ViolationInfo info) { 7865 ProcessRecord r = findAppProcess(app, "StrictMode"); 7866 if (r == null) { 7867 return; 7868 } 7869 7870 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7871 Integer stackFingerprint = info.hashCode(); 7872 boolean logIt = true; 7873 synchronized (mAlreadyLoggedViolatedStacks) { 7874 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7875 logIt = false; 7876 // TODO: sub-sample into EventLog for these, with 7877 // the info.durationMillis? Then we'd get 7878 // the relative pain numbers, without logging all 7879 // the stack traces repeatedly. We'd want to do 7880 // likewise in the client code, which also does 7881 // dup suppression, before the Binder call. 7882 } else { 7883 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7884 mAlreadyLoggedViolatedStacks.clear(); 7885 } 7886 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7887 } 7888 } 7889 if (logIt) { 7890 logStrictModeViolationToDropBox(r, info); 7891 } 7892 } 7893 7894 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7895 AppErrorResult result = new AppErrorResult(); 7896 synchronized (this) { 7897 final long origId = Binder.clearCallingIdentity(); 7898 7899 Message msg = Message.obtain(); 7900 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7901 HashMap<String, Object> data = new HashMap<String, Object>(); 7902 data.put("result", result); 7903 data.put("app", r); 7904 data.put("violationMask", violationMask); 7905 data.put("info", info); 7906 msg.obj = data; 7907 mHandler.sendMessage(msg); 7908 7909 Binder.restoreCallingIdentity(origId); 7910 } 7911 int res = result.get(); 7912 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7913 } 7914 } 7915 7916 // Depending on the policy in effect, there could be a bunch of 7917 // these in quick succession so we try to batch these together to 7918 // minimize disk writes, number of dropbox entries, and maximize 7919 // compression, by having more fewer, larger records. 7920 private void logStrictModeViolationToDropBox( 7921 ProcessRecord process, 7922 StrictMode.ViolationInfo info) { 7923 if (info == null) { 7924 return; 7925 } 7926 final boolean isSystemApp = process == null || 7927 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7928 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7929 final String processName = process == null ? "unknown" : process.processName; 7930 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7931 final DropBoxManager dbox = (DropBoxManager) 7932 mContext.getSystemService(Context.DROPBOX_SERVICE); 7933 7934 // Exit early if the dropbox isn't configured to accept this report type. 7935 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7936 7937 boolean bufferWasEmpty; 7938 boolean needsFlush; 7939 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7940 synchronized (sb) { 7941 bufferWasEmpty = sb.length() == 0; 7942 appendDropBoxProcessHeaders(process, processName, sb); 7943 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7944 sb.append("System-App: ").append(isSystemApp).append("\n"); 7945 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7946 if (info.violationNumThisLoop != 0) { 7947 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7948 } 7949 if (info.numAnimationsRunning != 0) { 7950 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7951 } 7952 if (info.broadcastIntentAction != null) { 7953 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7954 } 7955 if (info.durationMillis != -1) { 7956 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7957 } 7958 if (info.numInstances != -1) { 7959 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7960 } 7961 if (info.tags != null) { 7962 for (String tag : info.tags) { 7963 sb.append("Span-Tag: ").append(tag).append("\n"); 7964 } 7965 } 7966 sb.append("\n"); 7967 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7968 sb.append(info.crashInfo.stackTrace); 7969 } 7970 sb.append("\n"); 7971 7972 // Only buffer up to ~64k. Various logging bits truncate 7973 // things at 128k. 7974 needsFlush = (sb.length() > 64 * 1024); 7975 } 7976 7977 // Flush immediately if the buffer's grown too large, or this 7978 // is a non-system app. Non-system apps are isolated with a 7979 // different tag & policy and not batched. 7980 // 7981 // Batching is useful during internal testing with 7982 // StrictMode settings turned up high. Without batching, 7983 // thousands of separate files could be created on boot. 7984 if (!isSystemApp || needsFlush) { 7985 new Thread("Error dump: " + dropboxTag) { 7986 @Override 7987 public void run() { 7988 String report; 7989 synchronized (sb) { 7990 report = sb.toString(); 7991 sb.delete(0, sb.length()); 7992 sb.trimToSize(); 7993 } 7994 if (report.length() != 0) { 7995 dbox.addText(dropboxTag, report); 7996 } 7997 } 7998 }.start(); 7999 return; 8000 } 8001 8002 // System app batching: 8003 if (!bufferWasEmpty) { 8004 // An existing dropbox-writing thread is outstanding, so 8005 // we don't need to start it up. The existing thread will 8006 // catch the buffer appends we just did. 8007 return; 8008 } 8009 8010 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8011 // (After this point, we shouldn't access AMS internal data structures.) 8012 new Thread("Error dump: " + dropboxTag) { 8013 @Override 8014 public void run() { 8015 // 5 second sleep to let stacks arrive and be batched together 8016 try { 8017 Thread.sleep(5000); // 5 seconds 8018 } catch (InterruptedException e) {} 8019 8020 String errorReport; 8021 synchronized (mStrictModeBuffer) { 8022 errorReport = mStrictModeBuffer.toString(); 8023 if (errorReport.length() == 0) { 8024 return; 8025 } 8026 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8027 mStrictModeBuffer.trimToSize(); 8028 } 8029 dbox.addText(dropboxTag, errorReport); 8030 } 8031 }.start(); 8032 } 8033 8034 /** 8035 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8036 * @param app object of the crashing app, null for the system server 8037 * @param tag reported by the caller 8038 * @param crashInfo describing the context of the error 8039 * @return true if the process should exit immediately (WTF is fatal) 8040 */ 8041 public boolean handleApplicationWtf(IBinder app, String tag, 8042 ApplicationErrorReport.CrashInfo crashInfo) { 8043 ProcessRecord r = findAppProcess(app, "WTF"); 8044 final String processName = app == null ? "system_server" 8045 : (r == null ? "unknown" : r.processName); 8046 8047 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8048 processName, 8049 r == null ? -1 : r.info.flags, 8050 tag, crashInfo.exceptionMessage); 8051 8052 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8053 8054 if (r != null && r.pid != Process.myPid() && 8055 Settings.Secure.getInt(mContext.getContentResolver(), 8056 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8057 crashApplication(r, crashInfo); 8058 return true; 8059 } else { 8060 return false; 8061 } 8062 } 8063 8064 /** 8065 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8066 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8067 */ 8068 private ProcessRecord findAppProcess(IBinder app, String reason) { 8069 if (app == null) { 8070 return null; 8071 } 8072 8073 synchronized (this) { 8074 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8075 final int NA = apps.size(); 8076 for (int ia=0; ia<NA; ia++) { 8077 ProcessRecord p = apps.valueAt(ia); 8078 if (p.thread != null && p.thread.asBinder() == app) { 8079 return p; 8080 } 8081 } 8082 } 8083 8084 Slog.w(TAG, "Can't find mystery application for " + reason 8085 + " from pid=" + Binder.getCallingPid() 8086 + " uid=" + Binder.getCallingUid() + ": " + app); 8087 return null; 8088 } 8089 } 8090 8091 /** 8092 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8093 * to append various headers to the dropbox log text. 8094 */ 8095 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8096 StringBuilder sb) { 8097 // Watchdog thread ends up invoking this function (with 8098 // a null ProcessRecord) to add the stack file to dropbox. 8099 // Do not acquire a lock on this (am) in such cases, as it 8100 // could cause a potential deadlock, if and when watchdog 8101 // is invoked due to unavailability of lock on am and it 8102 // would prevent watchdog from killing system_server. 8103 if (process == null) { 8104 sb.append("Process: ").append(processName).append("\n"); 8105 return; 8106 } 8107 // Note: ProcessRecord 'process' is guarded by the service 8108 // instance. (notably process.pkgList, which could otherwise change 8109 // concurrently during execution of this method) 8110 synchronized (this) { 8111 sb.append("Process: ").append(processName).append("\n"); 8112 int flags = process.info.flags; 8113 IPackageManager pm = AppGlobals.getPackageManager(); 8114 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8115 for (String pkg : process.pkgList) { 8116 sb.append("Package: ").append(pkg); 8117 try { 8118 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8119 if (pi != null) { 8120 sb.append(" v").append(pi.versionCode); 8121 if (pi.versionName != null) { 8122 sb.append(" (").append(pi.versionName).append(")"); 8123 } 8124 } 8125 } catch (RemoteException e) { 8126 Slog.e(TAG, "Error getting package info: " + pkg, e); 8127 } 8128 sb.append("\n"); 8129 } 8130 } 8131 } 8132 8133 private static String processClass(ProcessRecord process) { 8134 if (process == null || process.pid == MY_PID) { 8135 return "system_server"; 8136 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8137 return "system_app"; 8138 } else { 8139 return "data_app"; 8140 } 8141 } 8142 8143 /** 8144 * Write a description of an error (crash, WTF, ANR) to the drop box. 8145 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8146 * @param process which caused the error, null means the system server 8147 * @param activity which triggered the error, null if unknown 8148 * @param parent activity related to the error, null if unknown 8149 * @param subject line related to the error, null if absent 8150 * @param report in long form describing the error, null if absent 8151 * @param logFile to include in the report, null if none 8152 * @param crashInfo giving an application stack trace, null if absent 8153 */ 8154 public void addErrorToDropBox(String eventType, 8155 ProcessRecord process, String processName, ActivityRecord activity, 8156 ActivityRecord parent, String subject, 8157 final String report, final File logFile, 8158 final ApplicationErrorReport.CrashInfo crashInfo) { 8159 // NOTE -- this must never acquire the ActivityManagerService lock, 8160 // otherwise the watchdog may be prevented from resetting the system. 8161 8162 final String dropboxTag = processClass(process) + "_" + eventType; 8163 final DropBoxManager dbox = (DropBoxManager) 8164 mContext.getSystemService(Context.DROPBOX_SERVICE); 8165 8166 // Exit early if the dropbox isn't configured to accept this report type. 8167 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8168 8169 final StringBuilder sb = new StringBuilder(1024); 8170 appendDropBoxProcessHeaders(process, processName, sb); 8171 if (activity != null) { 8172 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8173 } 8174 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8175 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8176 } 8177 if (parent != null && parent != activity) { 8178 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8179 } 8180 if (subject != null) { 8181 sb.append("Subject: ").append(subject).append("\n"); 8182 } 8183 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8184 if (Debug.isDebuggerConnected()) { 8185 sb.append("Debugger: Connected\n"); 8186 } 8187 sb.append("\n"); 8188 8189 // Do the rest in a worker thread to avoid blocking the caller on I/O 8190 // (After this point, we shouldn't access AMS internal data structures.) 8191 Thread worker = new Thread("Error dump: " + dropboxTag) { 8192 @Override 8193 public void run() { 8194 if (report != null) { 8195 sb.append(report); 8196 } 8197 if (logFile != null) { 8198 try { 8199 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8200 } catch (IOException e) { 8201 Slog.e(TAG, "Error reading " + logFile, e); 8202 } 8203 } 8204 if (crashInfo != null && crashInfo.stackTrace != null) { 8205 sb.append(crashInfo.stackTrace); 8206 } 8207 8208 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8209 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8210 if (lines > 0) { 8211 sb.append("\n"); 8212 8213 // Merge several logcat streams, and take the last N lines 8214 InputStreamReader input = null; 8215 try { 8216 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8217 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8218 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8219 8220 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8221 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8222 input = new InputStreamReader(logcat.getInputStream()); 8223 8224 int num; 8225 char[] buf = new char[8192]; 8226 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8227 } catch (IOException e) { 8228 Slog.e(TAG, "Error running logcat", e); 8229 } finally { 8230 if (input != null) try { input.close(); } catch (IOException e) {} 8231 } 8232 } 8233 8234 dbox.addText(dropboxTag, sb.toString()); 8235 } 8236 }; 8237 8238 if (process == null) { 8239 // If process is null, we are being called from some internal code 8240 // and may be about to die -- run this synchronously. 8241 worker.run(); 8242 } else { 8243 worker.start(); 8244 } 8245 } 8246 8247 /** 8248 * Bring up the "unexpected error" dialog box for a crashing app. 8249 * Deal with edge cases (intercepts from instrumented applications, 8250 * ActivityController, error intent receivers, that sort of thing). 8251 * @param r the application crashing 8252 * @param crashInfo describing the failure 8253 */ 8254 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8255 long timeMillis = System.currentTimeMillis(); 8256 String shortMsg = crashInfo.exceptionClassName; 8257 String longMsg = crashInfo.exceptionMessage; 8258 String stackTrace = crashInfo.stackTrace; 8259 if (shortMsg != null && longMsg != null) { 8260 longMsg = shortMsg + ": " + longMsg; 8261 } else if (shortMsg != null) { 8262 longMsg = shortMsg; 8263 } 8264 8265 AppErrorResult result = new AppErrorResult(); 8266 synchronized (this) { 8267 if (mController != null) { 8268 try { 8269 String name = r != null ? r.processName : null; 8270 int pid = r != null ? r.pid : Binder.getCallingPid(); 8271 if (!mController.appCrashed(name, pid, 8272 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8273 Slog.w(TAG, "Force-killing crashed app " + name 8274 + " at watcher's request"); 8275 Process.killProcess(pid); 8276 return; 8277 } 8278 } catch (RemoteException e) { 8279 mController = null; 8280 } 8281 } 8282 8283 final long origId = Binder.clearCallingIdentity(); 8284 8285 // If this process is running instrumentation, finish it. 8286 if (r != null && r.instrumentationClass != null) { 8287 Slog.w(TAG, "Error in app " + r.processName 8288 + " running instrumentation " + r.instrumentationClass + ":"); 8289 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8290 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8291 Bundle info = new Bundle(); 8292 info.putString("shortMsg", shortMsg); 8293 info.putString("longMsg", longMsg); 8294 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8295 Binder.restoreCallingIdentity(origId); 8296 return; 8297 } 8298 8299 // If we can't identify the process or it's already exceeded its crash quota, 8300 // quit right away without showing a crash dialog. 8301 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8302 Binder.restoreCallingIdentity(origId); 8303 return; 8304 } 8305 8306 Message msg = Message.obtain(); 8307 msg.what = SHOW_ERROR_MSG; 8308 HashMap data = new HashMap(); 8309 data.put("result", result); 8310 data.put("app", r); 8311 msg.obj = data; 8312 mHandler.sendMessage(msg); 8313 8314 Binder.restoreCallingIdentity(origId); 8315 } 8316 8317 int res = result.get(); 8318 8319 Intent appErrorIntent = null; 8320 synchronized (this) { 8321 if (r != null && !r.isolated) { 8322 // XXX Can't keep track of crash time for isolated processes, 8323 // since they don't have a persistent identity. 8324 mProcessCrashTimes.put(r.info.processName, r.uid, 8325 SystemClock.uptimeMillis()); 8326 } 8327 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8328 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8329 } 8330 } 8331 8332 if (appErrorIntent != null) { 8333 try { 8334 mContext.startActivity(appErrorIntent); 8335 } catch (ActivityNotFoundException e) { 8336 Slog.w(TAG, "bug report receiver dissappeared", e); 8337 } 8338 } 8339 } 8340 8341 Intent createAppErrorIntentLocked(ProcessRecord r, 8342 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8343 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8344 if (report == null) { 8345 return null; 8346 } 8347 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8348 result.setComponent(r.errorReportReceiver); 8349 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8350 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8351 return result; 8352 } 8353 8354 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8355 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8356 if (r.errorReportReceiver == null) { 8357 return null; 8358 } 8359 8360 if (!r.crashing && !r.notResponding) { 8361 return null; 8362 } 8363 8364 ApplicationErrorReport report = new ApplicationErrorReport(); 8365 report.packageName = r.info.packageName; 8366 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8367 report.processName = r.processName; 8368 report.time = timeMillis; 8369 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8370 8371 if (r.crashing) { 8372 report.type = ApplicationErrorReport.TYPE_CRASH; 8373 report.crashInfo = crashInfo; 8374 } else if (r.notResponding) { 8375 report.type = ApplicationErrorReport.TYPE_ANR; 8376 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8377 8378 report.anrInfo.activity = r.notRespondingReport.tag; 8379 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8380 report.anrInfo.info = r.notRespondingReport.longMsg; 8381 } 8382 8383 return report; 8384 } 8385 8386 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8387 enforceNotIsolatedCaller("getProcessesInErrorState"); 8388 // assume our apps are happy - lazy create the list 8389 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8390 8391 final boolean allUsers = ActivityManager.checkUidPermission( 8392 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8393 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8394 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8395 8396 synchronized (this) { 8397 8398 // iterate across all processes 8399 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8400 ProcessRecord app = mLruProcesses.get(i); 8401 if (!allUsers && app.userId != userId) { 8402 continue; 8403 } 8404 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8405 // This one's in trouble, so we'll generate a report for it 8406 // crashes are higher priority (in case there's a crash *and* an anr) 8407 ActivityManager.ProcessErrorStateInfo report = null; 8408 if (app.crashing) { 8409 report = app.crashingReport; 8410 } else if (app.notResponding) { 8411 report = app.notRespondingReport; 8412 } 8413 8414 if (report != null) { 8415 if (errList == null) { 8416 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8417 } 8418 errList.add(report); 8419 } else { 8420 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8421 " crashing = " + app.crashing + 8422 " notResponding = " + app.notResponding); 8423 } 8424 } 8425 } 8426 } 8427 8428 return errList; 8429 } 8430 8431 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8432 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8433 if (currApp != null) { 8434 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8435 } 8436 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8437 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8438 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8439 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8440 if (currApp != null) { 8441 currApp.lru = 0; 8442 } 8443 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8444 } else if (adj >= ProcessList.SERVICE_ADJ) { 8445 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8446 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8447 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8448 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8449 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8450 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8451 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8452 } else { 8453 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8454 } 8455 } 8456 8457 private void fillInProcMemInfo(ProcessRecord app, 8458 ActivityManager.RunningAppProcessInfo outInfo) { 8459 outInfo.pid = app.pid; 8460 outInfo.uid = app.info.uid; 8461 if (mHeavyWeightProcess == app) { 8462 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8463 } 8464 if (app.persistent) { 8465 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8466 } 8467 if (app.hasActivities) { 8468 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8469 } 8470 outInfo.lastTrimLevel = app.trimMemoryLevel; 8471 int adj = app.curAdj; 8472 outInfo.importance = oomAdjToImportance(adj, outInfo); 8473 outInfo.importanceReasonCode = app.adjTypeCode; 8474 } 8475 8476 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8477 enforceNotIsolatedCaller("getRunningAppProcesses"); 8478 // Lazy instantiation of list 8479 List<ActivityManager.RunningAppProcessInfo> runList = null; 8480 final boolean allUsers = ActivityManager.checkUidPermission( 8481 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8482 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8483 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8484 synchronized (this) { 8485 // Iterate across all processes 8486 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8487 ProcessRecord app = mLruProcesses.get(i); 8488 if (!allUsers && app.userId != userId) { 8489 continue; 8490 } 8491 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8492 // Generate process state info for running application 8493 ActivityManager.RunningAppProcessInfo currApp = 8494 new ActivityManager.RunningAppProcessInfo(app.processName, 8495 app.pid, app.getPackageList()); 8496 fillInProcMemInfo(app, currApp); 8497 if (app.adjSource instanceof ProcessRecord) { 8498 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8499 currApp.importanceReasonImportance = oomAdjToImportance( 8500 app.adjSourceOom, null); 8501 } else if (app.adjSource instanceof ActivityRecord) { 8502 ActivityRecord r = (ActivityRecord)app.adjSource; 8503 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8504 } 8505 if (app.adjTarget instanceof ComponentName) { 8506 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8507 } 8508 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8509 // + " lru=" + currApp.lru); 8510 if (runList == null) { 8511 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8512 } 8513 runList.add(currApp); 8514 } 8515 } 8516 } 8517 return runList; 8518 } 8519 8520 public List<ApplicationInfo> getRunningExternalApplications() { 8521 enforceNotIsolatedCaller("getRunningExternalApplications"); 8522 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8523 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8524 if (runningApps != null && runningApps.size() > 0) { 8525 Set<String> extList = new HashSet<String>(); 8526 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8527 if (app.pkgList != null) { 8528 for (String pkg : app.pkgList) { 8529 extList.add(pkg); 8530 } 8531 } 8532 } 8533 IPackageManager pm = AppGlobals.getPackageManager(); 8534 for (String pkg : extList) { 8535 try { 8536 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8537 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8538 retList.add(info); 8539 } 8540 } catch (RemoteException e) { 8541 } 8542 } 8543 } 8544 return retList; 8545 } 8546 8547 @Override 8548 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8549 enforceNotIsolatedCaller("getMyMemoryState"); 8550 synchronized (this) { 8551 ProcessRecord proc; 8552 synchronized (mPidsSelfLocked) { 8553 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8554 } 8555 fillInProcMemInfo(proc, outInfo); 8556 } 8557 } 8558 8559 @Override 8560 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8561 if (checkCallingPermission(android.Manifest.permission.DUMP) 8562 != PackageManager.PERMISSION_GRANTED) { 8563 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8564 + Binder.getCallingPid() 8565 + ", uid=" + Binder.getCallingUid() 8566 + " without permission " 8567 + android.Manifest.permission.DUMP); 8568 return; 8569 } 8570 8571 boolean dumpAll = false; 8572 boolean dumpClient = false; 8573 String dumpPackage = null; 8574 8575 int opti = 0; 8576 while (opti < args.length) { 8577 String opt = args[opti]; 8578 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8579 break; 8580 } 8581 opti++; 8582 if ("-a".equals(opt)) { 8583 dumpAll = true; 8584 } else if ("-c".equals(opt)) { 8585 dumpClient = true; 8586 } else if ("-h".equals(opt)) { 8587 pw.println("Activity manager dump options:"); 8588 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8589 pw.println(" cmd may be one of:"); 8590 pw.println(" a[ctivities]: activity stack state"); 8591 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8592 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8593 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8594 pw.println(" o[om]: out of memory management"); 8595 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8596 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8597 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8598 pw.println(" service [COMP_SPEC]: service client-side state"); 8599 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8600 pw.println(" all: dump all activities"); 8601 pw.println(" top: dump the top activity"); 8602 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8603 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8604 pw.println(" a partial substring in a component name, a"); 8605 pw.println(" hex object identifier."); 8606 pw.println(" -a: include all available server state."); 8607 pw.println(" -c: include client state."); 8608 return; 8609 } else { 8610 pw.println("Unknown argument: " + opt + "; use -h for help"); 8611 } 8612 } 8613 8614 long origId = Binder.clearCallingIdentity(); 8615 boolean more = false; 8616 // Is the caller requesting to dump a particular piece of data? 8617 if (opti < args.length) { 8618 String cmd = args[opti]; 8619 opti++; 8620 if ("activities".equals(cmd) || "a".equals(cmd)) { 8621 synchronized (this) { 8622 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8623 } 8624 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8625 String[] newArgs; 8626 String name; 8627 if (opti >= args.length) { 8628 name = null; 8629 newArgs = EMPTY_STRING_ARRAY; 8630 } else { 8631 name = args[opti]; 8632 opti++; 8633 newArgs = new String[args.length - opti]; 8634 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8635 args.length - opti); 8636 } 8637 synchronized (this) { 8638 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8639 } 8640 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8641 String[] newArgs; 8642 String name; 8643 if (opti >= args.length) { 8644 name = null; 8645 newArgs = EMPTY_STRING_ARRAY; 8646 } else { 8647 name = args[opti]; 8648 opti++; 8649 newArgs = new String[args.length - opti]; 8650 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8651 args.length - opti); 8652 } 8653 synchronized (this) { 8654 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8655 } 8656 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8657 String[] newArgs; 8658 String name; 8659 if (opti >= args.length) { 8660 name = null; 8661 newArgs = EMPTY_STRING_ARRAY; 8662 } else { 8663 name = args[opti]; 8664 opti++; 8665 newArgs = new String[args.length - opti]; 8666 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8667 args.length - opti); 8668 } 8669 synchronized (this) { 8670 dumpProcessesLocked(fd, pw, args, opti, true, name); 8671 } 8672 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8673 synchronized (this) { 8674 dumpOomLocked(fd, pw, args, opti, true); 8675 } 8676 } else if ("provider".equals(cmd)) { 8677 String[] newArgs; 8678 String name; 8679 if (opti >= args.length) { 8680 name = null; 8681 newArgs = EMPTY_STRING_ARRAY; 8682 } else { 8683 name = args[opti]; 8684 opti++; 8685 newArgs = new String[args.length - opti]; 8686 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8687 } 8688 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8689 pw.println("No providers match: " + name); 8690 pw.println("Use -h for help."); 8691 } 8692 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8693 synchronized (this) { 8694 dumpProvidersLocked(fd, pw, args, opti, true, null); 8695 } 8696 } else if ("service".equals(cmd)) { 8697 String[] newArgs; 8698 String name; 8699 if (opti >= args.length) { 8700 name = null; 8701 newArgs = EMPTY_STRING_ARRAY; 8702 } else { 8703 name = args[opti]; 8704 opti++; 8705 newArgs = new String[args.length - opti]; 8706 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8707 args.length - opti); 8708 } 8709 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8710 pw.println("No services match: " + name); 8711 pw.println("Use -h for help."); 8712 } 8713 } else if ("package".equals(cmd)) { 8714 String[] newArgs; 8715 if (opti >= args.length) { 8716 pw.println("package: no package name specified"); 8717 pw.println("Use -h for help."); 8718 } else { 8719 dumpPackage = args[opti]; 8720 opti++; 8721 newArgs = new String[args.length - opti]; 8722 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8723 args.length - opti); 8724 args = newArgs; 8725 opti = 0; 8726 more = true; 8727 } 8728 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8729 synchronized (this) { 8730 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8731 } 8732 } else { 8733 // Dumping a single activity? 8734 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8735 pw.println("Bad activity command, or no activities match: " + cmd); 8736 pw.println("Use -h for help."); 8737 } 8738 } 8739 if (!more) { 8740 Binder.restoreCallingIdentity(origId); 8741 return; 8742 } 8743 } 8744 8745 // No piece of data specified, dump everything. 8746 synchronized (this) { 8747 boolean needSep; 8748 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8749 if (needSep) { 8750 pw.println(" "); 8751 } 8752 if (dumpAll) { 8753 pw.println("-------------------------------------------------------------------------------"); 8754 } 8755 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8756 if (needSep) { 8757 pw.println(" "); 8758 } 8759 if (dumpAll) { 8760 pw.println("-------------------------------------------------------------------------------"); 8761 } 8762 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8763 if (needSep) { 8764 pw.println(" "); 8765 } 8766 if (dumpAll) { 8767 pw.println("-------------------------------------------------------------------------------"); 8768 } 8769 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8770 if (needSep) { 8771 pw.println(" "); 8772 } 8773 if (dumpAll) { 8774 pw.println("-------------------------------------------------------------------------------"); 8775 } 8776 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8777 if (needSep) { 8778 pw.println(" "); 8779 } 8780 if (dumpAll) { 8781 pw.println("-------------------------------------------------------------------------------"); 8782 } 8783 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8784 } 8785 Binder.restoreCallingIdentity(origId); 8786 } 8787 8788 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8789 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8790 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8791 pw.println(" Main stack:"); 8792 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8793 dumpPackage); 8794 pw.println(" "); 8795 pw.println(" Running activities (most recent first):"); 8796 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8797 dumpPackage); 8798 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8799 pw.println(" "); 8800 pw.println(" Activities waiting for another to become visible:"); 8801 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8802 !dumpAll, false, dumpPackage); 8803 } 8804 if (mMainStack.mStoppingActivities.size() > 0) { 8805 pw.println(" "); 8806 pw.println(" Activities waiting to stop:"); 8807 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8808 !dumpAll, false, dumpPackage); 8809 } 8810 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8811 pw.println(" "); 8812 pw.println(" Activities waiting to sleep:"); 8813 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8814 !dumpAll, false, dumpPackage); 8815 } 8816 if (mMainStack.mFinishingActivities.size() > 0) { 8817 pw.println(" "); 8818 pw.println(" Activities waiting to finish:"); 8819 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8820 !dumpAll, false, dumpPackage); 8821 } 8822 8823 pw.println(" "); 8824 if (mMainStack.mPausingActivity != null) { 8825 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8826 } 8827 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8828 pw.println(" mFocusedActivity: " + mFocusedActivity); 8829 if (dumpAll) { 8830 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8831 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8832 pw.println(" mDismissKeyguardOnNextActivity: " 8833 + mMainStack.mDismissKeyguardOnNextActivity); 8834 } 8835 8836 if (mRecentTasks.size() > 0) { 8837 pw.println(); 8838 pw.println(" Recent tasks:"); 8839 8840 final int N = mRecentTasks.size(); 8841 for (int i=0; i<N; i++) { 8842 TaskRecord tr = mRecentTasks.get(i); 8843 if (dumpPackage != null) { 8844 if (tr.realActivity == null || 8845 !dumpPackage.equals(tr.realActivity)) { 8846 continue; 8847 } 8848 } 8849 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8850 pw.println(tr); 8851 if (dumpAll) { 8852 mRecentTasks.get(i).dump(pw, " "); 8853 } 8854 } 8855 } 8856 8857 if (dumpAll) { 8858 pw.println(" "); 8859 pw.println(" mCurTask: " + mCurTask); 8860 } 8861 8862 return true; 8863 } 8864 8865 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8866 int opti, boolean dumpAll, String dumpPackage) { 8867 boolean needSep = false; 8868 int numPers = 0; 8869 8870 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8871 8872 if (dumpAll) { 8873 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8874 final int NA = procs.size(); 8875 for (int ia=0; ia<NA; ia++) { 8876 ProcessRecord r = procs.valueAt(ia); 8877 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8878 continue; 8879 } 8880 if (!needSep) { 8881 pw.println(" All known processes:"); 8882 needSep = true; 8883 } 8884 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8885 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8886 pw.print(" "); pw.println(r); 8887 r.dump(pw, " "); 8888 if (r.persistent) { 8889 numPers++; 8890 } 8891 } 8892 } 8893 } 8894 8895 if (mIsolatedProcesses.size() > 0) { 8896 if (needSep) pw.println(" "); 8897 needSep = true; 8898 pw.println(" Isolated process list (sorted by uid):"); 8899 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8900 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8901 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8902 continue; 8903 } 8904 pw.println(String.format("%sIsolated #%2d: %s", 8905 " ", i, r.toString())); 8906 } 8907 } 8908 8909 if (mLruProcesses.size() > 0) { 8910 if (needSep) pw.println(" "); 8911 needSep = true; 8912 pw.println(" Process LRU list (sorted by oom_adj):"); 8913 dumpProcessOomList(pw, this, mLruProcesses, " ", 8914 "Proc", "PERS", false, dumpPackage); 8915 needSep = true; 8916 } 8917 8918 if (dumpAll) { 8919 synchronized (mPidsSelfLocked) { 8920 boolean printed = false; 8921 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8922 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8923 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8924 continue; 8925 } 8926 if (!printed) { 8927 if (needSep) pw.println(" "); 8928 needSep = true; 8929 pw.println(" PID mappings:"); 8930 printed = true; 8931 } 8932 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8933 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8934 } 8935 } 8936 } 8937 8938 if (mForegroundProcesses.size() > 0) { 8939 synchronized (mPidsSelfLocked) { 8940 boolean printed = false; 8941 for (int i=0; i<mForegroundProcesses.size(); i++) { 8942 ProcessRecord r = mPidsSelfLocked.get( 8943 mForegroundProcesses.valueAt(i).pid); 8944 if (dumpPackage != null && (r == null 8945 || !dumpPackage.equals(r.info.packageName))) { 8946 continue; 8947 } 8948 if (!printed) { 8949 if (needSep) pw.println(" "); 8950 needSep = true; 8951 pw.println(" Foreground Processes:"); 8952 printed = true; 8953 } 8954 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8955 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8956 } 8957 } 8958 } 8959 8960 if (mPersistentStartingProcesses.size() > 0) { 8961 if (needSep) pw.println(" "); 8962 needSep = true; 8963 pw.println(" Persisent processes that are starting:"); 8964 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8965 "Starting Norm", "Restarting PERS", dumpPackage); 8966 } 8967 8968 if (mRemovedProcesses.size() > 0) { 8969 if (needSep) pw.println(" "); 8970 needSep = true; 8971 pw.println(" Processes that are being removed:"); 8972 dumpProcessList(pw, this, mRemovedProcesses, " ", 8973 "Removed Norm", "Removed PERS", dumpPackage); 8974 } 8975 8976 if (mProcessesOnHold.size() > 0) { 8977 if (needSep) pw.println(" "); 8978 needSep = true; 8979 pw.println(" Processes that are on old until the system is ready:"); 8980 dumpProcessList(pw, this, mProcessesOnHold, " ", 8981 "OnHold Norm", "OnHold PERS", dumpPackage); 8982 } 8983 8984 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8985 8986 if (mProcessCrashTimes.getMap().size() > 0) { 8987 boolean printed = false; 8988 long now = SystemClock.uptimeMillis(); 8989 for (Map.Entry<String, SparseArray<Long>> procs 8990 : mProcessCrashTimes.getMap().entrySet()) { 8991 String pname = procs.getKey(); 8992 SparseArray<Long> uids = procs.getValue(); 8993 final int N = uids.size(); 8994 for (int i=0; i<N; i++) { 8995 int puid = uids.keyAt(i); 8996 ProcessRecord r = mProcessNames.get(pname, puid); 8997 if (dumpPackage != null && (r == null 8998 || !dumpPackage.equals(r.info.packageName))) { 8999 continue; 9000 } 9001 if (!printed) { 9002 if (needSep) pw.println(" "); 9003 needSep = true; 9004 pw.println(" Time since processes crashed:"); 9005 printed = true; 9006 } 9007 pw.print(" Process "); pw.print(pname); 9008 pw.print(" uid "); pw.print(puid); 9009 pw.print(": last crashed "); 9010 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9011 pw.println(" ago"); 9012 } 9013 } 9014 } 9015 9016 if (mBadProcesses.getMap().size() > 0) { 9017 boolean printed = false; 9018 for (Map.Entry<String, SparseArray<Long>> procs 9019 : mBadProcesses.getMap().entrySet()) { 9020 String pname = procs.getKey(); 9021 SparseArray<Long> uids = procs.getValue(); 9022 final int N = uids.size(); 9023 for (int i=0; i<N; i++) { 9024 int puid = uids.keyAt(i); 9025 ProcessRecord r = mProcessNames.get(pname, puid); 9026 if (dumpPackage != null && (r == null 9027 || !dumpPackage.equals(r.info.packageName))) { 9028 continue; 9029 } 9030 if (!printed) { 9031 if (needSep) pw.println(" "); 9032 needSep = true; 9033 pw.println(" Bad processes:"); 9034 } 9035 pw.print(" Bad process "); pw.print(pname); 9036 pw.print(" uid "); pw.print(puid); 9037 pw.print(": crashed at time "); 9038 pw.println(uids.valueAt(i)); 9039 } 9040 } 9041 } 9042 9043 pw.println(); 9044 pw.println(" mHomeProcess: " + mHomeProcess); 9045 pw.println(" mPreviousProcess: " + mPreviousProcess); 9046 if (dumpAll) { 9047 StringBuilder sb = new StringBuilder(128); 9048 sb.append(" mPreviousProcessVisibleTime: "); 9049 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9050 pw.println(sb); 9051 } 9052 if (mHeavyWeightProcess != null) { 9053 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9054 } 9055 pw.println(" mConfiguration: " + mConfiguration); 9056 if (dumpAll) { 9057 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9058 if (mCompatModePackages.getPackages().size() > 0) { 9059 boolean printed = false; 9060 for (Map.Entry<String, Integer> entry 9061 : mCompatModePackages.getPackages().entrySet()) { 9062 String pkg = entry.getKey(); 9063 int mode = entry.getValue(); 9064 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9065 continue; 9066 } 9067 if (!printed) { 9068 pw.println(" mScreenCompatPackages:"); 9069 printed = true; 9070 } 9071 pw.print(" "); pw.print(pkg); pw.print(": "); 9072 pw.print(mode); pw.println(); 9073 } 9074 } 9075 } 9076 if (mSleeping || mWentToSleep || mLockScreenShown) { 9077 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9078 + " mLockScreenShown " + mLockScreenShown); 9079 } 9080 if (mShuttingDown) { 9081 pw.println(" mShuttingDown=" + mShuttingDown); 9082 } 9083 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9084 || mOrigWaitForDebugger) { 9085 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9086 + " mDebugTransient=" + mDebugTransient 9087 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9088 } 9089 if (mOpenGlTraceApp != null) { 9090 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9091 } 9092 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9093 || mProfileFd != null) { 9094 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9095 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9096 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9097 + mAutoStopProfiler); 9098 } 9099 if (mAlwaysFinishActivities || mController != null) { 9100 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9101 + " mController=" + mController); 9102 } 9103 if (dumpAll) { 9104 pw.println(" Total persistent processes: " + numPers); 9105 pw.println(" mStartRunning=" + mStartRunning 9106 + " mProcessesReady=" + mProcessesReady 9107 + " mSystemReady=" + mSystemReady); 9108 pw.println(" mBooting=" + mBooting 9109 + " mBooted=" + mBooted 9110 + " mFactoryTest=" + mFactoryTest); 9111 pw.print(" mLastPowerCheckRealtime="); 9112 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9113 pw.println(""); 9114 pw.print(" mLastPowerCheckUptime="); 9115 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9116 pw.println(""); 9117 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9118 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9119 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9120 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9121 + " mNumHiddenProcs=" + mNumHiddenProcs 9122 + " mNumServiceProcs=" + mNumServiceProcs 9123 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9124 } 9125 9126 return true; 9127 } 9128 9129 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9130 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9131 if (mProcessesToGc.size() > 0) { 9132 boolean printed = false; 9133 long now = SystemClock.uptimeMillis(); 9134 for (int i=0; i<mProcessesToGc.size(); i++) { 9135 ProcessRecord proc = mProcessesToGc.get(i); 9136 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9137 continue; 9138 } 9139 if (!printed) { 9140 if (needSep) pw.println(" "); 9141 needSep = true; 9142 pw.println(" Processes that are waiting to GC:"); 9143 printed = true; 9144 } 9145 pw.print(" Process "); pw.println(proc); 9146 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9147 pw.print(", last gced="); 9148 pw.print(now-proc.lastRequestedGc); 9149 pw.print(" ms ago, last lowMem="); 9150 pw.print(now-proc.lastLowMemory); 9151 pw.println(" ms ago"); 9152 9153 } 9154 } 9155 return needSep; 9156 } 9157 9158 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9159 int opti, boolean dumpAll) { 9160 boolean needSep = false; 9161 9162 if (mLruProcesses.size() > 0) { 9163 if (needSep) pw.println(" "); 9164 needSep = true; 9165 pw.println(" OOM levels:"); 9166 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9167 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9168 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9169 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9170 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9171 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9172 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9173 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9174 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9175 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9176 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9177 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9178 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9179 9180 if (needSep) pw.println(" "); 9181 needSep = true; 9182 pw.println(" Process OOM control:"); 9183 dumpProcessOomList(pw, this, mLruProcesses, " ", 9184 "Proc", "PERS", true, null); 9185 needSep = true; 9186 } 9187 9188 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9189 9190 pw.println(); 9191 pw.println(" mHomeProcess: " + mHomeProcess); 9192 pw.println(" mPreviousProcess: " + mPreviousProcess); 9193 if (mHeavyWeightProcess != null) { 9194 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9195 } 9196 9197 return true; 9198 } 9199 9200 /** 9201 * There are three ways to call this: 9202 * - no provider specified: dump all the providers 9203 * - a flattened component name that matched an existing provider was specified as the 9204 * first arg: dump that one provider 9205 * - the first arg isn't the flattened component name of an existing provider: 9206 * dump all providers whose component contains the first arg as a substring 9207 */ 9208 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9209 int opti, boolean dumpAll) { 9210 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9211 } 9212 9213 static class ItemMatcher { 9214 ArrayList<ComponentName> components; 9215 ArrayList<String> strings; 9216 ArrayList<Integer> objects; 9217 boolean all; 9218 9219 ItemMatcher() { 9220 all = true; 9221 } 9222 9223 void build(String name) { 9224 ComponentName componentName = ComponentName.unflattenFromString(name); 9225 if (componentName != null) { 9226 if (components == null) { 9227 components = new ArrayList<ComponentName>(); 9228 } 9229 components.add(componentName); 9230 all = false; 9231 } else { 9232 int objectId = 0; 9233 // Not a '/' separated full component name; maybe an object ID? 9234 try { 9235 objectId = Integer.parseInt(name, 16); 9236 if (objects == null) { 9237 objects = new ArrayList<Integer>(); 9238 } 9239 objects.add(objectId); 9240 all = false; 9241 } catch (RuntimeException e) { 9242 // Not an integer; just do string match. 9243 if (strings == null) { 9244 strings = new ArrayList<String>(); 9245 } 9246 strings.add(name); 9247 all = false; 9248 } 9249 } 9250 } 9251 9252 int build(String[] args, int opti) { 9253 for (; opti<args.length; opti++) { 9254 String name = args[opti]; 9255 if ("--".equals(name)) { 9256 return opti+1; 9257 } 9258 build(name); 9259 } 9260 return opti; 9261 } 9262 9263 boolean match(Object object, ComponentName comp) { 9264 if (all) { 9265 return true; 9266 } 9267 if (components != null) { 9268 for (int i=0; i<components.size(); i++) { 9269 if (components.get(i).equals(comp)) { 9270 return true; 9271 } 9272 } 9273 } 9274 if (objects != null) { 9275 for (int i=0; i<objects.size(); i++) { 9276 if (System.identityHashCode(object) == objects.get(i)) { 9277 return true; 9278 } 9279 } 9280 } 9281 if (strings != null) { 9282 String flat = comp.flattenToString(); 9283 for (int i=0; i<strings.size(); i++) { 9284 if (flat.contains(strings.get(i))) { 9285 return true; 9286 } 9287 } 9288 } 9289 return false; 9290 } 9291 } 9292 9293 /** 9294 * There are three things that cmd can be: 9295 * - a flattened component name that matches an existing activity 9296 * - the cmd arg isn't the flattened component name of an existing activity: 9297 * dump all activity whose component contains the cmd as a substring 9298 * - A hex number of the ActivityRecord object instance. 9299 */ 9300 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9301 int opti, boolean dumpAll) { 9302 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9303 9304 if ("all".equals(name)) { 9305 synchronized (this) { 9306 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9307 activities.add(r1); 9308 } 9309 } 9310 } else if ("top".equals(name)) { 9311 synchronized (this) { 9312 final int N = mMainStack.mHistory.size(); 9313 if (N > 0) { 9314 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9315 } 9316 } 9317 } else { 9318 ItemMatcher matcher = new ItemMatcher(); 9319 matcher.build(name); 9320 9321 synchronized (this) { 9322 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9323 if (matcher.match(r1, r1.intent.getComponent())) { 9324 activities.add(r1); 9325 } 9326 } 9327 } 9328 } 9329 9330 if (activities.size() <= 0) { 9331 return false; 9332 } 9333 9334 String[] newArgs = new String[args.length - opti]; 9335 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9336 9337 TaskRecord lastTask = null; 9338 boolean needSep = false; 9339 for (int i=activities.size()-1; i>=0; i--) { 9340 ActivityRecord r = (ActivityRecord)activities.get(i); 9341 if (needSep) { 9342 pw.println(); 9343 } 9344 needSep = true; 9345 synchronized (this) { 9346 if (lastTask != r.task) { 9347 lastTask = r.task; 9348 pw.print("TASK "); pw.print(lastTask.affinity); 9349 pw.print(" id="); pw.println(lastTask.taskId); 9350 if (dumpAll) { 9351 lastTask.dump(pw, " "); 9352 } 9353 } 9354 } 9355 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9356 } 9357 return true; 9358 } 9359 9360 /** 9361 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9362 * there is a thread associated with the activity. 9363 */ 9364 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9365 final ActivityRecord r, String[] args, boolean dumpAll) { 9366 String innerPrefix = prefix + " "; 9367 synchronized (this) { 9368 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9369 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9370 pw.print(" pid="); 9371 if (r.app != null) pw.println(r.app.pid); 9372 else pw.println("(not running)"); 9373 if (dumpAll) { 9374 r.dump(pw, innerPrefix); 9375 } 9376 } 9377 if (r.app != null && r.app.thread != null) { 9378 // flush anything that is already in the PrintWriter since the thread is going 9379 // to write to the file descriptor directly 9380 pw.flush(); 9381 try { 9382 TransferPipe tp = new TransferPipe(); 9383 try { 9384 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9385 r.appToken, innerPrefix, args); 9386 tp.go(fd); 9387 } finally { 9388 tp.kill(); 9389 } 9390 } catch (IOException e) { 9391 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9392 } catch (RemoteException e) { 9393 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9394 } 9395 } 9396 } 9397 9398 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9399 int opti, boolean dumpAll, String dumpPackage) { 9400 boolean needSep = false; 9401 9402 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9403 if (dumpAll) { 9404 if (mRegisteredReceivers.size() > 0) { 9405 boolean printed = false; 9406 Iterator it = mRegisteredReceivers.values().iterator(); 9407 while (it.hasNext()) { 9408 ReceiverList r = (ReceiverList)it.next(); 9409 if (dumpPackage != null && (r.app == null || 9410 !dumpPackage.equals(r.app.info.packageName))) { 9411 continue; 9412 } 9413 if (!printed) { 9414 pw.println(" Registered Receivers:"); 9415 needSep = true; 9416 printed = true; 9417 } 9418 pw.print(" * "); pw.println(r); 9419 r.dump(pw, " "); 9420 } 9421 } 9422 9423 if (mReceiverResolver.dump(pw, needSep ? 9424 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9425 " ", dumpPackage, false)) { 9426 needSep = true; 9427 } 9428 } 9429 9430 for (BroadcastQueue q : mBroadcastQueues) { 9431 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9432 } 9433 9434 needSep = true; 9435 9436 if (mStickyBroadcasts != null && dumpPackage == null) { 9437 if (needSep) { 9438 pw.println(); 9439 } 9440 needSep = true; 9441 pw.println(" Sticky broadcasts:"); 9442 StringBuilder sb = new StringBuilder(128); 9443 for (Map.Entry<String, ArrayList<Intent>> ent 9444 : mStickyBroadcasts.entrySet()) { 9445 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9446 if (dumpAll) { 9447 pw.println(":"); 9448 ArrayList<Intent> intents = ent.getValue(); 9449 final int N = intents.size(); 9450 for (int i=0; i<N; i++) { 9451 sb.setLength(0); 9452 sb.append(" Intent: "); 9453 intents.get(i).toShortString(sb, false, true, false, false); 9454 pw.println(sb.toString()); 9455 Bundle bundle = intents.get(i).getExtras(); 9456 if (bundle != null) { 9457 pw.print(" "); 9458 pw.println(bundle.toString()); 9459 } 9460 } 9461 } else { 9462 pw.println(""); 9463 } 9464 } 9465 needSep = true; 9466 } 9467 9468 if (dumpAll) { 9469 pw.println(); 9470 for (BroadcastQueue queue : mBroadcastQueues) { 9471 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9472 + queue.mBroadcastsScheduled); 9473 } 9474 pw.println(" mHandler:"); 9475 mHandler.dump(new PrintWriterPrinter(pw), " "); 9476 needSep = true; 9477 } 9478 9479 return needSep; 9480 } 9481 9482 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9483 int opti, boolean dumpAll, String dumpPackage) { 9484 boolean needSep = true; 9485 9486 ItemMatcher matcher = new ItemMatcher(); 9487 matcher.build(args, opti); 9488 9489 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9490 9491 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9492 9493 if (mLaunchingProviders.size() > 0) { 9494 boolean printed = false; 9495 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9496 ContentProviderRecord r = mLaunchingProviders.get(i); 9497 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9498 continue; 9499 } 9500 if (!printed) { 9501 if (needSep) pw.println(" "); 9502 needSep = true; 9503 pw.println(" Launching content providers:"); 9504 printed = true; 9505 } 9506 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9507 pw.println(r); 9508 } 9509 } 9510 9511 if (mGrantedUriPermissions.size() > 0) { 9512 if (needSep) pw.println(); 9513 needSep = true; 9514 pw.println("Granted Uri Permissions:"); 9515 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9516 int uid = mGrantedUriPermissions.keyAt(i); 9517 HashMap<Uri, UriPermission> perms 9518 = mGrantedUriPermissions.valueAt(i); 9519 pw.print(" * UID "); pw.print(uid); 9520 pw.println(" holds:"); 9521 for (UriPermission perm : perms.values()) { 9522 pw.print(" "); pw.println(perm); 9523 if (dumpAll) { 9524 perm.dump(pw, " "); 9525 } 9526 } 9527 } 9528 needSep = true; 9529 } 9530 9531 return needSep; 9532 } 9533 9534 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9535 int opti, boolean dumpAll, String dumpPackage) { 9536 boolean needSep = false; 9537 9538 if (mIntentSenderRecords.size() > 0) { 9539 boolean printed = false; 9540 Iterator<WeakReference<PendingIntentRecord>> it 9541 = mIntentSenderRecords.values().iterator(); 9542 while (it.hasNext()) { 9543 WeakReference<PendingIntentRecord> ref = it.next(); 9544 PendingIntentRecord rec = ref != null ? ref.get(): null; 9545 if (dumpPackage != null && (rec == null 9546 || !dumpPackage.equals(rec.key.packageName))) { 9547 continue; 9548 } 9549 if (!printed) { 9550 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9551 printed = true; 9552 } 9553 needSep = true; 9554 if (rec != null) { 9555 pw.print(" * "); pw.println(rec); 9556 if (dumpAll) { 9557 rec.dump(pw, " "); 9558 } 9559 } else { 9560 pw.print(" * "); pw.println(ref); 9561 } 9562 } 9563 } 9564 9565 return needSep; 9566 } 9567 9568 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9569 String prefix, String label, boolean complete, boolean brief, boolean client, 9570 String dumpPackage) { 9571 TaskRecord lastTask = null; 9572 boolean needNL = false; 9573 final String innerPrefix = prefix + " "; 9574 final String[] args = new String[0]; 9575 for (int i=list.size()-1; i>=0; i--) { 9576 final ActivityRecord r = (ActivityRecord)list.get(i); 9577 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9578 continue; 9579 } 9580 final boolean full = !brief && (complete || !r.isInHistory()); 9581 if (needNL) { 9582 pw.println(" "); 9583 needNL = false; 9584 } 9585 if (lastTask != r.task) { 9586 lastTask = r.task; 9587 pw.print(prefix); 9588 pw.print(full ? "* " : " "); 9589 pw.println(lastTask); 9590 if (full) { 9591 lastTask.dump(pw, prefix + " "); 9592 } else if (complete) { 9593 // Complete + brief == give a summary. Isn't that obvious?!? 9594 if (lastTask.intent != null) { 9595 pw.print(prefix); pw.print(" "); 9596 pw.println(lastTask.intent.toInsecureStringWithClip()); 9597 } 9598 } 9599 } 9600 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9601 pw.print(" #"); pw.print(i); pw.print(": "); 9602 pw.println(r); 9603 if (full) { 9604 r.dump(pw, innerPrefix); 9605 } else if (complete) { 9606 // Complete + brief == give a summary. Isn't that obvious?!? 9607 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9608 if (r.app != null) { 9609 pw.print(innerPrefix); pw.println(r.app); 9610 } 9611 } 9612 if (client && r.app != null && r.app.thread != null) { 9613 // flush anything that is already in the PrintWriter since the thread is going 9614 // to write to the file descriptor directly 9615 pw.flush(); 9616 try { 9617 TransferPipe tp = new TransferPipe(); 9618 try { 9619 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9620 r.appToken, innerPrefix, args); 9621 // Short timeout, since blocking here can 9622 // deadlock with the application. 9623 tp.go(fd, 2000); 9624 } finally { 9625 tp.kill(); 9626 } 9627 } catch (IOException e) { 9628 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9629 } catch (RemoteException e) { 9630 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9631 } 9632 needNL = true; 9633 } 9634 } 9635 } 9636 9637 private static String buildOomTag(String prefix, String space, int val, int base) { 9638 if (val == base) { 9639 if (space == null) return prefix; 9640 return prefix + " "; 9641 } 9642 return prefix + "+" + Integer.toString(val-base); 9643 } 9644 9645 private static final int dumpProcessList(PrintWriter pw, 9646 ActivityManagerService service, List list, 9647 String prefix, String normalLabel, String persistentLabel, 9648 String dumpPackage) { 9649 int numPers = 0; 9650 final int N = list.size()-1; 9651 for (int i=N; i>=0; i--) { 9652 ProcessRecord r = (ProcessRecord)list.get(i); 9653 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9654 continue; 9655 } 9656 pw.println(String.format("%s%s #%2d: %s", 9657 prefix, (r.persistent ? persistentLabel : normalLabel), 9658 i, r.toString())); 9659 if (r.persistent) { 9660 numPers++; 9661 } 9662 } 9663 return numPers; 9664 } 9665 9666 private static final boolean dumpProcessOomList(PrintWriter pw, 9667 ActivityManagerService service, List<ProcessRecord> origList, 9668 String prefix, String normalLabel, String persistentLabel, 9669 boolean inclDetails, String dumpPackage) { 9670 9671 ArrayList<Pair<ProcessRecord, Integer>> list 9672 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9673 for (int i=0; i<origList.size(); i++) { 9674 ProcessRecord r = origList.get(i); 9675 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9676 continue; 9677 } 9678 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9679 } 9680 9681 if (list.size() <= 0) { 9682 return false; 9683 } 9684 9685 Comparator<Pair<ProcessRecord, Integer>> comparator 9686 = new Comparator<Pair<ProcessRecord, Integer>>() { 9687 @Override 9688 public int compare(Pair<ProcessRecord, Integer> object1, 9689 Pair<ProcessRecord, Integer> object2) { 9690 if (object1.first.setAdj != object2.first.setAdj) { 9691 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9692 } 9693 if (object1.second.intValue() != object2.second.intValue()) { 9694 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9695 } 9696 return 0; 9697 } 9698 }; 9699 9700 Collections.sort(list, comparator); 9701 9702 final long curRealtime = SystemClock.elapsedRealtime(); 9703 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9704 final long curUptime = SystemClock.uptimeMillis(); 9705 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9706 9707 for (int i=list.size()-1; i>=0; i--) { 9708 ProcessRecord r = list.get(i).first; 9709 String oomAdj; 9710 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9711 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9712 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9713 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9714 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9715 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9716 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9717 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9718 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9719 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9720 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9721 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9722 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9723 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9724 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9725 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9726 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9727 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9728 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9729 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9730 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9731 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9732 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9733 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9734 } else { 9735 oomAdj = Integer.toString(r.setAdj); 9736 } 9737 String schedGroup; 9738 switch (r.setSchedGroup) { 9739 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9740 schedGroup = "B"; 9741 break; 9742 case Process.THREAD_GROUP_DEFAULT: 9743 schedGroup = "F"; 9744 break; 9745 default: 9746 schedGroup = Integer.toString(r.setSchedGroup); 9747 break; 9748 } 9749 String foreground; 9750 if (r.foregroundActivities) { 9751 foreground = "A"; 9752 } else if (r.foregroundServices) { 9753 foreground = "S"; 9754 } else { 9755 foreground = " "; 9756 } 9757 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9758 prefix, (r.persistent ? persistentLabel : normalLabel), 9759 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9760 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9761 if (r.adjSource != null || r.adjTarget != null) { 9762 pw.print(prefix); 9763 pw.print(" "); 9764 if (r.adjTarget instanceof ComponentName) { 9765 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9766 } else if (r.adjTarget != null) { 9767 pw.print(r.adjTarget.toString()); 9768 } else { 9769 pw.print("{null}"); 9770 } 9771 pw.print("<="); 9772 if (r.adjSource instanceof ProcessRecord) { 9773 pw.print("Proc{"); 9774 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9775 pw.println("}"); 9776 } else if (r.adjSource != null) { 9777 pw.println(r.adjSource.toString()); 9778 } else { 9779 pw.println("{null}"); 9780 } 9781 } 9782 if (inclDetails) { 9783 pw.print(prefix); 9784 pw.print(" "); 9785 pw.print("oom: max="); pw.print(r.maxAdj); 9786 pw.print(" hidden="); pw.print(r.hiddenAdj); 9787 pw.print(" empty="); pw.print(r.emptyAdj); 9788 pw.print(" curRaw="); pw.print(r.curRawAdj); 9789 pw.print(" setRaw="); pw.print(r.setRawAdj); 9790 pw.print(" cur="); pw.print(r.curAdj); 9791 pw.print(" set="); pw.println(r.setAdj); 9792 pw.print(prefix); 9793 pw.print(" "); 9794 pw.print("keeping="); pw.print(r.keeping); 9795 pw.print(" hidden="); pw.print(r.hidden); 9796 pw.print(" empty="); pw.print(r.empty); 9797 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9798 9799 if (!r.keeping) { 9800 if (r.lastWakeTime != 0) { 9801 long wtime; 9802 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9803 synchronized (stats) { 9804 wtime = stats.getProcessWakeTime(r.info.uid, 9805 r.pid, curRealtime); 9806 } 9807 long timeUsed = wtime - r.lastWakeTime; 9808 pw.print(prefix); 9809 pw.print(" "); 9810 pw.print("keep awake over "); 9811 TimeUtils.formatDuration(realtimeSince, pw); 9812 pw.print(" used "); 9813 TimeUtils.formatDuration(timeUsed, pw); 9814 pw.print(" ("); 9815 pw.print((timeUsed*100)/realtimeSince); 9816 pw.println("%)"); 9817 } 9818 if (r.lastCpuTime != 0) { 9819 long timeUsed = r.curCpuTime - r.lastCpuTime; 9820 pw.print(prefix); 9821 pw.print(" "); 9822 pw.print("run cpu over "); 9823 TimeUtils.formatDuration(uptimeSince, pw); 9824 pw.print(" used "); 9825 TimeUtils.formatDuration(timeUsed, pw); 9826 pw.print(" ("); 9827 pw.print((timeUsed*100)/uptimeSince); 9828 pw.println("%)"); 9829 } 9830 } 9831 } 9832 } 9833 return true; 9834 } 9835 9836 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9837 ArrayList<ProcessRecord> procs; 9838 synchronized (this) { 9839 if (args != null && args.length > start 9840 && args[start].charAt(0) != '-') { 9841 procs = new ArrayList<ProcessRecord>(); 9842 int pid = -1; 9843 try { 9844 pid = Integer.parseInt(args[start]); 9845 } catch (NumberFormatException e) { 9846 9847 } 9848 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9849 ProcessRecord proc = mLruProcesses.get(i); 9850 if (proc.pid == pid) { 9851 procs.add(proc); 9852 } else if (proc.processName.equals(args[start])) { 9853 procs.add(proc); 9854 } 9855 } 9856 if (procs.size() <= 0) { 9857 pw.println("No process found for: " + args[start]); 9858 return null; 9859 } 9860 } else { 9861 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9862 } 9863 } 9864 return procs; 9865 } 9866 9867 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9868 PrintWriter pw, String[] args) { 9869 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9870 if (procs == null) { 9871 return; 9872 } 9873 9874 long uptime = SystemClock.uptimeMillis(); 9875 long realtime = SystemClock.elapsedRealtime(); 9876 pw.println("Applications Graphics Acceleration Info:"); 9877 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9878 9879 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9880 ProcessRecord r = procs.get(i); 9881 if (r.thread != null) { 9882 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9883 pw.flush(); 9884 try { 9885 TransferPipe tp = new TransferPipe(); 9886 try { 9887 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9888 tp.go(fd); 9889 } finally { 9890 tp.kill(); 9891 } 9892 } catch (IOException e) { 9893 pw.println("Failure while dumping the app: " + r); 9894 pw.flush(); 9895 } catch (RemoteException e) { 9896 pw.println("Got a RemoteException while dumping the app " + r); 9897 pw.flush(); 9898 } 9899 } 9900 } 9901 } 9902 9903 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9904 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9905 if (procs == null) { 9906 return; 9907 } 9908 9909 pw.println("Applications Database Info:"); 9910 9911 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9912 ProcessRecord r = procs.get(i); 9913 if (r.thread != null) { 9914 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9915 pw.flush(); 9916 try { 9917 TransferPipe tp = new TransferPipe(); 9918 try { 9919 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9920 tp.go(fd); 9921 } finally { 9922 tp.kill(); 9923 } 9924 } catch (IOException e) { 9925 pw.println("Failure while dumping the app: " + r); 9926 pw.flush(); 9927 } catch (RemoteException e) { 9928 pw.println("Got a RemoteException while dumping the app " + r); 9929 pw.flush(); 9930 } 9931 } 9932 } 9933 } 9934 9935 final static class MemItem { 9936 final String label; 9937 final String shortLabel; 9938 final long pss; 9939 final int id; 9940 ArrayList<MemItem> subitems; 9941 9942 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9943 label = _label; 9944 shortLabel = _shortLabel; 9945 pss = _pss; 9946 id = _id; 9947 } 9948 } 9949 9950 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9951 boolean sort) { 9952 if (sort) { 9953 Collections.sort(items, new Comparator<MemItem>() { 9954 @Override 9955 public int compare(MemItem lhs, MemItem rhs) { 9956 if (lhs.pss < rhs.pss) { 9957 return 1; 9958 } else if (lhs.pss > rhs.pss) { 9959 return -1; 9960 } 9961 return 0; 9962 } 9963 }); 9964 } 9965 9966 for (int i=0; i<items.size(); i++) { 9967 MemItem mi = items.get(i); 9968 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9969 if (mi.subitems != null) { 9970 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9971 } 9972 } 9973 } 9974 9975 // These are in KB. 9976 static final long[] DUMP_MEM_BUCKETS = new long[] { 9977 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9978 120*1024, 160*1024, 200*1024, 9979 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9980 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9981 }; 9982 9983 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9984 boolean stackLike) { 9985 int start = label.lastIndexOf('.'); 9986 if (start >= 0) start++; 9987 else start = 0; 9988 int end = label.length(); 9989 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9990 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9991 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9992 out.append(bucket); 9993 out.append(stackLike ? "MB." : "MB "); 9994 out.append(label, start, end); 9995 return; 9996 } 9997 } 9998 out.append(memKB/1024); 9999 out.append(stackLike ? "MB." : "MB "); 10000 out.append(label, start, end); 10001 } 10002 10003 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10004 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10005 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10006 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10007 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10008 }; 10009 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10010 "System", "Persistent", "Foreground", 10011 "Visible", "Perceptible", "Heavy Weight", 10012 "Backup", "A Services", "Home", "Previous", 10013 "B Services", "Background" 10014 }; 10015 10016 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10017 PrintWriter pw, String prefix, String[] args, boolean brief, 10018 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10019 boolean dumpAll = false; 10020 boolean oomOnly = false; 10021 10022 int opti = 0; 10023 while (opti < args.length) { 10024 String opt = args[opti]; 10025 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10026 break; 10027 } 10028 opti++; 10029 if ("-a".equals(opt)) { 10030 dumpAll = true; 10031 } else if ("--oom".equals(opt)) { 10032 oomOnly = true; 10033 } else if ("-h".equals(opt)) { 10034 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10035 pw.println(" -a: include all available information for each process."); 10036 pw.println(" --oom: only show processes organized by oom adj."); 10037 pw.println("If [process] is specified it can be the name or "); 10038 pw.println("pid of a specific process to dump."); 10039 return; 10040 } else { 10041 pw.println("Unknown argument: " + opt + "; use -h for help"); 10042 } 10043 } 10044 10045 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10046 if (procs == null) { 10047 return; 10048 } 10049 10050 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10051 long uptime = SystemClock.uptimeMillis(); 10052 long realtime = SystemClock.elapsedRealtime(); 10053 10054 if (procs.size() == 1 || isCheckinRequest) { 10055 dumpAll = true; 10056 } 10057 10058 if (isCheckinRequest) { 10059 // short checkin version 10060 pw.println(uptime + "," + realtime); 10061 pw.flush(); 10062 } else { 10063 pw.println("Applications Memory Usage (kB):"); 10064 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10065 } 10066 10067 String[] innerArgs = new String[args.length-opti]; 10068 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10069 10070 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10071 long nativePss=0, dalvikPss=0, otherPss=0; 10072 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10073 10074 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10075 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10076 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10077 10078 long totalPss = 0; 10079 10080 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10081 ProcessRecord r = procs.get(i); 10082 if (r.thread != null) { 10083 if (!isCheckinRequest && dumpAll) { 10084 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10085 pw.flush(); 10086 } 10087 Debug.MemoryInfo mi = null; 10088 if (dumpAll) { 10089 try { 10090 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10091 } catch (RemoteException e) { 10092 if (!isCheckinRequest) { 10093 pw.println("Got RemoteException!"); 10094 pw.flush(); 10095 } 10096 } 10097 } else { 10098 mi = new Debug.MemoryInfo(); 10099 Debug.getMemoryInfo(r.pid, mi); 10100 } 10101 10102 if (!isCheckinRequest && mi != null) { 10103 long myTotalPss = mi.getTotalPss(); 10104 totalPss += myTotalPss; 10105 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10106 r.processName, myTotalPss, 0); 10107 procMems.add(pssItem); 10108 10109 nativePss += mi.nativePss; 10110 dalvikPss += mi.dalvikPss; 10111 otherPss += mi.otherPss; 10112 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10113 long mem = mi.getOtherPss(j); 10114 miscPss[j] += mem; 10115 otherPss -= mem; 10116 } 10117 10118 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10119 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10120 || oomIndex == (oomPss.length-1)) { 10121 oomPss[oomIndex] += myTotalPss; 10122 if (oomProcs[oomIndex] == null) { 10123 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10124 } 10125 oomProcs[oomIndex].add(pssItem); 10126 break; 10127 } 10128 } 10129 } 10130 } 10131 } 10132 10133 if (!isCheckinRequest && procs.size() > 1) { 10134 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10135 10136 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10137 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10138 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10139 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10140 String label = Debug.MemoryInfo.getOtherLabel(j); 10141 catMems.add(new MemItem(label, label, miscPss[j], j)); 10142 } 10143 10144 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10145 for (int j=0; j<oomPss.length; j++) { 10146 if (oomPss[j] != 0) { 10147 String label = DUMP_MEM_OOM_LABEL[j]; 10148 MemItem item = new MemItem(label, label, oomPss[j], 10149 DUMP_MEM_OOM_ADJ[j]); 10150 item.subitems = oomProcs[j]; 10151 oomMems.add(item); 10152 } 10153 } 10154 10155 if (outTag != null || outStack != null) { 10156 if (outTag != null) { 10157 appendMemBucket(outTag, totalPss, "total", false); 10158 } 10159 if (outStack != null) { 10160 appendMemBucket(outStack, totalPss, "total", true); 10161 } 10162 boolean firstLine = true; 10163 for (int i=0; i<oomMems.size(); i++) { 10164 MemItem miCat = oomMems.get(i); 10165 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10166 continue; 10167 } 10168 if (miCat.id < ProcessList.SERVICE_ADJ 10169 || miCat.id == ProcessList.HOME_APP_ADJ 10170 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10171 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10172 outTag.append(" / "); 10173 } 10174 if (outStack != null) { 10175 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10176 if (firstLine) { 10177 outStack.append(":"); 10178 firstLine = false; 10179 } 10180 outStack.append("\n\t at "); 10181 } else { 10182 outStack.append("$"); 10183 } 10184 } 10185 for (int j=0; j<miCat.subitems.size(); j++) { 10186 MemItem mi = miCat.subitems.get(j); 10187 if (j > 0) { 10188 if (outTag != null) { 10189 outTag.append(" "); 10190 } 10191 if (outStack != null) { 10192 outStack.append("$"); 10193 } 10194 } 10195 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10196 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10197 } 10198 if (outStack != null) { 10199 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10200 } 10201 } 10202 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10203 outStack.append("("); 10204 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10205 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10206 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10207 outStack.append(":"); 10208 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10209 } 10210 } 10211 outStack.append(")"); 10212 } 10213 } 10214 } 10215 } 10216 10217 if (!brief && !oomOnly) { 10218 pw.println(); 10219 pw.println("Total PSS by process:"); 10220 dumpMemItems(pw, " ", procMems, true); 10221 pw.println(); 10222 } 10223 pw.println("Total PSS by OOM adjustment:"); 10224 dumpMemItems(pw, " ", oomMems, false); 10225 if (!oomOnly) { 10226 PrintWriter out = categoryPw != null ? categoryPw : pw; 10227 out.println(); 10228 out.println("Total PSS by category:"); 10229 dumpMemItems(out, " ", catMems, true); 10230 } 10231 pw.println(); 10232 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10233 final int[] SINGLE_LONG_FORMAT = new int[] { 10234 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10235 }; 10236 long[] longOut = new long[1]; 10237 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10238 SINGLE_LONG_FORMAT, null, longOut, null); 10239 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10240 longOut[0] = 0; 10241 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10242 SINGLE_LONG_FORMAT, null, longOut, null); 10243 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10244 longOut[0] = 0; 10245 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10246 SINGLE_LONG_FORMAT, null, longOut, null); 10247 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10248 longOut[0] = 0; 10249 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10250 SINGLE_LONG_FORMAT, null, longOut, null); 10251 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10252 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10253 pw.print(shared); pw.println(" kB"); 10254 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10255 pw.print(voltile); pw.println(" kB volatile"); 10256 } 10257 } 10258 10259 /** 10260 * Searches array of arguments for the specified string 10261 * @param args array of argument strings 10262 * @param value value to search for 10263 * @return true if the value is contained in the array 10264 */ 10265 private static boolean scanArgs(String[] args, String value) { 10266 if (args != null) { 10267 for (String arg : args) { 10268 if (value.equals(arg)) { 10269 return true; 10270 } 10271 } 10272 } 10273 return false; 10274 } 10275 10276 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10277 ContentProviderRecord cpr, boolean always) { 10278 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10279 10280 if (!inLaunching || always) { 10281 synchronized (cpr) { 10282 cpr.launchingApp = null; 10283 cpr.notifyAll(); 10284 } 10285 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10286 String names[] = cpr.info.authority.split(";"); 10287 for (int j = 0; j < names.length; j++) { 10288 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10289 } 10290 } 10291 10292 for (int i=0; i<cpr.connections.size(); i++) { 10293 ContentProviderConnection conn = cpr.connections.get(i); 10294 if (conn.waiting) { 10295 // If this connection is waiting for the provider, then we don't 10296 // need to mess with its process unless we are always removing 10297 // or for some reason the provider is not currently launching. 10298 if (inLaunching && !always) { 10299 continue; 10300 } 10301 } 10302 ProcessRecord capp = conn.client; 10303 conn.dead = true; 10304 if (conn.stableCount > 0) { 10305 if (!capp.persistent && capp.thread != null 10306 && capp.pid != 0 10307 && capp.pid != MY_PID) { 10308 Slog.i(TAG, "Kill " + capp.processName 10309 + " (pid " + capp.pid + "): provider " + cpr.info.name 10310 + " in dying process " + (proc != null ? proc.processName : "??")); 10311 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10312 capp.processName, capp.setAdj, "dying provider " 10313 + cpr.name.toShortString()); 10314 Process.killProcessQuiet(capp.pid); 10315 } 10316 } else if (capp.thread != null && conn.provider.provider != null) { 10317 try { 10318 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10319 } catch (RemoteException e) { 10320 } 10321 // In the protocol here, we don't expect the client to correctly 10322 // clean up this connection, we'll just remove it. 10323 cpr.connections.remove(i); 10324 conn.client.conProviders.remove(conn); 10325 } 10326 } 10327 10328 if (inLaunching && always) { 10329 mLaunchingProviders.remove(cpr); 10330 } 10331 return inLaunching; 10332 } 10333 10334 /** 10335 * Main code for cleaning up a process when it has gone away. This is 10336 * called both as a result of the process dying, or directly when stopping 10337 * a process when running in single process mode. 10338 */ 10339 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10340 boolean restarting, boolean allowRestart, int index) { 10341 if (index >= 0) { 10342 mLruProcesses.remove(index); 10343 } 10344 10345 mProcessesToGc.remove(app); 10346 10347 // Dismiss any open dialogs. 10348 if (app.crashDialog != null) { 10349 app.crashDialog.dismiss(); 10350 app.crashDialog = null; 10351 } 10352 if (app.anrDialog != null) { 10353 app.anrDialog.dismiss(); 10354 app.anrDialog = null; 10355 } 10356 if (app.waitDialog != null) { 10357 app.waitDialog.dismiss(); 10358 app.waitDialog = null; 10359 } 10360 10361 app.crashing = false; 10362 app.notResponding = false; 10363 10364 app.resetPackageList(); 10365 app.unlinkDeathRecipient(); 10366 app.thread = null; 10367 app.forcingToForeground = null; 10368 app.foregroundServices = false; 10369 app.foregroundActivities = false; 10370 app.hasShownUi = false; 10371 app.hasAboveClient = false; 10372 10373 mServices.killServicesLocked(app, allowRestart); 10374 10375 boolean restart = false; 10376 10377 // Remove published content providers. 10378 if (!app.pubProviders.isEmpty()) { 10379 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10380 while (it.hasNext()) { 10381 ContentProviderRecord cpr = it.next(); 10382 10383 final boolean always = app.bad || !allowRestart; 10384 if (removeDyingProviderLocked(app, cpr, always) || always) { 10385 // We left the provider in the launching list, need to 10386 // restart it. 10387 restart = true; 10388 } 10389 10390 cpr.provider = null; 10391 cpr.proc = null; 10392 } 10393 app.pubProviders.clear(); 10394 } 10395 10396 // Take care of any launching providers waiting for this process. 10397 if (checkAppInLaunchingProvidersLocked(app, false)) { 10398 restart = true; 10399 } 10400 10401 // Unregister from connected content providers. 10402 if (!app.conProviders.isEmpty()) { 10403 for (int i=0; i<app.conProviders.size(); i++) { 10404 ContentProviderConnection conn = app.conProviders.get(i); 10405 conn.provider.connections.remove(conn); 10406 } 10407 app.conProviders.clear(); 10408 } 10409 10410 // At this point there may be remaining entries in mLaunchingProviders 10411 // where we were the only one waiting, so they are no longer of use. 10412 // Look for these and clean up if found. 10413 // XXX Commented out for now. Trying to figure out a way to reproduce 10414 // the actual situation to identify what is actually going on. 10415 if (false) { 10416 for (int i=0; i<mLaunchingProviders.size(); i++) { 10417 ContentProviderRecord cpr = (ContentProviderRecord) 10418 mLaunchingProviders.get(i); 10419 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10420 synchronized (cpr) { 10421 cpr.launchingApp = null; 10422 cpr.notifyAll(); 10423 } 10424 } 10425 } 10426 } 10427 10428 skipCurrentReceiverLocked(app); 10429 10430 // Unregister any receivers. 10431 if (app.receivers.size() > 0) { 10432 Iterator<ReceiverList> it = app.receivers.iterator(); 10433 while (it.hasNext()) { 10434 removeReceiverLocked(it.next()); 10435 } 10436 app.receivers.clear(); 10437 } 10438 10439 // If the app is undergoing backup, tell the backup manager about it 10440 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10441 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10442 try { 10443 IBackupManager bm = IBackupManager.Stub.asInterface( 10444 ServiceManager.getService(Context.BACKUP_SERVICE)); 10445 bm.agentDisconnected(app.info.packageName); 10446 } catch (RemoteException e) { 10447 // can't happen; backup manager is local 10448 } 10449 } 10450 10451 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10452 ProcessChangeItem item = mPendingProcessChanges.get(i); 10453 if (item.pid == app.pid) { 10454 mPendingProcessChanges.remove(i); 10455 mAvailProcessChanges.add(item); 10456 } 10457 } 10458 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10459 10460 // If the caller is restarting this app, then leave it in its 10461 // current lists and let the caller take care of it. 10462 if (restarting) { 10463 return; 10464 } 10465 10466 if (!app.persistent || app.isolated) { 10467 if (DEBUG_PROCESSES) Slog.v(TAG, 10468 "Removing non-persistent process during cleanup: " + app); 10469 mProcessNames.remove(app.processName, app.uid); 10470 mIsolatedProcesses.remove(app.uid); 10471 if (mHeavyWeightProcess == app) { 10472 mHeavyWeightProcess = null; 10473 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10474 } 10475 } else if (!app.removed) { 10476 // This app is persistent, so we need to keep its record around. 10477 // If it is not already on the pending app list, add it there 10478 // and start a new process for it. 10479 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10480 mPersistentStartingProcesses.add(app); 10481 restart = true; 10482 } 10483 } 10484 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10485 "Clean-up removing on hold: " + app); 10486 mProcessesOnHold.remove(app); 10487 10488 if (app == mHomeProcess) { 10489 mHomeProcess = null; 10490 } 10491 if (app == mPreviousProcess) { 10492 mPreviousProcess = null; 10493 } 10494 10495 if (restart && !app.isolated) { 10496 // We have components that still need to be running in the 10497 // process, so re-launch it. 10498 mProcessNames.put(app.processName, app.uid, app); 10499 startProcessLocked(app, "restart", app.processName); 10500 } else if (app.pid > 0 && app.pid != MY_PID) { 10501 // Goodbye! 10502 synchronized (mPidsSelfLocked) { 10503 mPidsSelfLocked.remove(app.pid); 10504 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10505 } 10506 app.setPid(0); 10507 } 10508 } 10509 10510 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10511 // Look through the content providers we are waiting to have launched, 10512 // and if any run in this process then either schedule a restart of 10513 // the process or kill the client waiting for it if this process has 10514 // gone bad. 10515 int NL = mLaunchingProviders.size(); 10516 boolean restart = false; 10517 for (int i=0; i<NL; i++) { 10518 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10519 if (cpr.launchingApp == app) { 10520 if (!alwaysBad && !app.bad) { 10521 restart = true; 10522 } else { 10523 removeDyingProviderLocked(app, cpr, true); 10524 NL = mLaunchingProviders.size(); 10525 } 10526 } 10527 } 10528 return restart; 10529 } 10530 10531 // ========================================================= 10532 // SERVICES 10533 // ========================================================= 10534 10535 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10536 int flags) { 10537 enforceNotIsolatedCaller("getServices"); 10538 synchronized (this) { 10539 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10540 } 10541 } 10542 10543 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10544 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10545 synchronized (this) { 10546 return mServices.getRunningServiceControlPanelLocked(name); 10547 } 10548 } 10549 10550 public ComponentName startService(IApplicationThread caller, Intent service, 10551 String resolvedType) { 10552 enforceNotIsolatedCaller("startService"); 10553 // Refuse possible leaked file descriptors 10554 if (service != null && service.hasFileDescriptors() == true) { 10555 throw new IllegalArgumentException("File descriptors passed in Intent"); 10556 } 10557 10558 if (DEBUG_SERVICE) 10559 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10560 synchronized(this) { 10561 final int callingPid = Binder.getCallingPid(); 10562 final int callingUid = Binder.getCallingUid(); 10563 final long origId = Binder.clearCallingIdentity(); 10564 ComponentName res = mServices.startServiceLocked(caller, service, 10565 resolvedType, callingPid, callingUid); 10566 Binder.restoreCallingIdentity(origId); 10567 return res; 10568 } 10569 } 10570 10571 ComponentName startServiceInPackage(int uid, 10572 Intent service, String resolvedType) { 10573 synchronized(this) { 10574 if (DEBUG_SERVICE) 10575 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10576 final long origId = Binder.clearCallingIdentity(); 10577 ComponentName res = mServices.startServiceLocked(null, service, 10578 resolvedType, -1, uid); 10579 Binder.restoreCallingIdentity(origId); 10580 return res; 10581 } 10582 } 10583 10584 public int stopService(IApplicationThread caller, Intent service, 10585 String resolvedType) { 10586 enforceNotIsolatedCaller("stopService"); 10587 // Refuse possible leaked file descriptors 10588 if (service != null && service.hasFileDescriptors() == true) { 10589 throw new IllegalArgumentException("File descriptors passed in Intent"); 10590 } 10591 10592 synchronized(this) { 10593 return mServices.stopServiceLocked(caller, service, resolvedType); 10594 } 10595 } 10596 10597 public IBinder peekService(Intent service, String resolvedType) { 10598 enforceNotIsolatedCaller("peekService"); 10599 // Refuse possible leaked file descriptors 10600 if (service != null && service.hasFileDescriptors() == true) { 10601 throw new IllegalArgumentException("File descriptors passed in Intent"); 10602 } 10603 synchronized(this) { 10604 return mServices.peekServiceLocked(service, resolvedType); 10605 } 10606 } 10607 10608 public boolean stopServiceToken(ComponentName className, IBinder token, 10609 int startId) { 10610 synchronized(this) { 10611 return mServices.stopServiceTokenLocked(className, token, startId); 10612 } 10613 } 10614 10615 public void setServiceForeground(ComponentName className, IBinder token, 10616 int id, Notification notification, boolean removeNotification) { 10617 synchronized(this) { 10618 mServices.setServiceForegroundLocked(className, token, id, notification, 10619 removeNotification); 10620 } 10621 } 10622 10623 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10624 String className, int flags) { 10625 boolean result = false; 10626 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10627 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10628 if (ActivityManager.checkUidPermission( 10629 android.Manifest.permission.INTERACT_ACROSS_USERS, 10630 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10631 ComponentName comp = new ComponentName(aInfo.packageName, className); 10632 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10633 + " requests FLAG_SINGLE_USER, but app does not hold " 10634 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10635 Slog.w(TAG, msg); 10636 throw new SecurityException(msg); 10637 } 10638 result = true; 10639 } 10640 } else if (componentProcessName == aInfo.packageName) { 10641 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10642 } else if ("system".equals(componentProcessName)) { 10643 result = true; 10644 } 10645 if (DEBUG_MU) { 10646 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10647 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10648 } 10649 return result; 10650 } 10651 10652 public int bindService(IApplicationThread caller, IBinder token, 10653 Intent service, String resolvedType, 10654 IServiceConnection connection, int flags, int userId) { 10655 enforceNotIsolatedCaller("bindService"); 10656 // Refuse possible leaked file descriptors 10657 if (service != null && service.hasFileDescriptors() == true) { 10658 throw new IllegalArgumentException("File descriptors passed in Intent"); 10659 } 10660 10661 checkValidCaller(Binder.getCallingUid(), userId); 10662 10663 synchronized(this) { 10664 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10665 connection, flags, userId); 10666 } 10667 } 10668 10669 public boolean unbindService(IServiceConnection connection) { 10670 synchronized (this) { 10671 return mServices.unbindServiceLocked(connection); 10672 } 10673 } 10674 10675 public void publishService(IBinder token, Intent intent, IBinder service) { 10676 // Refuse possible leaked file descriptors 10677 if (intent != null && intent.hasFileDescriptors() == true) { 10678 throw new IllegalArgumentException("File descriptors passed in Intent"); 10679 } 10680 10681 synchronized(this) { 10682 if (!(token instanceof ServiceRecord)) { 10683 throw new IllegalArgumentException("Invalid service token"); 10684 } 10685 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10686 } 10687 } 10688 10689 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10690 // Refuse possible leaked file descriptors 10691 if (intent != null && intent.hasFileDescriptors() == true) { 10692 throw new IllegalArgumentException("File descriptors passed in Intent"); 10693 } 10694 10695 synchronized(this) { 10696 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10697 } 10698 } 10699 10700 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10701 synchronized(this) { 10702 if (!(token instanceof ServiceRecord)) { 10703 throw new IllegalArgumentException("Invalid service token"); 10704 } 10705 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10706 } 10707 } 10708 10709 // ========================================================= 10710 // BACKUP AND RESTORE 10711 // ========================================================= 10712 10713 // Cause the target app to be launched if necessary and its backup agent 10714 // instantiated. The backup agent will invoke backupAgentCreated() on the 10715 // activity manager to announce its creation. 10716 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10717 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10718 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10719 10720 synchronized(this) { 10721 // !!! TODO: currently no check here that we're already bound 10722 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10723 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10724 synchronized (stats) { 10725 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10726 } 10727 10728 // Backup agent is now in use, its package can't be stopped. 10729 try { 10730 AppGlobals.getPackageManager().setPackageStoppedState( 10731 app.packageName, false, UserHandle.getUserId(app.uid)); 10732 } catch (RemoteException e) { 10733 } catch (IllegalArgumentException e) { 10734 Slog.w(TAG, "Failed trying to unstop package " 10735 + app.packageName + ": " + e); 10736 } 10737 10738 BackupRecord r = new BackupRecord(ss, app, backupMode); 10739 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10740 ? new ComponentName(app.packageName, app.backupAgentName) 10741 : new ComponentName("android", "FullBackupAgent"); 10742 // startProcessLocked() returns existing proc's record if it's already running 10743 ProcessRecord proc = startProcessLocked(app.processName, app, 10744 false, 0, "backup", hostingName, false, false); 10745 if (proc == null) { 10746 Slog.e(TAG, "Unable to start backup agent process " + r); 10747 return false; 10748 } 10749 10750 r.app = proc; 10751 mBackupTarget = r; 10752 mBackupAppName = app.packageName; 10753 10754 // Try not to kill the process during backup 10755 updateOomAdjLocked(proc); 10756 10757 // If the process is already attached, schedule the creation of the backup agent now. 10758 // If it is not yet live, this will be done when it attaches to the framework. 10759 if (proc.thread != null) { 10760 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10761 try { 10762 proc.thread.scheduleCreateBackupAgent(app, 10763 compatibilityInfoForPackageLocked(app), backupMode); 10764 } catch (RemoteException e) { 10765 // Will time out on the backup manager side 10766 } 10767 } else { 10768 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10769 } 10770 // Invariants: at this point, the target app process exists and the application 10771 // is either already running or in the process of coming up. mBackupTarget and 10772 // mBackupAppName describe the app, so that when it binds back to the AM we 10773 // know that it's scheduled for a backup-agent operation. 10774 } 10775 10776 return true; 10777 } 10778 10779 // A backup agent has just come up 10780 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10781 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10782 + " = " + agent); 10783 10784 synchronized(this) { 10785 if (!agentPackageName.equals(mBackupAppName)) { 10786 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10787 return; 10788 } 10789 } 10790 10791 long oldIdent = Binder.clearCallingIdentity(); 10792 try { 10793 IBackupManager bm = IBackupManager.Stub.asInterface( 10794 ServiceManager.getService(Context.BACKUP_SERVICE)); 10795 bm.agentConnected(agentPackageName, agent); 10796 } catch (RemoteException e) { 10797 // can't happen; the backup manager service is local 10798 } catch (Exception e) { 10799 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10800 e.printStackTrace(); 10801 } finally { 10802 Binder.restoreCallingIdentity(oldIdent); 10803 } 10804 } 10805 10806 // done with this agent 10807 public void unbindBackupAgent(ApplicationInfo appInfo) { 10808 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10809 if (appInfo == null) { 10810 Slog.w(TAG, "unbind backup agent for null app"); 10811 return; 10812 } 10813 10814 synchronized(this) { 10815 if (mBackupAppName == null) { 10816 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10817 return; 10818 } 10819 10820 if (!mBackupAppName.equals(appInfo.packageName)) { 10821 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10822 return; 10823 } 10824 10825 ProcessRecord proc = mBackupTarget.app; 10826 mBackupTarget = null; 10827 mBackupAppName = null; 10828 10829 // Not backing this app up any more; reset its OOM adjustment 10830 updateOomAdjLocked(proc); 10831 10832 // If the app crashed during backup, 'thread' will be null here 10833 if (proc.thread != null) { 10834 try { 10835 proc.thread.scheduleDestroyBackupAgent(appInfo, 10836 compatibilityInfoForPackageLocked(appInfo)); 10837 } catch (Exception e) { 10838 Slog.e(TAG, "Exception when unbinding backup agent:"); 10839 e.printStackTrace(); 10840 } 10841 } 10842 } 10843 } 10844 // ========================================================= 10845 // BROADCASTS 10846 // ========================================================= 10847 10848 private final List getStickiesLocked(String action, IntentFilter filter, 10849 List cur) { 10850 final ContentResolver resolver = mContext.getContentResolver(); 10851 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10852 if (list == null) { 10853 return cur; 10854 } 10855 int N = list.size(); 10856 for (int i=0; i<N; i++) { 10857 Intent intent = list.get(i); 10858 if (filter.match(resolver, intent, true, TAG) >= 0) { 10859 if (cur == null) { 10860 cur = new ArrayList<Intent>(); 10861 } 10862 cur.add(intent); 10863 } 10864 } 10865 return cur; 10866 } 10867 10868 boolean isPendingBroadcastProcessLocked(int pid) { 10869 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10870 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10871 } 10872 10873 void skipPendingBroadcastLocked(int pid) { 10874 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10875 for (BroadcastQueue queue : mBroadcastQueues) { 10876 queue.skipPendingBroadcastLocked(pid); 10877 } 10878 } 10879 10880 // The app just attached; send any pending broadcasts that it should receive 10881 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10882 boolean didSomething = false; 10883 for (BroadcastQueue queue : mBroadcastQueues) { 10884 didSomething |= queue.sendPendingBroadcastsLocked(app); 10885 } 10886 return didSomething; 10887 } 10888 10889 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10890 IIntentReceiver receiver, IntentFilter filter, String permission) { 10891 enforceNotIsolatedCaller("registerReceiver"); 10892 int callingUid; 10893 synchronized(this) { 10894 ProcessRecord callerApp = null; 10895 if (caller != null) { 10896 callerApp = getRecordForAppLocked(caller); 10897 if (callerApp == null) { 10898 throw new SecurityException( 10899 "Unable to find app for caller " + caller 10900 + " (pid=" + Binder.getCallingPid() 10901 + ") when registering receiver " + receiver); 10902 } 10903 if (callerApp.info.uid != Process.SYSTEM_UID && 10904 !callerApp.pkgList.contains(callerPackage)) { 10905 throw new SecurityException("Given caller package " + callerPackage 10906 + " is not running in process " + callerApp); 10907 } 10908 callingUid = callerApp.info.uid; 10909 } else { 10910 callerPackage = null; 10911 callingUid = Binder.getCallingUid(); 10912 } 10913 10914 List allSticky = null; 10915 10916 // Look for any matching sticky broadcasts... 10917 Iterator actions = filter.actionsIterator(); 10918 if (actions != null) { 10919 while (actions.hasNext()) { 10920 String action = (String)actions.next(); 10921 allSticky = getStickiesLocked(action, filter, allSticky); 10922 } 10923 } else { 10924 allSticky = getStickiesLocked(null, filter, allSticky); 10925 } 10926 10927 // The first sticky in the list is returned directly back to 10928 // the client. 10929 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10930 10931 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10932 + ": " + sticky); 10933 10934 if (receiver == null) { 10935 return sticky; 10936 } 10937 10938 ReceiverList rl 10939 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10940 if (rl == null) { 10941 rl = new ReceiverList(this, callerApp, 10942 Binder.getCallingPid(), 10943 Binder.getCallingUid(), receiver); 10944 if (rl.app != null) { 10945 rl.app.receivers.add(rl); 10946 } else { 10947 try { 10948 receiver.asBinder().linkToDeath(rl, 0); 10949 } catch (RemoteException e) { 10950 return sticky; 10951 } 10952 rl.linkedToDeath = true; 10953 } 10954 mRegisteredReceivers.put(receiver.asBinder(), rl); 10955 } 10956 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10957 permission, callingUid); 10958 rl.add(bf); 10959 if (!bf.debugCheck()) { 10960 Slog.w(TAG, "==> For Dynamic broadast"); 10961 } 10962 mReceiverResolver.addFilter(bf); 10963 10964 // Enqueue broadcasts for all existing stickies that match 10965 // this filter. 10966 if (allSticky != null) { 10967 ArrayList receivers = new ArrayList(); 10968 receivers.add(bf); 10969 10970 int N = allSticky.size(); 10971 for (int i=0; i<N; i++) { 10972 Intent intent = (Intent)allSticky.get(i); 10973 BroadcastQueue queue = broadcastQueueForIntent(intent); 10974 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10975 null, -1, -1, null, receivers, null, 0, null, null, 10976 false, true, true, false); 10977 queue.enqueueParallelBroadcastLocked(r); 10978 queue.scheduleBroadcastsLocked(); 10979 } 10980 } 10981 10982 return sticky; 10983 } 10984 } 10985 10986 public void unregisterReceiver(IIntentReceiver receiver) { 10987 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10988 10989 final long origId = Binder.clearCallingIdentity(); 10990 try { 10991 boolean doTrim = false; 10992 10993 synchronized(this) { 10994 ReceiverList rl 10995 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10996 if (rl != null) { 10997 if (rl.curBroadcast != null) { 10998 BroadcastRecord r = rl.curBroadcast; 10999 final boolean doNext = finishReceiverLocked( 11000 receiver.asBinder(), r.resultCode, r.resultData, 11001 r.resultExtras, r.resultAbort, true); 11002 if (doNext) { 11003 doTrim = true; 11004 r.queue.processNextBroadcast(false); 11005 } 11006 } 11007 11008 if (rl.app != null) { 11009 rl.app.receivers.remove(rl); 11010 } 11011 removeReceiverLocked(rl); 11012 if (rl.linkedToDeath) { 11013 rl.linkedToDeath = false; 11014 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11015 } 11016 } 11017 } 11018 11019 // If we actually concluded any broadcasts, we might now be able 11020 // to trim the recipients' apps from our working set 11021 if (doTrim) { 11022 trimApplications(); 11023 return; 11024 } 11025 11026 } finally { 11027 Binder.restoreCallingIdentity(origId); 11028 } 11029 } 11030 11031 void removeReceiverLocked(ReceiverList rl) { 11032 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11033 int N = rl.size(); 11034 for (int i=0; i<N; i++) { 11035 mReceiverResolver.removeFilter(rl.get(i)); 11036 } 11037 } 11038 11039 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11040 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11041 ProcessRecord r = mLruProcesses.get(i); 11042 if (r.thread != null) { 11043 try { 11044 r.thread.dispatchPackageBroadcast(cmd, packages); 11045 } catch (RemoteException ex) { 11046 } 11047 } 11048 } 11049 } 11050 11051 private final int broadcastIntentLocked(ProcessRecord callerApp, 11052 String callerPackage, Intent intent, String resolvedType, 11053 IIntentReceiver resultTo, int resultCode, String resultData, 11054 Bundle map, String requiredPermission, 11055 boolean ordered, boolean sticky, int callingPid, int callingUid, 11056 int userId) { 11057 intent = new Intent(intent); 11058 11059 // By default broadcasts do not go to stopped apps. 11060 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11061 11062 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11063 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11064 + " ordered=" + ordered + " userid=" + userId); 11065 if ((resultTo != null) && !ordered) { 11066 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11067 } 11068 11069 boolean onlySendToCaller = false; 11070 11071 // If the caller is trying to send this broadcast to a different 11072 // user, verify that is allowed. 11073 if (UserHandle.getUserId(callingUid) != userId) { 11074 if (checkComponentPermission( 11075 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11076 callingPid, callingUid, -1, true) 11077 != PackageManager.PERMISSION_GRANTED) { 11078 if (checkComponentPermission( 11079 android.Manifest.permission.INTERACT_ACROSS_USERS, 11080 callingPid, callingUid, -1, true) 11081 == PackageManager.PERMISSION_GRANTED) { 11082 onlySendToCaller = true; 11083 } else { 11084 String msg = "Permission Denial: " + intent.getAction() 11085 + " broadcast from " + callerPackage 11086 + " asks to send as user " + userId 11087 + " but is calling from user " + UserHandle.getUserId(callingUid) 11088 + "; this requires " 11089 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11090 Slog.w(TAG, msg); 11091 throw new SecurityException(msg); 11092 } 11093 } 11094 } 11095 11096 // Handle special intents: if this broadcast is from the package 11097 // manager about a package being removed, we need to remove all of 11098 // its activities from the history stack. 11099 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11100 intent.getAction()); 11101 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11102 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11103 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11104 || uidRemoved) { 11105 if (checkComponentPermission( 11106 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11107 callingPid, callingUid, -1, true) 11108 == PackageManager.PERMISSION_GRANTED) { 11109 if (uidRemoved) { 11110 final Bundle intentExtras = intent.getExtras(); 11111 final int uid = intentExtras != null 11112 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11113 if (uid >= 0) { 11114 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11115 synchronized (bs) { 11116 bs.removeUidStatsLocked(uid); 11117 } 11118 } 11119 } else { 11120 // If resources are unvailble just force stop all 11121 // those packages and flush the attribute cache as well. 11122 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11123 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11124 if (list != null && (list.length > 0)) { 11125 for (String pkg : list) { 11126 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11127 } 11128 sendPackageBroadcastLocked( 11129 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11130 } 11131 } else { 11132 Uri data = intent.getData(); 11133 String ssp; 11134 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11135 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11136 forceStopPackageLocked(ssp, 11137 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11138 false, userId); 11139 } 11140 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11141 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11142 new String[] {ssp}); 11143 } 11144 } 11145 } 11146 } 11147 } else { 11148 String msg = "Permission Denial: " + intent.getAction() 11149 + " broadcast from " + callerPackage + " (pid=" + callingPid 11150 + ", uid=" + callingUid + ")" 11151 + " requires " 11152 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11153 Slog.w(TAG, msg); 11154 throw new SecurityException(msg); 11155 } 11156 11157 // Special case for adding a package: by default turn on compatibility 11158 // mode. 11159 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11160 Uri data = intent.getData(); 11161 String ssp; 11162 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11163 mCompatModePackages.handlePackageAddedLocked(ssp, 11164 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11165 } 11166 } 11167 11168 /* 11169 * If this is the time zone changed action, queue up a message that will reset the timezone 11170 * of all currently running processes. This message will get queued up before the broadcast 11171 * happens. 11172 */ 11173 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11174 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11175 } 11176 11177 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11178 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11179 } 11180 11181 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11182 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11183 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11184 } 11185 11186 /* 11187 * Prevent non-system code (defined here to be non-persistent 11188 * processes) from sending protected broadcasts. 11189 */ 11190 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11191 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11192 callingUid == 0) { 11193 // Always okay. 11194 } else if (callerApp == null || !callerApp.persistent) { 11195 try { 11196 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11197 intent.getAction())) { 11198 String msg = "Permission Denial: not allowed to send broadcast " 11199 + intent.getAction() + " from pid=" 11200 + callingPid + ", uid=" + callingUid; 11201 Slog.w(TAG, msg); 11202 throw new SecurityException(msg); 11203 } 11204 } catch (RemoteException e) { 11205 Slog.w(TAG, "Remote exception", e); 11206 return ActivityManager.BROADCAST_SUCCESS; 11207 } 11208 } 11209 11210 // Add to the sticky list if requested. 11211 if (sticky) { 11212 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11213 callingPid, callingUid) 11214 != PackageManager.PERMISSION_GRANTED) { 11215 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11216 + callingPid + ", uid=" + callingUid 11217 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11218 Slog.w(TAG, msg); 11219 throw new SecurityException(msg); 11220 } 11221 if (requiredPermission != null) { 11222 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11223 + " and enforce permission " + requiredPermission); 11224 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11225 } 11226 if (intent.getComponent() != null) { 11227 throw new SecurityException( 11228 "Sticky broadcasts can't target a specific component"); 11229 } 11230 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11231 if (list == null) { 11232 list = new ArrayList<Intent>(); 11233 mStickyBroadcasts.put(intent.getAction(), list); 11234 } 11235 int N = list.size(); 11236 int i; 11237 for (i=0; i<N; i++) { 11238 if (intent.filterEquals(list.get(i))) { 11239 // This sticky already exists, replace it. 11240 list.set(i, new Intent(intent)); 11241 break; 11242 } 11243 } 11244 if (i >= N) { 11245 list.add(new Intent(intent)); 11246 } 11247 } 11248 11249 // Figure out who all will receive this broadcast. 11250 List receivers = null; 11251 List<BroadcastFilter> registeredReceivers = null; 11252 try { 11253 // Need to resolve the intent to interested receivers... 11254 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11255 == 0) { 11256 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11257 intent, resolvedType, STOCK_PM_FLAGS, userId); 11258 } 11259 if (intent.getComponent() == null) { 11260 registeredReceivers = mReceiverResolver.queryIntent(intent, 11261 resolvedType, false, userId); 11262 } 11263 } catch (RemoteException ex) { 11264 // pm is in same process, this will never happen. 11265 } 11266 11267 final boolean replacePending = 11268 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11269 11270 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11271 + " replacePending=" + replacePending); 11272 11273 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11274 if (!ordered && NR > 0) { 11275 // If we are not serializing this broadcast, then send the 11276 // registered receivers separately so they don't wait for the 11277 // components to be launched. 11278 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11279 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11280 callerPackage, callingPid, callingUid, requiredPermission, 11281 registeredReceivers, resultTo, resultCode, resultData, map, 11282 ordered, sticky, false, onlySendToCaller); 11283 if (DEBUG_BROADCAST) Slog.v( 11284 TAG, "Enqueueing parallel broadcast " + r); 11285 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11286 if (!replaced) { 11287 queue.enqueueParallelBroadcastLocked(r); 11288 queue.scheduleBroadcastsLocked(); 11289 } 11290 registeredReceivers = null; 11291 NR = 0; 11292 } 11293 11294 // Merge into one list. 11295 int ir = 0; 11296 if (receivers != null) { 11297 // A special case for PACKAGE_ADDED: do not allow the package 11298 // being added to see this broadcast. This prevents them from 11299 // using this as a back door to get run as soon as they are 11300 // installed. Maybe in the future we want to have a special install 11301 // broadcast or such for apps, but we'd like to deliberately make 11302 // this decision. 11303 String skipPackages[] = null; 11304 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11305 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11306 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11307 Uri data = intent.getData(); 11308 if (data != null) { 11309 String pkgName = data.getSchemeSpecificPart(); 11310 if (pkgName != null) { 11311 skipPackages = new String[] { pkgName }; 11312 } 11313 } 11314 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11315 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11316 } 11317 if (skipPackages != null && (skipPackages.length > 0)) { 11318 for (String skipPackage : skipPackages) { 11319 if (skipPackage != null) { 11320 int NT = receivers.size(); 11321 for (int it=0; it<NT; it++) { 11322 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11323 if (curt.activityInfo.packageName.equals(skipPackage)) { 11324 receivers.remove(it); 11325 it--; 11326 NT--; 11327 } 11328 } 11329 } 11330 } 11331 } 11332 11333 int NT = receivers != null ? receivers.size() : 0; 11334 int it = 0; 11335 ResolveInfo curt = null; 11336 BroadcastFilter curr = null; 11337 while (it < NT && ir < NR) { 11338 if (curt == null) { 11339 curt = (ResolveInfo)receivers.get(it); 11340 } 11341 if (curr == null) { 11342 curr = registeredReceivers.get(ir); 11343 } 11344 if (curr.getPriority() >= curt.priority) { 11345 // Insert this broadcast record into the final list. 11346 receivers.add(it, curr); 11347 ir++; 11348 curr = null; 11349 it++; 11350 NT++; 11351 } else { 11352 // Skip to the next ResolveInfo in the final list. 11353 it++; 11354 curt = null; 11355 } 11356 } 11357 } 11358 while (ir < NR) { 11359 if (receivers == null) { 11360 receivers = new ArrayList(); 11361 } 11362 receivers.add(registeredReceivers.get(ir)); 11363 ir++; 11364 } 11365 11366 if ((receivers != null && receivers.size() > 0) 11367 || resultTo != null) { 11368 BroadcastQueue queue = broadcastQueueForIntent(intent); 11369 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11370 callerPackage, callingPid, callingUid, requiredPermission, 11371 receivers, resultTo, resultCode, resultData, map, ordered, 11372 sticky, false, onlySendToCaller); 11373 if (DEBUG_BROADCAST) Slog.v( 11374 TAG, "Enqueueing ordered broadcast " + r 11375 + ": prev had " + queue.mOrderedBroadcasts.size()); 11376 if (DEBUG_BROADCAST) { 11377 int seq = r.intent.getIntExtra("seq", -1); 11378 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11379 } 11380 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11381 if (!replaced) { 11382 queue.enqueueOrderedBroadcastLocked(r); 11383 queue.scheduleBroadcastsLocked(); 11384 } 11385 } 11386 11387 return ActivityManager.BROADCAST_SUCCESS; 11388 } 11389 11390 final Intent verifyBroadcastLocked(Intent intent) { 11391 // Refuse possible leaked file descriptors 11392 if (intent != null && intent.hasFileDescriptors() == true) { 11393 throw new IllegalArgumentException("File descriptors passed in Intent"); 11394 } 11395 11396 int flags = intent.getFlags(); 11397 11398 if (!mProcessesReady) { 11399 // if the caller really truly claims to know what they're doing, go 11400 // ahead and allow the broadcast without launching any receivers 11401 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11402 intent = new Intent(intent); 11403 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11404 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11405 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11406 + " before boot completion"); 11407 throw new IllegalStateException("Cannot broadcast before boot completed"); 11408 } 11409 } 11410 11411 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11412 throw new IllegalArgumentException( 11413 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11414 } 11415 11416 return intent; 11417 } 11418 11419 public final int broadcastIntent(IApplicationThread caller, 11420 Intent intent, String resolvedType, IIntentReceiver resultTo, 11421 int resultCode, String resultData, Bundle map, 11422 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11423 enforceNotIsolatedCaller("broadcastIntent"); 11424 synchronized(this) { 11425 intent = verifyBroadcastLocked(intent); 11426 11427 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11428 final int callingPid = Binder.getCallingPid(); 11429 final int callingUid = Binder.getCallingUid(); 11430 final long origId = Binder.clearCallingIdentity(); 11431 int res = broadcastIntentLocked(callerApp, 11432 callerApp != null ? callerApp.info.packageName : null, 11433 intent, resolvedType, resultTo, 11434 resultCode, resultData, map, requiredPermission, serialized, sticky, 11435 callingPid, callingUid, userId); 11436 Binder.restoreCallingIdentity(origId); 11437 return res; 11438 } 11439 } 11440 11441 int broadcastIntentInPackage(String packageName, int uid, 11442 Intent intent, String resolvedType, IIntentReceiver resultTo, 11443 int resultCode, String resultData, Bundle map, 11444 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11445 synchronized(this) { 11446 intent = verifyBroadcastLocked(intent); 11447 11448 final long origId = Binder.clearCallingIdentity(); 11449 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11450 resultTo, resultCode, resultData, map, requiredPermission, 11451 serialized, sticky, -1, uid, userId); 11452 Binder.restoreCallingIdentity(origId); 11453 return res; 11454 } 11455 } 11456 11457 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11458 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11459 // Refuse possible leaked file descriptors 11460 if (intent != null && intent.hasFileDescriptors() == true) { 11461 throw new IllegalArgumentException("File descriptors passed in Intent"); 11462 } 11463 11464 synchronized(this) { 11465 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11466 != PackageManager.PERMISSION_GRANTED) { 11467 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11468 + Binder.getCallingPid() 11469 + ", uid=" + Binder.getCallingUid() 11470 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11471 Slog.w(TAG, msg); 11472 throw new SecurityException(msg); 11473 } 11474 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11475 if (list != null) { 11476 int N = list.size(); 11477 int i; 11478 for (i=0; i<N; i++) { 11479 if (intent.filterEquals(list.get(i))) { 11480 list.remove(i); 11481 break; 11482 } 11483 } 11484 } 11485 } 11486 } 11487 11488 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11489 String resultData, Bundle resultExtras, boolean resultAbort, 11490 boolean explicit) { 11491 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11492 if (r == null) { 11493 Slog.w(TAG, "finishReceiver called but not found on queue"); 11494 return false; 11495 } 11496 11497 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11498 explicit); 11499 } 11500 11501 public void finishReceiver(IBinder who, int resultCode, String resultData, 11502 Bundle resultExtras, boolean resultAbort) { 11503 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11504 11505 // Refuse possible leaked file descriptors 11506 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11507 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11508 } 11509 11510 final long origId = Binder.clearCallingIdentity(); 11511 try { 11512 boolean doNext = false; 11513 BroadcastRecord r = null; 11514 11515 synchronized(this) { 11516 r = broadcastRecordForReceiverLocked(who); 11517 if (r != null) { 11518 doNext = r.queue.finishReceiverLocked(r, resultCode, 11519 resultData, resultExtras, resultAbort, true); 11520 } 11521 } 11522 11523 if (doNext) { 11524 r.queue.processNextBroadcast(false); 11525 } 11526 trimApplications(); 11527 } finally { 11528 Binder.restoreCallingIdentity(origId); 11529 } 11530 } 11531 11532 // ========================================================= 11533 // INSTRUMENTATION 11534 // ========================================================= 11535 11536 public boolean startInstrumentation(ComponentName className, 11537 String profileFile, int flags, Bundle arguments, 11538 IInstrumentationWatcher watcher) { 11539 enforceNotIsolatedCaller("startInstrumentation"); 11540 // Refuse possible leaked file descriptors 11541 if (arguments != null && arguments.hasFileDescriptors()) { 11542 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11543 } 11544 11545 synchronized(this) { 11546 InstrumentationInfo ii = null; 11547 ApplicationInfo ai = null; 11548 try { 11549 ii = mContext.getPackageManager().getInstrumentationInfo( 11550 className, STOCK_PM_FLAGS); 11551 ai = mContext.getPackageManager().getApplicationInfo( 11552 ii.targetPackage, STOCK_PM_FLAGS); 11553 } catch (PackageManager.NameNotFoundException e) { 11554 } 11555 if (ii == null) { 11556 reportStartInstrumentationFailure(watcher, className, 11557 "Unable to find instrumentation info for: " + className); 11558 return false; 11559 } 11560 if (ai == null) { 11561 reportStartInstrumentationFailure(watcher, className, 11562 "Unable to find instrumentation target package: " + ii.targetPackage); 11563 return false; 11564 } 11565 11566 int match = mContext.getPackageManager().checkSignatures( 11567 ii.targetPackage, ii.packageName); 11568 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11569 String msg = "Permission Denial: starting instrumentation " 11570 + className + " from pid=" 11571 + Binder.getCallingPid() 11572 + ", uid=" + Binder.getCallingPid() 11573 + " not allowed because package " + ii.packageName 11574 + " does not have a signature matching the target " 11575 + ii.targetPackage; 11576 reportStartInstrumentationFailure(watcher, className, msg); 11577 throw new SecurityException(msg); 11578 } 11579 11580 int userId = UserHandle.getCallingUserId(); 11581 final long origId = Binder.clearCallingIdentity(); 11582 // Instrumentation can kill and relaunch even persistent processes 11583 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11584 ProcessRecord app = addAppLocked(ai, false); 11585 app.instrumentationClass = className; 11586 app.instrumentationInfo = ai; 11587 app.instrumentationProfileFile = profileFile; 11588 app.instrumentationArguments = arguments; 11589 app.instrumentationWatcher = watcher; 11590 app.instrumentationResultClass = className; 11591 Binder.restoreCallingIdentity(origId); 11592 } 11593 11594 return true; 11595 } 11596 11597 /** 11598 * Report errors that occur while attempting to start Instrumentation. Always writes the 11599 * error to the logs, but if somebody is watching, send the report there too. This enables 11600 * the "am" command to report errors with more information. 11601 * 11602 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11603 * @param cn The component name of the instrumentation. 11604 * @param report The error report. 11605 */ 11606 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11607 ComponentName cn, String report) { 11608 Slog.w(TAG, report); 11609 try { 11610 if (watcher != null) { 11611 Bundle results = new Bundle(); 11612 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11613 results.putString("Error", report); 11614 watcher.instrumentationStatus(cn, -1, results); 11615 } 11616 } catch (RemoteException e) { 11617 Slog.w(TAG, e); 11618 } 11619 } 11620 11621 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11622 if (app.instrumentationWatcher != null) { 11623 try { 11624 // NOTE: IInstrumentationWatcher *must* be oneway here 11625 app.instrumentationWatcher.instrumentationFinished( 11626 app.instrumentationClass, 11627 resultCode, 11628 results); 11629 } catch (RemoteException e) { 11630 } 11631 } 11632 app.instrumentationWatcher = null; 11633 app.instrumentationClass = null; 11634 app.instrumentationInfo = null; 11635 app.instrumentationProfileFile = null; 11636 app.instrumentationArguments = null; 11637 11638 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11639 } 11640 11641 public void finishInstrumentation(IApplicationThread target, 11642 int resultCode, Bundle results) { 11643 int userId = UserHandle.getCallingUserId(); 11644 // Refuse possible leaked file descriptors 11645 if (results != null && results.hasFileDescriptors()) { 11646 throw new IllegalArgumentException("File descriptors passed in Intent"); 11647 } 11648 11649 synchronized(this) { 11650 ProcessRecord app = getRecordForAppLocked(target); 11651 if (app == null) { 11652 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11653 return; 11654 } 11655 final long origId = Binder.clearCallingIdentity(); 11656 finishInstrumentationLocked(app, resultCode, results); 11657 Binder.restoreCallingIdentity(origId); 11658 } 11659 } 11660 11661 // ========================================================= 11662 // CONFIGURATION 11663 // ========================================================= 11664 11665 public ConfigurationInfo getDeviceConfigurationInfo() { 11666 ConfigurationInfo config = new ConfigurationInfo(); 11667 synchronized (this) { 11668 config.reqTouchScreen = mConfiguration.touchscreen; 11669 config.reqKeyboardType = mConfiguration.keyboard; 11670 config.reqNavigation = mConfiguration.navigation; 11671 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11672 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11673 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11674 } 11675 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11676 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11677 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11678 } 11679 config.reqGlEsVersion = GL_ES_VERSION; 11680 } 11681 return config; 11682 } 11683 11684 public Configuration getConfiguration() { 11685 Configuration ci; 11686 synchronized(this) { 11687 ci = new Configuration(mConfiguration); 11688 } 11689 return ci; 11690 } 11691 11692 public void updatePersistentConfiguration(Configuration values) { 11693 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11694 "updateConfiguration()"); 11695 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11696 "updateConfiguration()"); 11697 if (values == null) { 11698 throw new NullPointerException("Configuration must not be null"); 11699 } 11700 11701 synchronized(this) { 11702 final long origId = Binder.clearCallingIdentity(); 11703 updateConfigurationLocked(values, null, true, false); 11704 Binder.restoreCallingIdentity(origId); 11705 } 11706 } 11707 11708 public void updateConfiguration(Configuration values) { 11709 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11710 "updateConfiguration()"); 11711 11712 synchronized(this) { 11713 if (values == null && mWindowManager != null) { 11714 // sentinel: fetch the current configuration from the window manager 11715 values = mWindowManager.computeNewConfiguration(); 11716 } 11717 11718 if (mWindowManager != null) { 11719 mProcessList.applyDisplaySize(mWindowManager); 11720 } 11721 11722 final long origId = Binder.clearCallingIdentity(); 11723 if (values != null) { 11724 Settings.System.clearConfiguration(values); 11725 } 11726 updateConfigurationLocked(values, null, false, false); 11727 Binder.restoreCallingIdentity(origId); 11728 } 11729 } 11730 11731 /** 11732 * Do either or both things: (1) change the current configuration, and (2) 11733 * make sure the given activity is running with the (now) current 11734 * configuration. Returns true if the activity has been left running, or 11735 * false if <var>starting</var> is being destroyed to match the new 11736 * configuration. 11737 * @param persistent TODO 11738 */ 11739 boolean updateConfigurationLocked(Configuration values, 11740 ActivityRecord starting, boolean persistent, boolean initLocale) { 11741 // do nothing if we are headless 11742 if (mHeadless) return true; 11743 11744 int changes = 0; 11745 11746 boolean kept = true; 11747 11748 if (values != null) { 11749 Configuration newConfig = new Configuration(mConfiguration); 11750 changes = newConfig.updateFrom(values); 11751 if (changes != 0) { 11752 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11753 Slog.i(TAG, "Updating configuration to: " + values); 11754 } 11755 11756 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11757 11758 if (values.locale != null && !initLocale) { 11759 saveLocaleLocked(values.locale, 11760 !values.locale.equals(mConfiguration.locale), 11761 values.userSetLocale); 11762 } 11763 11764 mConfigurationSeq++; 11765 if (mConfigurationSeq <= 0) { 11766 mConfigurationSeq = 1; 11767 } 11768 newConfig.seq = mConfigurationSeq; 11769 mConfiguration = newConfig; 11770 Slog.i(TAG, "Config changed: " + newConfig); 11771 11772 final Configuration configCopy = new Configuration(mConfiguration); 11773 11774 // TODO: If our config changes, should we auto dismiss any currently 11775 // showing dialogs? 11776 mShowDialogs = shouldShowDialogs(newConfig); 11777 11778 AttributeCache ac = AttributeCache.instance(); 11779 if (ac != null) { 11780 ac.updateConfiguration(configCopy); 11781 } 11782 11783 // Make sure all resources in our process are updated 11784 // right now, so that anyone who is going to retrieve 11785 // resource values after we return will be sure to get 11786 // the new ones. This is especially important during 11787 // boot, where the first config change needs to guarantee 11788 // all resources have that config before following boot 11789 // code is executed. 11790 mSystemThread.applyConfigurationToResources(configCopy); 11791 11792 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11793 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11794 msg.obj = new Configuration(configCopy); 11795 mHandler.sendMessage(msg); 11796 } 11797 11798 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11799 ProcessRecord app = mLruProcesses.get(i); 11800 try { 11801 if (app.thread != null) { 11802 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11803 + app.processName + " new config " + mConfiguration); 11804 app.thread.scheduleConfigurationChanged(configCopy); 11805 } 11806 } catch (Exception e) { 11807 } 11808 } 11809 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11810 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11811 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11812 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11813 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11814 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11815 broadcastIntentLocked(null, null, 11816 new Intent(Intent.ACTION_LOCALE_CHANGED), 11817 null, null, 0, null, null, 11818 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11819 } 11820 } 11821 } 11822 11823 if (changes != 0 && starting == null) { 11824 // If the configuration changed, and the caller is not already 11825 // in the process of starting an activity, then find the top 11826 // activity to check if its configuration needs to change. 11827 starting = mMainStack.topRunningActivityLocked(null); 11828 } 11829 11830 if (starting != null) { 11831 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11832 // And we need to make sure at this point that all other activities 11833 // are made visible with the correct configuration. 11834 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11835 } 11836 11837 if (values != null && mWindowManager != null) { 11838 mWindowManager.setNewConfiguration(mConfiguration); 11839 } 11840 11841 return kept; 11842 } 11843 11844 /** 11845 * Decide based on the configuration whether we should shouw the ANR, 11846 * crash, etc dialogs. The idea is that if there is no affordnace to 11847 * press the on-screen buttons, we shouldn't show the dialog. 11848 * 11849 * A thought: SystemUI might also want to get told about this, the Power 11850 * dialog / global actions also might want different behaviors. 11851 */ 11852 private static final boolean shouldShowDialogs(Configuration config) { 11853 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11854 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11855 } 11856 11857 /** 11858 * Save the locale. You must be inside a synchronized (this) block. 11859 */ 11860 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11861 if(isDiff) { 11862 SystemProperties.set("user.language", l.getLanguage()); 11863 SystemProperties.set("user.region", l.getCountry()); 11864 } 11865 11866 if(isPersist) { 11867 SystemProperties.set("persist.sys.language", l.getLanguage()); 11868 SystemProperties.set("persist.sys.country", l.getCountry()); 11869 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11870 } 11871 } 11872 11873 @Override 11874 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11875 ActivityRecord srec = ActivityRecord.forToken(token); 11876 return srec != null && srec.task.affinity != null && 11877 srec.task.affinity.equals(destAffinity); 11878 } 11879 11880 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11881 Intent resultData) { 11882 ComponentName dest = destIntent.getComponent(); 11883 11884 synchronized (this) { 11885 ActivityRecord srec = ActivityRecord.forToken(token); 11886 if (srec == null) { 11887 return false; 11888 } 11889 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11890 final int start = history.indexOf(srec); 11891 if (start < 0) { 11892 // Current activity is not in history stack; do nothing. 11893 return false; 11894 } 11895 int finishTo = start - 1; 11896 ActivityRecord parent = null; 11897 boolean foundParentInTask = false; 11898 if (dest != null) { 11899 TaskRecord tr = srec.task; 11900 for (int i = start - 1; i >= 0; i--) { 11901 ActivityRecord r = history.get(i); 11902 if (tr != r.task) { 11903 // Couldn't find parent in the same task; stop at the one above this. 11904 // (Root of current task; in-app "home" behavior) 11905 // Always at least finish the current activity. 11906 finishTo = Math.min(start - 1, i + 1); 11907 parent = history.get(finishTo); 11908 break; 11909 } else if (r.info.packageName.equals(dest.getPackageName()) && 11910 r.info.name.equals(dest.getClassName())) { 11911 finishTo = i; 11912 parent = r; 11913 foundParentInTask = true; 11914 break; 11915 } 11916 } 11917 } 11918 11919 if (mController != null) { 11920 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11921 if (next != null) { 11922 // ask watcher if this is allowed 11923 boolean resumeOK = true; 11924 try { 11925 resumeOK = mController.activityResuming(next.packageName); 11926 } catch (RemoteException e) { 11927 mController = null; 11928 } 11929 11930 if (!resumeOK) { 11931 return false; 11932 } 11933 } 11934 } 11935 final long origId = Binder.clearCallingIdentity(); 11936 for (int i = start; i > finishTo; i--) { 11937 ActivityRecord r = history.get(i); 11938 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11939 "navigate-up"); 11940 // Only return the supplied result for the first activity finished 11941 resultCode = Activity.RESULT_CANCELED; 11942 resultData = null; 11943 } 11944 11945 if (parent != null && foundParentInTask) { 11946 final int parentLaunchMode = parent.info.launchMode; 11947 final int destIntentFlags = destIntent.getFlags(); 11948 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11949 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11950 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11951 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11952 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11953 } else { 11954 try { 11955 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11956 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 11957 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11958 null, aInfo, parent.appToken, null, 11959 0, -1, parent.launchedFromUid, 0, null, true, null); 11960 foundParentInTask = res == ActivityManager.START_SUCCESS; 11961 } catch (RemoteException e) { 11962 foundParentInTask = false; 11963 } 11964 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11965 resultData, "navigate-up"); 11966 } 11967 } 11968 Binder.restoreCallingIdentity(origId); 11969 return foundParentInTask; 11970 } 11971 } 11972 11973 public int getLaunchedFromUid(IBinder activityToken) { 11974 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11975 if (srec == null) { 11976 return -1; 11977 } 11978 return srec.launchedFromUid; 11979 } 11980 11981 // ========================================================= 11982 // LIFETIME MANAGEMENT 11983 // ========================================================= 11984 11985 // Returns which broadcast queue the app is the current [or imminent] receiver 11986 // on, or 'null' if the app is not an active broadcast recipient. 11987 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11988 BroadcastRecord r = app.curReceiver; 11989 if (r != null) { 11990 return r.queue; 11991 } 11992 11993 // It's not the current receiver, but it might be starting up to become one 11994 synchronized (this) { 11995 for (BroadcastQueue queue : mBroadcastQueues) { 11996 r = queue.mPendingBroadcast; 11997 if (r != null && r.curApp == app) { 11998 // found it; report which queue it's in 11999 return queue; 12000 } 12001 } 12002 } 12003 12004 return null; 12005 } 12006 12007 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12008 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12009 if (mAdjSeq == app.adjSeq) { 12010 // This adjustment has already been computed. If we are calling 12011 // from the top, we may have already computed our adjustment with 12012 // an earlier hidden adjustment that isn't really for us... if 12013 // so, use the new hidden adjustment. 12014 if (!recursed && app.hidden) { 12015 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12016 app.hasActivities ? hiddenAdj : emptyAdj; 12017 } 12018 return app.curRawAdj; 12019 } 12020 12021 if (app.thread == null) { 12022 app.adjSeq = mAdjSeq; 12023 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12024 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12025 } 12026 12027 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12028 app.adjSource = null; 12029 app.adjTarget = null; 12030 app.empty = false; 12031 app.hidden = false; 12032 12033 final int activitiesSize = app.activities.size(); 12034 12035 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12036 // The max adjustment doesn't allow this app to be anything 12037 // below foreground, so it is not worth doing work for it. 12038 app.adjType = "fixed"; 12039 app.adjSeq = mAdjSeq; 12040 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12041 app.hasActivities = false; 12042 app.foregroundActivities = false; 12043 app.keeping = true; 12044 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12045 // System process can do UI, and when they do we want to have 12046 // them trim their memory after the user leaves the UI. To 12047 // facilitate this, here we need to determine whether or not it 12048 // is currently showing UI. 12049 app.systemNoUi = true; 12050 if (app == TOP_APP) { 12051 app.systemNoUi = false; 12052 app.hasActivities = true; 12053 } else if (activitiesSize > 0) { 12054 for (int j = 0; j < activitiesSize; j++) { 12055 final ActivityRecord r = app.activities.get(j); 12056 if (r.visible) { 12057 app.systemNoUi = false; 12058 } 12059 if (r.app == app) { 12060 app.hasActivities = true; 12061 } 12062 } 12063 } 12064 return (app.curAdj=app.maxAdj); 12065 } 12066 12067 app.keeping = false; 12068 app.systemNoUi = false; 12069 app.hasActivities = false; 12070 12071 // Determine the importance of the process, starting with most 12072 // important to least, and assign an appropriate OOM adjustment. 12073 int adj; 12074 int schedGroup; 12075 boolean foregroundActivities = false; 12076 boolean interesting = false; 12077 BroadcastQueue queue; 12078 if (app == TOP_APP) { 12079 // The last app on the list is the foreground app. 12080 adj = ProcessList.FOREGROUND_APP_ADJ; 12081 schedGroup = Process.THREAD_GROUP_DEFAULT; 12082 app.adjType = "top-activity"; 12083 foregroundActivities = true; 12084 interesting = true; 12085 app.hasActivities = true; 12086 } else if (app.instrumentationClass != null) { 12087 // Don't want to kill running instrumentation. 12088 adj = ProcessList.FOREGROUND_APP_ADJ; 12089 schedGroup = Process.THREAD_GROUP_DEFAULT; 12090 app.adjType = "instrumentation"; 12091 interesting = true; 12092 } else if ((queue = isReceivingBroadcast(app)) != null) { 12093 // An app that is currently receiving a broadcast also 12094 // counts as being in the foreground for OOM killer purposes. 12095 // It's placed in a sched group based on the nature of the 12096 // broadcast as reflected by which queue it's active in. 12097 adj = ProcessList.FOREGROUND_APP_ADJ; 12098 schedGroup = (queue == mFgBroadcastQueue) 12099 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12100 app.adjType = "broadcast"; 12101 } else if (app.executingServices.size() > 0) { 12102 // An app that is currently executing a service callback also 12103 // counts as being in the foreground. 12104 adj = ProcessList.FOREGROUND_APP_ADJ; 12105 schedGroup = Process.THREAD_GROUP_DEFAULT; 12106 app.adjType = "exec-service"; 12107 } else { 12108 // Assume process is hidden (has activities); we will correct 12109 // later if this is not the case. 12110 adj = hiddenAdj; 12111 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12112 app.hidden = true; 12113 app.adjType = "bg-activities"; 12114 } 12115 12116 boolean hasStoppingActivities = false; 12117 12118 // Examine all activities if not already foreground. 12119 if (!foregroundActivities && activitiesSize > 0) { 12120 for (int j = 0; j < activitiesSize; j++) { 12121 final ActivityRecord r = app.activities.get(j); 12122 if (r.visible) { 12123 // App has a visible activity; only upgrade adjustment. 12124 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12125 adj = ProcessList.VISIBLE_APP_ADJ; 12126 app.adjType = "visible"; 12127 } 12128 schedGroup = Process.THREAD_GROUP_DEFAULT; 12129 app.hidden = false; 12130 app.hasActivities = true; 12131 foregroundActivities = true; 12132 break; 12133 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12134 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12135 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12136 app.adjType = "pausing"; 12137 } 12138 app.hidden = false; 12139 foregroundActivities = true; 12140 } else if (r.state == ActivityState.STOPPING) { 12141 // We will apply the actual adjustment later, because 12142 // we want to allow this process to immediately go through 12143 // any memory trimming that is in effect. 12144 app.hidden = false; 12145 foregroundActivities = true; 12146 hasStoppingActivities = true; 12147 } 12148 if (r.app == app) { 12149 app.hasActivities = true; 12150 } 12151 } 12152 } 12153 12154 if (adj == hiddenAdj && !app.hasActivities) { 12155 // Whoops, this process is completely empty as far as we know 12156 // at this point. 12157 adj = emptyAdj; 12158 app.empty = true; 12159 app.adjType = "bg-empty"; 12160 } 12161 12162 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12163 if (app.foregroundServices) { 12164 // The user is aware of this app, so make it visible. 12165 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12166 app.hidden = false; 12167 app.adjType = "foreground-service"; 12168 schedGroup = Process.THREAD_GROUP_DEFAULT; 12169 } else if (app.forcingToForeground != null) { 12170 // The user is aware of this app, so make it visible. 12171 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12172 app.hidden = false; 12173 app.adjType = "force-foreground"; 12174 app.adjSource = app.forcingToForeground; 12175 schedGroup = Process.THREAD_GROUP_DEFAULT; 12176 } 12177 } 12178 12179 if (app.foregroundServices) { 12180 interesting = true; 12181 } 12182 12183 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12184 // We don't want to kill the current heavy-weight process. 12185 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12186 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12187 app.hidden = false; 12188 app.adjType = "heavy"; 12189 } 12190 12191 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12192 // This process is hosting what we currently consider to be the 12193 // home app, so we don't want to let it go into the background. 12194 adj = ProcessList.HOME_APP_ADJ; 12195 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12196 app.hidden = false; 12197 app.adjType = "home"; 12198 } 12199 12200 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12201 && app.activities.size() > 0) { 12202 // This was the previous process that showed UI to the user. 12203 // We want to try to keep it around more aggressively, to give 12204 // a good experience around switching between two apps. 12205 adj = ProcessList.PREVIOUS_APP_ADJ; 12206 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12207 app.hidden = false; 12208 app.adjType = "previous"; 12209 } 12210 12211 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12212 + " reason=" + app.adjType); 12213 12214 // By default, we use the computed adjustment. It may be changed if 12215 // there are applications dependent on our services or providers, but 12216 // this gives us a baseline and makes sure we don't get into an 12217 // infinite recursion. 12218 app.adjSeq = mAdjSeq; 12219 app.curRawAdj = app.nonStoppingAdj = adj; 12220 12221 if (mBackupTarget != null && app == mBackupTarget.app) { 12222 // If possible we want to avoid killing apps while they're being backed up 12223 if (adj > ProcessList.BACKUP_APP_ADJ) { 12224 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12225 adj = ProcessList.BACKUP_APP_ADJ; 12226 app.adjType = "backup"; 12227 app.hidden = false; 12228 } 12229 } 12230 12231 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12232 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12233 final long now = SystemClock.uptimeMillis(); 12234 // This process is more important if the top activity is 12235 // bound to the service. 12236 Iterator<ServiceRecord> jt = app.services.iterator(); 12237 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12238 ServiceRecord s = jt.next(); 12239 if (s.startRequested) { 12240 if (app.hasShownUi && app != mHomeProcess) { 12241 // If this process has shown some UI, let it immediately 12242 // go to the LRU list because it may be pretty heavy with 12243 // UI stuff. We'll tag it with a label just to help 12244 // debug and understand what is going on. 12245 if (adj > ProcessList.SERVICE_ADJ) { 12246 app.adjType = "started-bg-ui-services"; 12247 } 12248 } else { 12249 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12250 // This service has seen some activity within 12251 // recent memory, so we will keep its process ahead 12252 // of the background processes. 12253 if (adj > ProcessList.SERVICE_ADJ) { 12254 adj = ProcessList.SERVICE_ADJ; 12255 app.adjType = "started-services"; 12256 app.hidden = false; 12257 } 12258 } 12259 // If we have let the service slide into the background 12260 // state, still have some text describing what it is doing 12261 // even though the service no longer has an impact. 12262 if (adj > ProcessList.SERVICE_ADJ) { 12263 app.adjType = "started-bg-services"; 12264 } 12265 } 12266 // Don't kill this process because it is doing work; it 12267 // has said it is doing work. 12268 app.keeping = true; 12269 } 12270 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12271 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12272 Iterator<ArrayList<ConnectionRecord>> kt 12273 = s.connections.values().iterator(); 12274 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12275 ArrayList<ConnectionRecord> clist = kt.next(); 12276 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12277 // XXX should compute this based on the max of 12278 // all connected clients. 12279 ConnectionRecord cr = clist.get(i); 12280 if (cr.binding.client == app) { 12281 // Binding to ourself is not interesting. 12282 continue; 12283 } 12284 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12285 ProcessRecord client = cr.binding.client; 12286 int clientAdj = adj; 12287 int myHiddenAdj = hiddenAdj; 12288 if (myHiddenAdj > client.hiddenAdj) { 12289 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12290 myHiddenAdj = client.hiddenAdj; 12291 } else { 12292 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12293 } 12294 } 12295 int myEmptyAdj = emptyAdj; 12296 if (myEmptyAdj > client.emptyAdj) { 12297 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12298 myEmptyAdj = client.emptyAdj; 12299 } else { 12300 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12301 } 12302 } 12303 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12304 myEmptyAdj, TOP_APP, true, doingAll); 12305 String adjType = null; 12306 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12307 // Not doing bind OOM management, so treat 12308 // this guy more like a started service. 12309 if (app.hasShownUi && app != mHomeProcess) { 12310 // If this process has shown some UI, let it immediately 12311 // go to the LRU list because it may be pretty heavy with 12312 // UI stuff. We'll tag it with a label just to help 12313 // debug and understand what is going on. 12314 if (adj > clientAdj) { 12315 adjType = "bound-bg-ui-services"; 12316 } 12317 app.hidden = false; 12318 clientAdj = adj; 12319 } else { 12320 if (now >= (s.lastActivity 12321 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12322 // This service has not seen activity within 12323 // recent memory, so allow it to drop to the 12324 // LRU list if there is no other reason to keep 12325 // it around. We'll also tag it with a label just 12326 // to help debug and undertand what is going on. 12327 if (adj > clientAdj) { 12328 adjType = "bound-bg-services"; 12329 } 12330 clientAdj = adj; 12331 } 12332 } 12333 } 12334 if (adj > clientAdj) { 12335 // If this process has recently shown UI, and 12336 // the process that is binding to it is less 12337 // important than being visible, then we don't 12338 // care about the binding as much as we care 12339 // about letting this process get into the LRU 12340 // list to be killed and restarted if needed for 12341 // memory. 12342 if (app.hasShownUi && app != mHomeProcess 12343 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12344 adjType = "bound-bg-ui-services"; 12345 } else { 12346 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12347 |Context.BIND_IMPORTANT)) != 0) { 12348 adj = clientAdj; 12349 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12350 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12351 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12352 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12353 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12354 adj = clientAdj; 12355 } else { 12356 app.pendingUiClean = true; 12357 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12358 adj = ProcessList.VISIBLE_APP_ADJ; 12359 } 12360 } 12361 if (!client.hidden) { 12362 app.hidden = false; 12363 } 12364 if (client.keeping) { 12365 app.keeping = true; 12366 } 12367 adjType = "service"; 12368 } 12369 } 12370 if (adjType != null) { 12371 app.adjType = adjType; 12372 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12373 .REASON_SERVICE_IN_USE; 12374 app.adjSource = cr.binding.client; 12375 app.adjSourceOom = clientAdj; 12376 app.adjTarget = s.name; 12377 } 12378 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12379 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12380 schedGroup = Process.THREAD_GROUP_DEFAULT; 12381 } 12382 } 12383 } 12384 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12385 ActivityRecord a = cr.activity; 12386 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12387 (a.visible || a.state == ActivityState.RESUMED 12388 || a.state == ActivityState.PAUSING)) { 12389 adj = ProcessList.FOREGROUND_APP_ADJ; 12390 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12391 schedGroup = Process.THREAD_GROUP_DEFAULT; 12392 } 12393 app.hidden = false; 12394 app.adjType = "service"; 12395 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12396 .REASON_SERVICE_IN_USE; 12397 app.adjSource = a; 12398 app.adjSourceOom = adj; 12399 app.adjTarget = s.name; 12400 } 12401 } 12402 } 12403 } 12404 } 12405 } 12406 12407 // Finally, if this process has active services running in it, we 12408 // would like to avoid killing it unless it would prevent the current 12409 // application from running. By default we put the process in 12410 // with the rest of the background processes; as we scan through 12411 // its services we may bump it up from there. 12412 if (adj > hiddenAdj) { 12413 adj = hiddenAdj; 12414 app.hidden = false; 12415 app.adjType = "bg-services"; 12416 } 12417 } 12418 12419 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12420 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12421 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12422 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12423 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12424 ContentProviderRecord cpr = jt.next(); 12425 for (int i = cpr.connections.size()-1; 12426 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12427 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12428 i--) { 12429 ContentProviderConnection conn = cpr.connections.get(i); 12430 ProcessRecord client = conn.client; 12431 if (client == app) { 12432 // Being our own client is not interesting. 12433 continue; 12434 } 12435 int myHiddenAdj = hiddenAdj; 12436 if (myHiddenAdj > client.hiddenAdj) { 12437 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12438 myHiddenAdj = client.hiddenAdj; 12439 } else { 12440 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12441 } 12442 } 12443 int myEmptyAdj = emptyAdj; 12444 if (myEmptyAdj > client.emptyAdj) { 12445 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12446 myEmptyAdj = client.emptyAdj; 12447 } else { 12448 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12449 } 12450 } 12451 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12452 myEmptyAdj, TOP_APP, true, doingAll); 12453 if (adj > clientAdj) { 12454 if (app.hasShownUi && app != mHomeProcess 12455 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12456 app.adjType = "bg-ui-provider"; 12457 } else { 12458 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12459 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12460 app.adjType = "provider"; 12461 } 12462 if (!client.hidden) { 12463 app.hidden = false; 12464 } 12465 if (client.keeping) { 12466 app.keeping = true; 12467 } 12468 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12469 .REASON_PROVIDER_IN_USE; 12470 app.adjSource = client; 12471 app.adjSourceOom = clientAdj; 12472 app.adjTarget = cpr.name; 12473 } 12474 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12475 schedGroup = Process.THREAD_GROUP_DEFAULT; 12476 } 12477 } 12478 // If the provider has external (non-framework) process 12479 // dependencies, ensure that its adjustment is at least 12480 // FOREGROUND_APP_ADJ. 12481 if (cpr.hasExternalProcessHandles()) { 12482 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12483 adj = ProcessList.FOREGROUND_APP_ADJ; 12484 schedGroup = Process.THREAD_GROUP_DEFAULT; 12485 app.hidden = false; 12486 app.keeping = true; 12487 app.adjType = "provider"; 12488 app.adjTarget = cpr.name; 12489 } 12490 } 12491 } 12492 } 12493 12494 if (adj == ProcessList.SERVICE_ADJ) { 12495 if (doingAll) { 12496 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12497 mNewNumServiceProcs++; 12498 } 12499 if (app.serviceb) { 12500 adj = ProcessList.SERVICE_B_ADJ; 12501 } 12502 } else { 12503 app.serviceb = false; 12504 } 12505 12506 app.nonStoppingAdj = adj; 12507 12508 if (hasStoppingActivities) { 12509 // Only upgrade adjustment. 12510 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12511 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12512 app.adjType = "stopping"; 12513 } 12514 } 12515 12516 app.curRawAdj = adj; 12517 12518 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12519 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12520 if (adj > app.maxAdj) { 12521 adj = app.maxAdj; 12522 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12523 schedGroup = Process.THREAD_GROUP_DEFAULT; 12524 } 12525 } 12526 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12527 app.keeping = true; 12528 } 12529 12530 if (app.hasAboveClient) { 12531 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12532 // then we need to drop its adjustment to be lower than the service's 12533 // in order to honor the request. We want to drop it by one adjustment 12534 // level... but there is special meaning applied to various levels so 12535 // we will skip some of them. 12536 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12537 // System process will not get dropped, ever 12538 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12539 adj = ProcessList.VISIBLE_APP_ADJ; 12540 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12541 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12542 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12543 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12544 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12545 adj++; 12546 } 12547 } 12548 12549 int importance = app.memImportance; 12550 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12551 app.curAdj = adj; 12552 app.curSchedGroup = schedGroup; 12553 if (!interesting) { 12554 // For this reporting, if there is not something explicitly 12555 // interesting in this process then we will push it to the 12556 // background importance. 12557 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12558 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12559 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12560 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12561 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12562 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12563 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12564 } else if (adj >= ProcessList.SERVICE_ADJ) { 12565 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12566 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12567 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12568 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12569 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12570 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12571 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12572 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12573 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12574 } else { 12575 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12576 } 12577 } 12578 12579 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12580 if (foregroundActivities != app.foregroundActivities) { 12581 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12582 } 12583 if (changes != 0) { 12584 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12585 app.memImportance = importance; 12586 app.foregroundActivities = foregroundActivities; 12587 int i = mPendingProcessChanges.size()-1; 12588 ProcessChangeItem item = null; 12589 while (i >= 0) { 12590 item = mPendingProcessChanges.get(i); 12591 if (item.pid == app.pid) { 12592 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12593 break; 12594 } 12595 i--; 12596 } 12597 if (i < 0) { 12598 // No existing item in pending changes; need a new one. 12599 final int NA = mAvailProcessChanges.size(); 12600 if (NA > 0) { 12601 item = mAvailProcessChanges.remove(NA-1); 12602 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12603 } else { 12604 item = new ProcessChangeItem(); 12605 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12606 } 12607 item.changes = 0; 12608 item.pid = app.pid; 12609 item.uid = app.info.uid; 12610 if (mPendingProcessChanges.size() == 0) { 12611 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12612 "*** Enqueueing dispatch processes changed!"); 12613 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12614 } 12615 mPendingProcessChanges.add(item); 12616 } 12617 item.changes |= changes; 12618 item.importance = importance; 12619 item.foregroundActivities = foregroundActivities; 12620 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12621 + Integer.toHexString(System.identityHashCode(item)) 12622 + " " + app.toShortString() + ": changes=" + item.changes 12623 + " importance=" + item.importance 12624 + " foreground=" + item.foregroundActivities 12625 + " type=" + app.adjType + " source=" + app.adjSource 12626 + " target=" + app.adjTarget); 12627 } 12628 12629 return app.curRawAdj; 12630 } 12631 12632 /** 12633 * Ask a given process to GC right now. 12634 */ 12635 final void performAppGcLocked(ProcessRecord app) { 12636 try { 12637 app.lastRequestedGc = SystemClock.uptimeMillis(); 12638 if (app.thread != null) { 12639 if (app.reportLowMemory) { 12640 app.reportLowMemory = false; 12641 app.thread.scheduleLowMemory(); 12642 } else { 12643 app.thread.processInBackground(); 12644 } 12645 } 12646 } catch (Exception e) { 12647 // whatever. 12648 } 12649 } 12650 12651 /** 12652 * Returns true if things are idle enough to perform GCs. 12653 */ 12654 private final boolean canGcNowLocked() { 12655 boolean processingBroadcasts = false; 12656 for (BroadcastQueue q : mBroadcastQueues) { 12657 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12658 processingBroadcasts = true; 12659 } 12660 } 12661 return !processingBroadcasts 12662 && (mSleeping || (mMainStack.mResumedActivity != null && 12663 mMainStack.mResumedActivity.idle)); 12664 } 12665 12666 /** 12667 * Perform GCs on all processes that are waiting for it, but only 12668 * if things are idle. 12669 */ 12670 final void performAppGcsLocked() { 12671 final int N = mProcessesToGc.size(); 12672 if (N <= 0) { 12673 return; 12674 } 12675 if (canGcNowLocked()) { 12676 while (mProcessesToGc.size() > 0) { 12677 ProcessRecord proc = mProcessesToGc.remove(0); 12678 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12679 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12680 <= SystemClock.uptimeMillis()) { 12681 // To avoid spamming the system, we will GC processes one 12682 // at a time, waiting a few seconds between each. 12683 performAppGcLocked(proc); 12684 scheduleAppGcsLocked(); 12685 return; 12686 } else { 12687 // It hasn't been long enough since we last GCed this 12688 // process... put it in the list to wait for its time. 12689 addProcessToGcListLocked(proc); 12690 break; 12691 } 12692 } 12693 } 12694 12695 scheduleAppGcsLocked(); 12696 } 12697 } 12698 12699 /** 12700 * If all looks good, perform GCs on all processes waiting for them. 12701 */ 12702 final void performAppGcsIfAppropriateLocked() { 12703 if (canGcNowLocked()) { 12704 performAppGcsLocked(); 12705 return; 12706 } 12707 // Still not idle, wait some more. 12708 scheduleAppGcsLocked(); 12709 } 12710 12711 /** 12712 * Schedule the execution of all pending app GCs. 12713 */ 12714 final void scheduleAppGcsLocked() { 12715 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12716 12717 if (mProcessesToGc.size() > 0) { 12718 // Schedule a GC for the time to the next process. 12719 ProcessRecord proc = mProcessesToGc.get(0); 12720 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12721 12722 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12723 long now = SystemClock.uptimeMillis(); 12724 if (when < (now+GC_TIMEOUT)) { 12725 when = now + GC_TIMEOUT; 12726 } 12727 mHandler.sendMessageAtTime(msg, when); 12728 } 12729 } 12730 12731 /** 12732 * Add a process to the array of processes waiting to be GCed. Keeps the 12733 * list in sorted order by the last GC time. The process can't already be 12734 * on the list. 12735 */ 12736 final void addProcessToGcListLocked(ProcessRecord proc) { 12737 boolean added = false; 12738 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12739 if (mProcessesToGc.get(i).lastRequestedGc < 12740 proc.lastRequestedGc) { 12741 added = true; 12742 mProcessesToGc.add(i+1, proc); 12743 break; 12744 } 12745 } 12746 if (!added) { 12747 mProcessesToGc.add(0, proc); 12748 } 12749 } 12750 12751 /** 12752 * Set up to ask a process to GC itself. This will either do it 12753 * immediately, or put it on the list of processes to gc the next 12754 * time things are idle. 12755 */ 12756 final void scheduleAppGcLocked(ProcessRecord app) { 12757 long now = SystemClock.uptimeMillis(); 12758 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12759 return; 12760 } 12761 if (!mProcessesToGc.contains(app)) { 12762 addProcessToGcListLocked(app); 12763 scheduleAppGcsLocked(); 12764 } 12765 } 12766 12767 final void checkExcessivePowerUsageLocked(boolean doKills) { 12768 updateCpuStatsNow(); 12769 12770 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12771 boolean doWakeKills = doKills; 12772 boolean doCpuKills = doKills; 12773 if (mLastPowerCheckRealtime == 0) { 12774 doWakeKills = false; 12775 } 12776 if (mLastPowerCheckUptime == 0) { 12777 doCpuKills = false; 12778 } 12779 if (stats.isScreenOn()) { 12780 doWakeKills = false; 12781 } 12782 final long curRealtime = SystemClock.elapsedRealtime(); 12783 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12784 final long curUptime = SystemClock.uptimeMillis(); 12785 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12786 mLastPowerCheckRealtime = curRealtime; 12787 mLastPowerCheckUptime = curUptime; 12788 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12789 doWakeKills = false; 12790 } 12791 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12792 doCpuKills = false; 12793 } 12794 int i = mLruProcesses.size(); 12795 while (i > 0) { 12796 i--; 12797 ProcessRecord app = mLruProcesses.get(i); 12798 if (!app.keeping) { 12799 long wtime; 12800 synchronized (stats) { 12801 wtime = stats.getProcessWakeTime(app.info.uid, 12802 app.pid, curRealtime); 12803 } 12804 long wtimeUsed = wtime - app.lastWakeTime; 12805 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12806 if (DEBUG_POWER) { 12807 StringBuilder sb = new StringBuilder(128); 12808 sb.append("Wake for "); 12809 app.toShortString(sb); 12810 sb.append(": over "); 12811 TimeUtils.formatDuration(realtimeSince, sb); 12812 sb.append(" used "); 12813 TimeUtils.formatDuration(wtimeUsed, sb); 12814 sb.append(" ("); 12815 sb.append((wtimeUsed*100)/realtimeSince); 12816 sb.append("%)"); 12817 Slog.i(TAG, sb.toString()); 12818 sb.setLength(0); 12819 sb.append("CPU for "); 12820 app.toShortString(sb); 12821 sb.append(": over "); 12822 TimeUtils.formatDuration(uptimeSince, sb); 12823 sb.append(" used "); 12824 TimeUtils.formatDuration(cputimeUsed, sb); 12825 sb.append(" ("); 12826 sb.append((cputimeUsed*100)/uptimeSince); 12827 sb.append("%)"); 12828 Slog.i(TAG, sb.toString()); 12829 } 12830 // If a process has held a wake lock for more 12831 // than 50% of the time during this period, 12832 // that sounds bad. Kill! 12833 if (doWakeKills && realtimeSince > 0 12834 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12835 synchronized (stats) { 12836 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12837 realtimeSince, wtimeUsed); 12838 } 12839 Slog.w(TAG, "Excessive wake lock in " + app.processName 12840 + " (pid " + app.pid + "): held " + wtimeUsed 12841 + " during " + realtimeSince); 12842 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12843 app.processName, app.setAdj, "excessive wake lock"); 12844 Process.killProcessQuiet(app.pid); 12845 } else if (doCpuKills && uptimeSince > 0 12846 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12847 synchronized (stats) { 12848 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12849 uptimeSince, cputimeUsed); 12850 } 12851 Slog.w(TAG, "Excessive CPU in " + app.processName 12852 + " (pid " + app.pid + "): used " + cputimeUsed 12853 + " during " + uptimeSince); 12854 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12855 app.processName, app.setAdj, "excessive cpu"); 12856 Process.killProcessQuiet(app.pid); 12857 } else { 12858 app.lastWakeTime = wtime; 12859 app.lastCpuTime = app.curCpuTime; 12860 } 12861 } 12862 } 12863 } 12864 12865 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12866 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12867 app.hiddenAdj = hiddenAdj; 12868 app.emptyAdj = emptyAdj; 12869 12870 if (app.thread == null) { 12871 return false; 12872 } 12873 12874 final boolean wasKeeping = app.keeping; 12875 12876 boolean success = true; 12877 12878 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12879 12880 if (app.curRawAdj != app.setRawAdj) { 12881 if (wasKeeping && !app.keeping) { 12882 // This app is no longer something we want to keep. Note 12883 // its current wake lock time to later know to kill it if 12884 // it is not behaving well. 12885 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12886 synchronized (stats) { 12887 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12888 app.pid, SystemClock.elapsedRealtime()); 12889 } 12890 app.lastCpuTime = app.curCpuTime; 12891 } 12892 12893 app.setRawAdj = app.curRawAdj; 12894 } 12895 12896 if (app.curAdj != app.setAdj) { 12897 if (Process.setOomAdj(app.pid, app.curAdj)) { 12898 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12899 TAG, "Set " + app.pid + " " + app.processName + 12900 " adj " + app.curAdj + ": " + app.adjType); 12901 app.setAdj = app.curAdj; 12902 } else { 12903 success = false; 12904 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12905 } 12906 } 12907 if (app.setSchedGroup != app.curSchedGroup) { 12908 app.setSchedGroup = app.curSchedGroup; 12909 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12910 "Setting process group of " + app.processName 12911 + " to " + app.curSchedGroup); 12912 if (app.waitingToKill != null && 12913 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12914 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12915 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12916 app.processName, app.setAdj, app.waitingToKill); 12917 app.killedBackground = true; 12918 Process.killProcessQuiet(app.pid); 12919 success = false; 12920 } else { 12921 if (true) { 12922 long oldId = Binder.clearCallingIdentity(); 12923 try { 12924 Process.setProcessGroup(app.pid, app.curSchedGroup); 12925 } catch (Exception e) { 12926 Slog.w(TAG, "Failed setting process group of " + app.pid 12927 + " to " + app.curSchedGroup); 12928 e.printStackTrace(); 12929 } finally { 12930 Binder.restoreCallingIdentity(oldId); 12931 } 12932 } else { 12933 if (app.thread != null) { 12934 try { 12935 app.thread.setSchedulingGroup(app.curSchedGroup); 12936 } catch (RemoteException e) { 12937 } 12938 } 12939 } 12940 } 12941 } 12942 return success; 12943 } 12944 12945 private final ActivityRecord resumedAppLocked() { 12946 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12947 if (resumedActivity == null || resumedActivity.app == null) { 12948 resumedActivity = mMainStack.mPausingActivity; 12949 if (resumedActivity == null || resumedActivity.app == null) { 12950 resumedActivity = mMainStack.topRunningActivityLocked(null); 12951 } 12952 } 12953 return resumedActivity; 12954 } 12955 12956 final boolean updateOomAdjLocked(ProcessRecord app) { 12957 final ActivityRecord TOP_ACT = resumedAppLocked(); 12958 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12959 int curAdj = app.curAdj; 12960 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12961 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12962 12963 mAdjSeq++; 12964 12965 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 12966 TOP_APP, false); 12967 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12968 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12969 if (nowHidden != wasHidden) { 12970 // Changed to/from hidden state, so apps after it in the LRU 12971 // list may also be changed. 12972 updateOomAdjLocked(); 12973 } 12974 return success; 12975 } 12976 12977 final void updateOomAdjLocked() { 12978 final ActivityRecord TOP_ACT = resumedAppLocked(); 12979 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12980 12981 if (false) { 12982 RuntimeException e = new RuntimeException(); 12983 e.fillInStackTrace(); 12984 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12985 } 12986 12987 mAdjSeq++; 12988 mNewNumServiceProcs = 0; 12989 12990 // Let's determine how many processes we have running vs. 12991 // how many slots we have for background processes; we may want 12992 // to put multiple processes in a slot of there are enough of 12993 // them. 12994 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 12995 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 12996 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 12997 if (emptyFactor < 1) emptyFactor = 1; 12998 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 12999 if (hiddenFactor < 1) hiddenFactor = 1; 13000 int stepHidden = 0; 13001 int stepEmpty = 0; 13002 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13003 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13004 int numHidden = 0; 13005 int numEmpty = 0; 13006 int numTrimming = 0; 13007 13008 mNumNonHiddenProcs = 0; 13009 mNumHiddenProcs = 0; 13010 13011 // First update the OOM adjustment for each of the 13012 // application processes based on their current state. 13013 int i = mLruProcesses.size(); 13014 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13015 int nextHiddenAdj = curHiddenAdj+1; 13016 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13017 int nextEmptyAdj = curEmptyAdj+2; 13018 while (i > 0) { 13019 i--; 13020 ProcessRecord app = mLruProcesses.get(i); 13021 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13022 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13023 if (!app.killedBackground) { 13024 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13025 // This process was assigned as a hidden process... step the 13026 // hidden level. 13027 mNumHiddenProcs++; 13028 if (curHiddenAdj != nextHiddenAdj) { 13029 stepHidden++; 13030 if (stepHidden >= hiddenFactor) { 13031 stepHidden = 0; 13032 curHiddenAdj = nextHiddenAdj; 13033 nextHiddenAdj += 2; 13034 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13035 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13036 } 13037 } 13038 } 13039 numHidden++; 13040 if (numHidden > hiddenProcessLimit) { 13041 Slog.i(TAG, "No longer want " + app.processName 13042 + " (pid " + app.pid + "): hidden #" + numHidden); 13043 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13044 app.processName, app.setAdj, "too many background"); 13045 app.killedBackground = true; 13046 Process.killProcessQuiet(app.pid); 13047 } 13048 } else { 13049 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13050 // This process was assigned as an empty process... step the 13051 // empty level. 13052 if (curEmptyAdj != nextEmptyAdj) { 13053 stepEmpty++; 13054 if (stepEmpty >= emptyFactor) { 13055 stepEmpty = 0; 13056 curEmptyAdj = nextEmptyAdj; 13057 nextEmptyAdj += 2; 13058 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13059 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13060 } 13061 } 13062 } 13063 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13064 mNumNonHiddenProcs++; 13065 } 13066 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13067 numEmpty++; 13068 if (numEmpty > emptyProcessLimit) { 13069 Slog.i(TAG, "No longer want " + app.processName 13070 + " (pid " + app.pid + "): empty #" + numEmpty); 13071 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13072 app.processName, app.setAdj, "too many background"); 13073 app.killedBackground = true; 13074 Process.killProcessQuiet(app.pid); 13075 } 13076 } 13077 } 13078 if (app.isolated && app.services.size() <= 0) { 13079 // If this is an isolated process, and there are no 13080 // services running in it, then the process is no longer 13081 // needed. We agressively kill these because we can by 13082 // definition not re-use the same process again, and it is 13083 // good to avoid having whatever code was running in them 13084 // left sitting around after no longer needed. 13085 Slog.i(TAG, "Isolated process " + app.processName 13086 + " (pid " + app.pid + ") no longer needed"); 13087 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13088 app.processName, app.setAdj, "isolated not needed"); 13089 app.killedBackground = true; 13090 Process.killProcessQuiet(app.pid); 13091 } 13092 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13093 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13094 && !app.killedBackground) { 13095 numTrimming++; 13096 } 13097 } 13098 } 13099 13100 mNumServiceProcs = mNewNumServiceProcs; 13101 13102 // Now determine the memory trimming level of background processes. 13103 // Unfortunately we need to start at the back of the list to do this 13104 // properly. We only do this if the number of background apps we 13105 // are managing to keep around is less than half the maximum we desire; 13106 // if we are keeping a good number around, we'll let them use whatever 13107 // memory they want. 13108 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13109 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13110 final int numHiddenAndEmpty = numHidden + numEmpty; 13111 final int N = mLruProcesses.size(); 13112 int factor = numTrimming/3; 13113 int minFactor = 2; 13114 if (mHomeProcess != null) minFactor++; 13115 if (mPreviousProcess != null) minFactor++; 13116 if (factor < minFactor) factor = minFactor; 13117 int step = 0; 13118 int fgTrimLevel; 13119 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13120 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13121 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13122 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13123 } else { 13124 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13125 } 13126 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13127 for (i=0; i<N; i++) { 13128 ProcessRecord app = mLruProcesses.get(i); 13129 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13130 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13131 && !app.killedBackground) { 13132 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13133 try { 13134 app.thread.scheduleTrimMemory(curLevel); 13135 } catch (RemoteException e) { 13136 } 13137 if (false) { 13138 // For now we won't do this; our memory trimming seems 13139 // to be good enough at this point that destroying 13140 // activities causes more harm than good. 13141 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13142 && app != mHomeProcess && app != mPreviousProcess) { 13143 // Need to do this on its own message because the stack may not 13144 // be in a consistent state at this point. 13145 // For these apps we will also finish their activities 13146 // to help them free memory. 13147 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13148 } 13149 } 13150 } 13151 app.trimMemoryLevel = curLevel; 13152 step++; 13153 if (step >= factor) { 13154 step = 0; 13155 switch (curLevel) { 13156 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13157 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13158 break; 13159 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13160 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13161 break; 13162 } 13163 } 13164 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13165 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13166 && app.thread != null) { 13167 try { 13168 app.thread.scheduleTrimMemory( 13169 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13170 } catch (RemoteException e) { 13171 } 13172 } 13173 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13174 } else { 13175 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13176 && app.pendingUiClean) { 13177 // If this application is now in the background and it 13178 // had done UI, then give it the special trim level to 13179 // have it free UI resources. 13180 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13181 if (app.trimMemoryLevel < level && app.thread != null) { 13182 try { 13183 app.thread.scheduleTrimMemory(level); 13184 } catch (RemoteException e) { 13185 } 13186 } 13187 app.pendingUiClean = false; 13188 } 13189 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13190 try { 13191 app.thread.scheduleTrimMemory(fgTrimLevel); 13192 } catch (RemoteException e) { 13193 } 13194 } 13195 app.trimMemoryLevel = fgTrimLevel; 13196 } 13197 } 13198 } else { 13199 final int N = mLruProcesses.size(); 13200 for (i=0; i<N; i++) { 13201 ProcessRecord app = mLruProcesses.get(i); 13202 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13203 && app.pendingUiClean) { 13204 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13205 && app.thread != null) { 13206 try { 13207 app.thread.scheduleTrimMemory( 13208 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13209 } catch (RemoteException e) { 13210 } 13211 } 13212 app.pendingUiClean = false; 13213 } 13214 app.trimMemoryLevel = 0; 13215 } 13216 } 13217 13218 if (mAlwaysFinishActivities) { 13219 // Need to do this on its own message because the stack may not 13220 // be in a consistent state at this point. 13221 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13222 } 13223 } 13224 13225 final void trimApplications() { 13226 synchronized (this) { 13227 int i; 13228 13229 // First remove any unused application processes whose package 13230 // has been removed. 13231 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13232 final ProcessRecord app = mRemovedProcesses.get(i); 13233 if (app.activities.size() == 0 13234 && app.curReceiver == null && app.services.size() == 0) { 13235 Slog.i( 13236 TAG, "Exiting empty application process " 13237 + app.processName + " (" 13238 + (app.thread != null ? app.thread.asBinder() : null) 13239 + ")\n"); 13240 if (app.pid > 0 && app.pid != MY_PID) { 13241 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13242 app.processName, app.setAdj, "empty"); 13243 Process.killProcessQuiet(app.pid); 13244 } else { 13245 try { 13246 app.thread.scheduleExit(); 13247 } catch (Exception e) { 13248 // Ignore exceptions. 13249 } 13250 } 13251 cleanUpApplicationRecordLocked(app, false, true, -1); 13252 mRemovedProcesses.remove(i); 13253 13254 if (app.persistent) { 13255 if (app.persistent) { 13256 addAppLocked(app.info, false); 13257 } 13258 } 13259 } 13260 } 13261 13262 // Now update the oom adj for all processes. 13263 updateOomAdjLocked(); 13264 } 13265 } 13266 13267 /** This method sends the specified signal to each of the persistent apps */ 13268 public void signalPersistentProcesses(int sig) throws RemoteException { 13269 if (sig != Process.SIGNAL_USR1) { 13270 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13271 } 13272 13273 synchronized (this) { 13274 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13275 != PackageManager.PERMISSION_GRANTED) { 13276 throw new SecurityException("Requires permission " 13277 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13278 } 13279 13280 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13281 ProcessRecord r = mLruProcesses.get(i); 13282 if (r.thread != null && r.persistent) { 13283 Process.sendSignal(r.pid, sig); 13284 } 13285 } 13286 } 13287 } 13288 13289 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13290 if (proc == null || proc == mProfileProc) { 13291 proc = mProfileProc; 13292 path = mProfileFile; 13293 profileType = mProfileType; 13294 clearProfilerLocked(); 13295 } 13296 if (proc == null) { 13297 return; 13298 } 13299 try { 13300 proc.thread.profilerControl(false, path, null, profileType); 13301 } catch (RemoteException e) { 13302 throw new IllegalStateException("Process disappeared"); 13303 } 13304 } 13305 13306 private void clearProfilerLocked() { 13307 if (mProfileFd != null) { 13308 try { 13309 mProfileFd.close(); 13310 } catch (IOException e) { 13311 } 13312 } 13313 mProfileApp = null; 13314 mProfileProc = null; 13315 mProfileFile = null; 13316 mProfileType = 0; 13317 mAutoStopProfiler = false; 13318 } 13319 13320 public boolean profileControl(String process, boolean start, 13321 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13322 13323 try { 13324 synchronized (this) { 13325 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13326 // its own permission. 13327 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13328 != PackageManager.PERMISSION_GRANTED) { 13329 throw new SecurityException("Requires permission " 13330 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13331 } 13332 13333 if (start && fd == null) { 13334 throw new IllegalArgumentException("null fd"); 13335 } 13336 13337 ProcessRecord proc = null; 13338 if (process != null) { 13339 try { 13340 int pid = Integer.parseInt(process); 13341 synchronized (mPidsSelfLocked) { 13342 proc = mPidsSelfLocked.get(pid); 13343 } 13344 } catch (NumberFormatException e) { 13345 } 13346 13347 if (proc == null) { 13348 HashMap<String, SparseArray<ProcessRecord>> all 13349 = mProcessNames.getMap(); 13350 SparseArray<ProcessRecord> procs = all.get(process); 13351 if (procs != null && procs.size() > 0) { 13352 proc = procs.valueAt(0); 13353 } 13354 } 13355 } 13356 13357 if (start && (proc == null || proc.thread == null)) { 13358 throw new IllegalArgumentException("Unknown process: " + process); 13359 } 13360 13361 if (start) { 13362 stopProfilerLocked(null, null, 0); 13363 setProfileApp(proc.info, proc.processName, path, fd, false); 13364 mProfileProc = proc; 13365 mProfileType = profileType; 13366 try { 13367 fd = fd.dup(); 13368 } catch (IOException e) { 13369 fd = null; 13370 } 13371 proc.thread.profilerControl(start, path, fd, profileType); 13372 fd = null; 13373 mProfileFd = null; 13374 } else { 13375 stopProfilerLocked(proc, path, profileType); 13376 if (fd != null) { 13377 try { 13378 fd.close(); 13379 } catch (IOException e) { 13380 } 13381 } 13382 } 13383 13384 return true; 13385 } 13386 } catch (RemoteException e) { 13387 throw new IllegalStateException("Process disappeared"); 13388 } finally { 13389 if (fd != null) { 13390 try { 13391 fd.close(); 13392 } catch (IOException e) { 13393 } 13394 } 13395 } 13396 } 13397 13398 public boolean dumpHeap(String process, boolean managed, 13399 String path, ParcelFileDescriptor fd) throws RemoteException { 13400 13401 try { 13402 synchronized (this) { 13403 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13404 // its own permission (same as profileControl). 13405 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13406 != PackageManager.PERMISSION_GRANTED) { 13407 throw new SecurityException("Requires permission " 13408 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13409 } 13410 13411 if (fd == null) { 13412 throw new IllegalArgumentException("null fd"); 13413 } 13414 13415 ProcessRecord proc = null; 13416 try { 13417 int pid = Integer.parseInt(process); 13418 synchronized (mPidsSelfLocked) { 13419 proc = mPidsSelfLocked.get(pid); 13420 } 13421 } catch (NumberFormatException e) { 13422 } 13423 13424 if (proc == null) { 13425 HashMap<String, SparseArray<ProcessRecord>> all 13426 = mProcessNames.getMap(); 13427 SparseArray<ProcessRecord> procs = all.get(process); 13428 if (procs != null && procs.size() > 0) { 13429 proc = procs.valueAt(0); 13430 } 13431 } 13432 13433 if (proc == null || proc.thread == null) { 13434 throw new IllegalArgumentException("Unknown process: " + process); 13435 } 13436 13437 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13438 if (!isDebuggable) { 13439 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13440 throw new SecurityException("Process not debuggable: " + proc); 13441 } 13442 } 13443 13444 proc.thread.dumpHeap(managed, path, fd); 13445 fd = null; 13446 return true; 13447 } 13448 } catch (RemoteException e) { 13449 throw new IllegalStateException("Process disappeared"); 13450 } finally { 13451 if (fd != null) { 13452 try { 13453 fd.close(); 13454 } catch (IOException e) { 13455 } 13456 } 13457 } 13458 } 13459 13460 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13461 public void monitor() { 13462 synchronized (this) { } 13463 } 13464 13465 void onCoreSettingsChange(Bundle settings) { 13466 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13467 ProcessRecord processRecord = mLruProcesses.get(i); 13468 try { 13469 if (processRecord.thread != null) { 13470 processRecord.thread.setCoreSettings(settings); 13471 } 13472 } catch (RemoteException re) { 13473 /* ignore */ 13474 } 13475 } 13476 } 13477 13478 // Multi-user methods 13479 13480 public boolean switchUser(int userId) { 13481 final int callingUid = Binder.getCallingUid(); 13482 if (callingUid != 0 && callingUid != Process.myUid()) { 13483 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13484 return false; 13485 } 13486 if (mCurrentUserId == userId) 13487 return true; 13488 13489 synchronized (this) { 13490 // Check if user is already logged in, otherwise check if user exists first before 13491 // adding to the list of logged in users. 13492 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13493 if (!userExists(userId)) { 13494 return false; 13495 } 13496 mLoggedInUsers.append(userId, userId); 13497 } 13498 13499 mCurrentUserId = userId; 13500 boolean haveActivities = mMainStack.switchUser(userId); 13501 if (!haveActivities) { 13502 startHomeActivityLocked(userId); 13503 } 13504 13505 } 13506 13507 // Inform of user switch 13508 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13509 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13510 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); 13511 13512 return true; 13513 } 13514 13515 @Override 13516 public UserInfo getCurrentUser() throws RemoteException { 13517 final int callingUid = Binder.getCallingUid(); 13518 if (callingUid != 0 && callingUid != Process.myUid()) { 13519 Slog.e(TAG, "Trying to get user from unauthorized app"); 13520 return null; 13521 } 13522 return getUserManager().getUserInfo(mCurrentUserId); 13523 } 13524 13525 private void onUserRemoved(Intent intent) { 13526 int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 13527 if (extraUserId < 1) return; 13528 13529 // Kill all the processes for the user 13530 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13531 synchronized (this) { 13532 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13533 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13534 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13535 for (int i = 0; i < uids.size(); i++) { 13536 if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) { 13537 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13538 } 13539 } 13540 } 13541 13542 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13543 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13544 false, false, true, true, extraUserId); 13545 } 13546 } 13547 } 13548 13549 private boolean userExists(int userId) { 13550 UserInfo user = getUserManager().getUserInfo(userId); 13551 return user != null; 13552 } 13553 13554 UserManager getUserManager() { 13555 if (mUserManager == null) { 13556 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13557 } 13558 return mUserManager; 13559 } 13560 13561 private void checkValidCaller(int uid, int userId) { 13562 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13563 13564 throw new SecurityException("Caller uid=" + uid 13565 + " is not privileged to communicate with user=" + userId); 13566 } 13567 13568 private int applyUserId(int uid, int userId) { 13569 return UserHandle.getUid(userId, uid); 13570 } 13571 13572 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13573 if (info == null) return null; 13574 ApplicationInfo newInfo = new ApplicationInfo(info); 13575 newInfo.uid = applyUserId(info.uid, userId); 13576 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13577 + info.packageName; 13578 return newInfo; 13579 } 13580 13581 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13582 if (aInfo == null 13583 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13584 return aInfo; 13585 } 13586 13587 ActivityInfo info = new ActivityInfo(aInfo); 13588 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13589 return info; 13590 } 13591} 13592