ActivityManagerService.java revision 8264408f5995534f8e3147b001664ea0df52aaa5
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.Service; 55import android.app.backup.IBackupManager; 56import android.content.ActivityNotFoundException; 57import android.content.BroadcastReceiver; 58import android.content.ClipData; 59import android.content.ComponentCallbacks2; 60import android.content.ComponentName; 61import android.content.ContentProvider; 62import android.content.ContentResolver; 63import android.content.Context; 64import android.content.DialogInterface; 65import android.content.IContentProvider; 66import android.content.IIntentReceiver; 67import android.content.IIntentSender; 68import android.content.Intent; 69import android.content.IntentFilter; 70import android.content.IntentSender; 71import android.content.pm.ActivityInfo; 72import android.content.pm.ApplicationInfo; 73import android.content.pm.ConfigurationInfo; 74import android.content.pm.IPackageDataObserver; 75import android.content.pm.IPackageManager; 76import android.content.pm.InstrumentationInfo; 77import android.content.pm.PackageInfo; 78import android.content.pm.PackageManager; 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.pm.UserInfo; 85import android.content.res.CompatibilityInfo; 86import android.content.res.Configuration; 87import android.graphics.Bitmap; 88import android.net.Proxy; 89import android.net.ProxyProperties; 90import android.net.Uri; 91import android.os.Binder; 92import android.os.Build; 93import android.os.Bundle; 94import android.os.Debug; 95import android.os.DropBoxManager; 96import android.os.Environment; 97import android.os.FileObserver; 98import android.os.FileUtils; 99import android.os.Handler; 100import android.os.IBinder; 101import android.os.IPermissionController; 102import android.os.Looper; 103import android.os.Message; 104import android.os.Parcel; 105import android.os.ParcelFileDescriptor; 106import android.os.Process; 107import android.os.RemoteCallbackList; 108import android.os.RemoteException; 109import android.os.ServiceManager; 110import android.os.StrictMode; 111import android.os.SystemClock; 112import android.os.SystemProperties; 113import android.os.UserId; 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.Collection; 147import java.util.Collections; 148import java.util.Comparator; 149import java.util.HashMap; 150import java.util.HashSet; 151import java.util.Iterator; 152import java.util.List; 153import java.util.Locale; 154import java.util.Map; 155import java.util.Map.Entry; 156import java.util.Set; 157import java.util.concurrent.atomic.AtomicBoolean; 158import java.util.concurrent.atomic.AtomicLong; 159 160public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 162 private static final String USER_DATA_DIR = "/data/user/"; 163 static final String TAG = "ActivityManager"; 164 static final String TAG_MU = "ActivityManagerServiceMU"; 165 static final boolean DEBUG = false; 166 static final boolean localLOGV = DEBUG; 167 static final boolean DEBUG_SWITCH = localLOGV || false; 168 static final boolean DEBUG_TASKS = localLOGV || false; 169 static final boolean DEBUG_PAUSE = localLOGV || false; 170 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 171 static final boolean DEBUG_TRANSITION = localLOGV || false; 172 static final boolean DEBUG_BROADCAST = localLOGV || false; 173 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_SERVICE = localLOGV || false; 176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 177 static final boolean DEBUG_VISBILITY = localLOGV || false; 178 static final boolean DEBUG_PROCESSES = localLOGV || false; 179 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 180 static final boolean DEBUG_PROVIDER = localLOGV || false; 181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 182 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 183 static final boolean DEBUG_RESULTS = localLOGV || false; 184 static final boolean DEBUG_BACKUP = localLOGV || false; 185 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 186 static final boolean DEBUG_POWER = localLOGV || false; 187 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 188 static final boolean DEBUG_MU = localLOGV || false; 189 static final boolean VALIDATE_TOKENS = false; 190 static final boolean SHOW_ACTIVITY_START_TIME = true; 191 192 // Control over CPU and battery monitoring. 193 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 194 static final boolean MONITOR_CPU_USAGE = true; 195 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 196 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 197 static final boolean MONITOR_THREAD_CPU_USAGE = false; 198 199 // The flags that are set for all calls we make to the package manager. 200 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 201 202 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 203 204 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 205 206 // Maximum number of recent tasks that we can remember. 207 static final int MAX_RECENT_TASKS = 20; 208 209 // Amount of time after a call to stopAppSwitches() during which we will 210 // prevent further untrusted switches from happening. 211 static final long APP_SWITCH_DELAY_TIME = 5*1000; 212 213 // How long we wait for a launched process to attach to the activity manager 214 // before we decide it's never going to come up for real. 215 static final int PROC_START_TIMEOUT = 10*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real, when the process was 219 // started with a wrapper for instrumentation (such as Valgrind) because it 220 // could take much longer than usual. 221 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 222 223 // How long to wait after going idle before forcing apps to GC. 224 static final int GC_TIMEOUT = 5*1000; 225 226 // The minimum amount of time between successive GC requests for a process. 227 static final int GC_MIN_INTERVAL = 60*1000; 228 229 // The rate at which we check for apps using excessive power -- 15 mins. 230 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 231 232 // The minimum sample duration we will allow before deciding we have 233 // enough data on wake locks to start killing things. 234 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on CPU usage to start killing things. 238 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // How long we allow a receiver to run before giving up on it. 241 static final int BROADCAST_FG_TIMEOUT = 10*1000; 242 static final int BROADCAST_BG_TIMEOUT = 60*1000; 243 244 // How long we wait until we timeout on key dispatching. 245 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 246 247 // How long we wait until we timeout on key dispatching during instrumentation. 248 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 249 250 static final int MY_PID = Process.myPid(); 251 252 static final String[] EMPTY_STRING_ARRAY = new String[0]; 253 254 public ActivityStack mMainStack; 255 256 private final boolean mHeadless; 257 258 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 259 // default actuion automatically. Important for devices without direct input 260 // devices. 261 private boolean mShowDialogs = true; 262 263 /** 264 * Description of a request to start a new activity, which has been held 265 * due to app switches being disabled. 266 */ 267 static class PendingActivityLaunch { 268 ActivityRecord r; 269 ActivityRecord sourceRecord; 270 int startFlags; 271 } 272 273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 274 = new ArrayList<PendingActivityLaunch>(); 275 276 277 BroadcastQueue mFgBroadcastQueue; 278 BroadcastQueue mBgBroadcastQueue; 279 // Convenient for easy iteration over the queues. Foreground is first 280 // so that dispatch of foreground broadcasts gets precedence. 281 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 282 283 BroadcastQueue broadcastQueueForIntent(Intent intent) { 284 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 285 if (DEBUG_BACKGROUND_BROADCAST) { 286 Slog.i(TAG, "Broadcast intent " + intent + " on " 287 + (isFg ? "foreground" : "background") 288 + " queue"); 289 } 290 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 291 } 292 293 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 294 for (BroadcastQueue queue : mBroadcastQueues) { 295 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 296 if (r != null) { 297 return r; 298 } 299 } 300 return null; 301 } 302 303 /** 304 * Activity we have told the window manager to have key focus. 305 */ 306 ActivityRecord mFocusedActivity = null; 307 /** 308 * List of intents that were used to start the most recent tasks. 309 */ 310 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 311 312 /** 313 * Process management. 314 */ 315 final ProcessList mProcessList = new ProcessList(); 316 317 /** 318 * All of the applications we currently have running organized by name. 319 * The keys are strings of the application package name (as 320 * returned by the package manager), and the keys are ApplicationRecord 321 * objects. 322 */ 323 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 324 325 /** 326 * The currently running isolated processes. 327 */ 328 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 329 330 /** 331 * Counter for assigning isolated process uids, to avoid frequently reusing the 332 * same ones. 333 */ 334 int mNextIsolatedProcessUid = 0; 335 336 /** 337 * The currently running heavy-weight process, if any. 338 */ 339 ProcessRecord mHeavyWeightProcess = null; 340 341 /** 342 * The last time that various processes have crashed. 343 */ 344 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 345 346 /** 347 * Set of applications that we consider to be bad, and will reject 348 * incoming broadcasts from (which the user has no control over). 349 * Processes are added to this set when they have crashed twice within 350 * a minimum amount of time; they are removed from it when they are 351 * later restarted (hopefully due to some user action). The value is the 352 * time it was added to the list. 353 */ 354 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 355 356 /** 357 * All of the processes we currently have running organized by pid. 358 * The keys are the pid running the application. 359 * 360 * <p>NOTE: This object is protected by its own lock, NOT the global 361 * activity manager lock! 362 */ 363 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 364 365 /** 366 * All of the processes that have been forced to be foreground. The key 367 * is the pid of the caller who requested it (we hold a death 368 * link on it). 369 */ 370 abstract class ForegroundToken implements IBinder.DeathRecipient { 371 int pid; 372 IBinder token; 373 } 374 final SparseArray<ForegroundToken> mForegroundProcesses 375 = new SparseArray<ForegroundToken>(); 376 377 /** 378 * List of records for processes that someone had tried to start before the 379 * system was ready. We don't start them at that point, but ensure they 380 * are started by the time booting is complete. 381 */ 382 final ArrayList<ProcessRecord> mProcessesOnHold 383 = new ArrayList<ProcessRecord>(); 384 385 /** 386 * List of persistent applications that are in the process 387 * of being started. 388 */ 389 final ArrayList<ProcessRecord> mPersistentStartingProcesses 390 = new ArrayList<ProcessRecord>(); 391 392 /** 393 * Processes that are being forcibly torn down. 394 */ 395 final ArrayList<ProcessRecord> mRemovedProcesses 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of running applications, sorted by recent usage. 400 * The first entry in the list is the least recently used. 401 * It contains ApplicationRecord objects. This list does NOT include 402 * any persistent application records (since we never want to exit them). 403 */ 404 final ArrayList<ProcessRecord> mLruProcesses 405 = new ArrayList<ProcessRecord>(); 406 407 /** 408 * List of processes that should gc as soon as things are idle. 409 */ 410 final ArrayList<ProcessRecord> mProcessesToGc 411 = new ArrayList<ProcessRecord>(); 412 413 /** 414 * This is the process holding what we currently consider to be 415 * the "home" activity. 416 */ 417 ProcessRecord mHomeProcess; 418 419 /** 420 * This is the process holding the activity the user last visited that 421 * is in a different process from the one they are currently in. 422 */ 423 ProcessRecord mPreviousProcess; 424 425 /** 426 * The time at which the previous process was last visible. 427 */ 428 long mPreviousProcessVisibleTime; 429 430 /** 431 * Packages that the user has asked to have run in screen size 432 * compatibility mode instead of filling the screen. 433 */ 434 final CompatModePackages mCompatModePackages; 435 436 /** 437 * Set of PendingResultRecord objects that are currently active. 438 */ 439 final HashSet mPendingResultRecords = new HashSet(); 440 441 /** 442 * Set of IntentSenderRecord objects that are currently active. 443 */ 444 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 445 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 446 447 /** 448 * Fingerprints (hashCode()) of stack traces that we've 449 * already logged DropBox entries for. Guarded by itself. If 450 * something (rogue user app) forces this over 451 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 452 */ 453 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 454 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 455 456 /** 457 * Strict Mode background batched logging state. 458 * 459 * The string buffer is guarded by itself, and its lock is also 460 * used to determine if another batched write is already 461 * in-flight. 462 */ 463 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 464 465 /** 466 * Keeps track of all IIntentReceivers that have been registered for 467 * broadcasts. Hash keys are the receiver IBinder, hash value is 468 * a ReceiverList. 469 */ 470 final HashMap mRegisteredReceivers = new HashMap(); 471 472 /** 473 * Resolver for broadcast intents to registered receivers. 474 * Holds BroadcastFilter (subclass of IntentFilter). 475 */ 476 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 477 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 478 @Override 479 protected boolean allowFilterResult( 480 BroadcastFilter filter, List<BroadcastFilter> dest) { 481 IBinder target = filter.receiverList.receiver.asBinder(); 482 for (int i=dest.size()-1; i>=0; i--) { 483 if (dest.get(i).receiverList.receiver.asBinder() == target) { 484 return false; 485 } 486 } 487 return true; 488 } 489 490 @Override 491 protected BroadcastFilter[] newArray(int size) { 492 return new BroadcastFilter[size]; 493 } 494 495 @Override 496 protected String packageForFilter(BroadcastFilter filter) { 497 return filter.packageName; 498 } 499 }; 500 501 /** 502 * State of all active sticky broadcasts. Keys are the action of the 503 * sticky Intent, values are an ArrayList of all broadcasted intents with 504 * that action (which should usually be one). 505 */ 506 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 507 new HashMap<String, ArrayList<Intent>>(); 508 509 final ActiveServices mServices; 510 511 /** 512 * Backup/restore process management 513 */ 514 String mBackupAppName = null; 515 BackupRecord mBackupTarget = null; 516 517 /** 518 * List of PendingThumbnailsRecord objects of clients who are still 519 * waiting to receive all of the thumbnails for a task. 520 */ 521 final ArrayList mPendingThumbnails = new ArrayList(); 522 523 /** 524 * List of HistoryRecord objects that have been finished and must 525 * still report back to a pending thumbnail receiver. 526 */ 527 final ArrayList mCancelledThumbnails = new ArrayList(); 528 529 final ProviderMap mProviderMap = new ProviderMap(); 530 531 /** 532 * List of content providers who have clients waiting for them. The 533 * application is currently being launched and the provider will be 534 * removed from this list once it is published. 535 */ 536 final ArrayList<ContentProviderRecord> mLaunchingProviders 537 = new ArrayList<ContentProviderRecord>(); 538 539 /** 540 * Global set of specific Uri permissions that have been granted. 541 */ 542 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 543 = new SparseArray<HashMap<Uri, UriPermission>>(); 544 545 CoreSettingsObserver mCoreSettingsObserver; 546 547 /** 548 * Thread-local storage used to carry caller permissions over through 549 * indirect content-provider access. 550 * @see #ActivityManagerService.openContentUri() 551 */ 552 private class Identity { 553 public int pid; 554 public int uid; 555 556 Identity(int _pid, int _uid) { 557 pid = _pid; 558 uid = _uid; 559 } 560 } 561 562 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 563 564 /** 565 * All information we have collected about the runtime performance of 566 * any user id that can impact battery performance. 567 */ 568 final BatteryStatsService mBatteryStatsService; 569 570 /** 571 * information about component usage 572 */ 573 final UsageStatsService mUsageStatsService; 574 575 /** 576 * Current configuration information. HistoryRecord objects are given 577 * a reference to this object to indicate which configuration they are 578 * currently running in, so this object must be kept immutable. 579 */ 580 Configuration mConfiguration = new Configuration(); 581 582 /** 583 * Current sequencing integer of the configuration, for skipping old 584 * configurations. 585 */ 586 int mConfigurationSeq = 0; 587 588 /** 589 * Hardware-reported OpenGLES version. 590 */ 591 final int GL_ES_VERSION; 592 593 /** 594 * List of initialization arguments to pass to all processes when binding applications to them. 595 * For example, references to the commonly used services. 596 */ 597 HashMap<String, IBinder> mAppBindArgs; 598 599 /** 600 * Temporary to avoid allocations. Protected by main lock. 601 */ 602 final StringBuilder mStringBuilder = new StringBuilder(256); 603 604 /** 605 * Used to control how we initialize the service. 606 */ 607 boolean mStartRunning = false; 608 ComponentName mTopComponent; 609 String mTopAction; 610 String mTopData; 611 boolean mProcessesReady = false; 612 boolean mSystemReady = false; 613 boolean mBooting = false; 614 boolean mWaitingUpdate = false; 615 boolean mDidUpdate = false; 616 boolean mOnBattery = false; 617 boolean mLaunchWarningShown = false; 618 619 Context mContext; 620 621 int mFactoryTest; 622 623 boolean mCheckedForSetup; 624 625 /** 626 * The time at which we will allow normal application switches again, 627 * after a call to {@link #stopAppSwitches()}. 628 */ 629 long mAppSwitchesAllowedTime; 630 631 /** 632 * This is set to true after the first switch after mAppSwitchesAllowedTime 633 * is set; any switches after that will clear the time. 634 */ 635 boolean mDidAppSwitch; 636 637 /** 638 * Last time (in realtime) at which we checked for power usage. 639 */ 640 long mLastPowerCheckRealtime; 641 642 /** 643 * Last time (in uptime) at which we checked for power usage. 644 */ 645 long mLastPowerCheckUptime; 646 647 /** 648 * Set while we are wanting to sleep, to prevent any 649 * activities from being started/resumed. 650 */ 651 boolean mSleeping = false; 652 653 /** 654 * State of external calls telling us if the device is asleep. 655 */ 656 boolean mWentToSleep = false; 657 658 /** 659 * State of external call telling us if the lock screen is shown. 660 */ 661 boolean mLockScreenShown = false; 662 663 /** 664 * Set if we are shutting down the system, similar to sleeping. 665 */ 666 boolean mShuttingDown = false; 667 668 /** 669 * Task identifier that activities are currently being started 670 * in. Incremented each time a new task is created. 671 * todo: Replace this with a TokenSpace class that generates non-repeating 672 * integers that won't wrap. 673 */ 674 int mCurTask = 1; 675 676 /** 677 * Current sequence id for oom_adj computation traversal. 678 */ 679 int mAdjSeq = 0; 680 681 /** 682 * Current sequence id for process LRU updating. 683 */ 684 int mLruSeq = 0; 685 686 /** 687 * Keep track of the number of service processes we last found, to 688 * determine on the next iteration which should be B services. 689 */ 690 int mNumServiceProcs = 0; 691 int mNewNumServiceProcs = 0; 692 693 /** 694 * System monitoring: number of processes that died since the last 695 * N procs were started. 696 */ 697 int[] mProcDeaths = new int[20]; 698 699 /** 700 * This is set if we had to do a delayed dexopt of an app before launching 701 * it, to increasing the ANR timeouts in that case. 702 */ 703 boolean mDidDexOpt; 704 705 String mDebugApp = null; 706 boolean mWaitForDebugger = false; 707 boolean mDebugTransient = false; 708 String mOrigDebugApp = null; 709 boolean mOrigWaitForDebugger = false; 710 boolean mAlwaysFinishActivities = false; 711 IActivityController mController = null; 712 String mProfileApp = null; 713 ProcessRecord mProfileProc = null; 714 String mProfileFile; 715 ParcelFileDescriptor mProfileFd; 716 int mProfileType = 0; 717 boolean mAutoStopProfiler = false; 718 String mOpenGlTraceApp = null; 719 720 static class ProcessChangeItem { 721 static final int CHANGE_ACTIVITIES = 1<<0; 722 static final int CHANGE_IMPORTANCE= 1<<1; 723 int changes; 724 int uid; 725 int pid; 726 int importance; 727 boolean foregroundActivities; 728 } 729 730 final RemoteCallbackList<IProcessObserver> mProcessObservers 731 = new RemoteCallbackList<IProcessObserver>(); 732 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 733 734 final ArrayList<ProcessChangeItem> mPendingProcessChanges 735 = new ArrayList<ProcessChangeItem>(); 736 final ArrayList<ProcessChangeItem> mAvailProcessChanges 737 = new ArrayList<ProcessChangeItem>(); 738 739 /** 740 * Callback of last caller to {@link #requestPss}. 741 */ 742 Runnable mRequestPssCallback; 743 744 /** 745 * Remaining processes for which we are waiting results from the last 746 * call to {@link #requestPss}. 747 */ 748 final ArrayList<ProcessRecord> mRequestPssList 749 = new ArrayList<ProcessRecord>(); 750 751 /** 752 * Runtime statistics collection thread. This object's lock is used to 753 * protect all related state. 754 */ 755 final Thread mProcessStatsThread; 756 757 /** 758 * Used to collect process stats when showing not responding dialog. 759 * Protected by mProcessStatsThread. 760 */ 761 final ProcessStats mProcessStats = new ProcessStats( 762 MONITOR_THREAD_CPU_USAGE); 763 final AtomicLong mLastCpuTime = new AtomicLong(0); 764 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 765 766 long mLastWriteTime = 0; 767 768 /** 769 * Set to true after the system has finished booting. 770 */ 771 boolean mBooted = false; 772 773 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 774 int mProcessLimitOverride = -1; 775 776 WindowManagerService mWindowManager; 777 778 static ActivityManagerService mSelf; 779 static ActivityThread mSystemThread; 780 781 private final class AppDeathRecipient implements IBinder.DeathRecipient { 782 final ProcessRecord mApp; 783 final int mPid; 784 final IApplicationThread mAppThread; 785 786 AppDeathRecipient(ProcessRecord app, int pid, 787 IApplicationThread thread) { 788 if (localLOGV) Slog.v( 789 TAG, "New death recipient " + this 790 + " for thread " + thread.asBinder()); 791 mApp = app; 792 mPid = pid; 793 mAppThread = thread; 794 } 795 796 public void binderDied() { 797 if (localLOGV) Slog.v( 798 TAG, "Death received in " + this 799 + " for thread " + mAppThread.asBinder()); 800 synchronized(ActivityManagerService.this) { 801 appDiedLocked(mApp, mPid, mAppThread); 802 } 803 } 804 } 805 806 static final int SHOW_ERROR_MSG = 1; 807 static final int SHOW_NOT_RESPONDING_MSG = 2; 808 static final int SHOW_FACTORY_ERROR_MSG = 3; 809 static final int UPDATE_CONFIGURATION_MSG = 4; 810 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 811 static final int WAIT_FOR_DEBUGGER_MSG = 6; 812 static final int SERVICE_TIMEOUT_MSG = 12; 813 static final int UPDATE_TIME_ZONE = 13; 814 static final int SHOW_UID_ERROR_MSG = 14; 815 static final int IM_FEELING_LUCKY_MSG = 15; 816 static final int PROC_START_TIMEOUT_MSG = 20; 817 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 818 static final int KILL_APPLICATION_MSG = 22; 819 static final int FINALIZE_PENDING_INTENT_MSG = 23; 820 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 821 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 822 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 823 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 824 static final int CLEAR_DNS_CACHE = 28; 825 static final int UPDATE_HTTP_PROXY = 29; 826 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 827 static final int DISPATCH_PROCESSES_CHANGED = 31; 828 static final int DISPATCH_PROCESS_DIED = 32; 829 static final int REPORT_MEM_USAGE = 33; 830 831 static final int FIRST_ACTIVITY_STACK_MSG = 100; 832 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 833 static final int FIRST_COMPAT_MODE_MSG = 300; 834 835 AlertDialog mUidAlert; 836 CompatModeDialog mCompatModeDialog; 837 long mLastMemUsageReportTime = 0; 838 839 final Handler mHandler = new Handler() { 840 //public Handler() { 841 // if (localLOGV) Slog.v(TAG, "Handler started!"); 842 //} 843 844 public void handleMessage(Message msg) { 845 switch (msg.what) { 846 case SHOW_ERROR_MSG: { 847 HashMap data = (HashMap) msg.obj; 848 synchronized (ActivityManagerService.this) { 849 ProcessRecord proc = (ProcessRecord)data.get("app"); 850 if (proc != null && proc.crashDialog != null) { 851 Slog.e(TAG, "App already has crash dialog: " + proc); 852 return; 853 } 854 AppErrorResult res = (AppErrorResult) data.get("result"); 855 if (mShowDialogs && !mSleeping && !mShuttingDown) { 856 Dialog d = new AppErrorDialog(mContext, res, proc); 857 d.show(); 858 proc.crashDialog = d; 859 } else { 860 // The device is asleep, so just pretend that the user 861 // saw a crash dialog and hit "force quit". 862 res.set(0); 863 } 864 } 865 866 ensureBootCompleted(); 867 } break; 868 case SHOW_NOT_RESPONDING_MSG: { 869 synchronized (ActivityManagerService.this) { 870 HashMap data = (HashMap) msg.obj; 871 ProcessRecord proc = (ProcessRecord)data.get("app"); 872 if (proc != null && proc.anrDialog != null) { 873 Slog.e(TAG, "App already has anr dialog: " + proc); 874 return; 875 } 876 877 Intent intent = new Intent("android.intent.action.ANR"); 878 if (!mProcessesReady) { 879 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 880 | Intent.FLAG_RECEIVER_FOREGROUND); 881 } 882 broadcastIntentLocked(null, null, intent, 883 null, null, 0, null, null, null, 884 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 885 886 if (mShowDialogs) { 887 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 888 mContext, proc, (ActivityRecord)data.get("activity")); 889 d.show(); 890 proc.anrDialog = d; 891 } else { 892 // Just kill the app if there is no dialog to be shown. 893 killAppAtUsersRequest(proc, null); 894 } 895 } 896 897 ensureBootCompleted(); 898 } break; 899 case SHOW_STRICT_MODE_VIOLATION_MSG: { 900 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 901 synchronized (ActivityManagerService.this) { 902 ProcessRecord proc = (ProcessRecord) data.get("app"); 903 if (proc == null) { 904 Slog.e(TAG, "App not found when showing strict mode dialog."); 905 break; 906 } 907 if (proc.crashDialog != null) { 908 Slog.e(TAG, "App already has strict mode dialog: " + proc); 909 return; 910 } 911 AppErrorResult res = (AppErrorResult) data.get("result"); 912 if (mShowDialogs && !mSleeping && !mShuttingDown) { 913 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 914 d.show(); 915 proc.crashDialog = d; 916 } else { 917 // The device is asleep, so just pretend that the user 918 // saw a crash dialog and hit "force quit". 919 res.set(0); 920 } 921 } 922 ensureBootCompleted(); 923 } break; 924 case SHOW_FACTORY_ERROR_MSG: { 925 Dialog d = new FactoryErrorDialog( 926 mContext, msg.getData().getCharSequence("msg")); 927 d.show(); 928 ensureBootCompleted(); 929 } break; 930 case UPDATE_CONFIGURATION_MSG: { 931 final ContentResolver resolver = mContext.getContentResolver(); 932 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 933 } break; 934 case GC_BACKGROUND_PROCESSES_MSG: { 935 synchronized (ActivityManagerService.this) { 936 performAppGcsIfAppropriateLocked(); 937 } 938 } break; 939 case WAIT_FOR_DEBUGGER_MSG: { 940 synchronized (ActivityManagerService.this) { 941 ProcessRecord app = (ProcessRecord)msg.obj; 942 if (msg.arg1 != 0) { 943 if (!app.waitedForDebugger) { 944 Dialog d = new AppWaitingForDebuggerDialog( 945 ActivityManagerService.this, 946 mContext, app); 947 app.waitDialog = d; 948 app.waitedForDebugger = true; 949 d.show(); 950 } 951 } else { 952 if (app.waitDialog != null) { 953 app.waitDialog.dismiss(); 954 app.waitDialog = null; 955 } 956 } 957 } 958 } break; 959 case SERVICE_TIMEOUT_MSG: { 960 if (mDidDexOpt) { 961 mDidDexOpt = false; 962 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 963 nmsg.obj = msg.obj; 964 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 965 return; 966 } 967 mServices.serviceTimeout((ProcessRecord)msg.obj); 968 } break; 969 case UPDATE_TIME_ZONE: { 970 synchronized (ActivityManagerService.this) { 971 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 972 ProcessRecord r = mLruProcesses.get(i); 973 if (r.thread != null) { 974 try { 975 r.thread.updateTimeZone(); 976 } catch (RemoteException ex) { 977 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 978 } 979 } 980 } 981 } 982 } break; 983 case CLEAR_DNS_CACHE: { 984 synchronized (ActivityManagerService.this) { 985 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 986 ProcessRecord r = mLruProcesses.get(i); 987 if (r.thread != null) { 988 try { 989 r.thread.clearDnsCache(); 990 } catch (RemoteException ex) { 991 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 992 } 993 } 994 } 995 } 996 } break; 997 case UPDATE_HTTP_PROXY: { 998 ProxyProperties proxy = (ProxyProperties)msg.obj; 999 String host = ""; 1000 String port = ""; 1001 String exclList = ""; 1002 if (proxy != null) { 1003 host = proxy.getHost(); 1004 port = Integer.toString(proxy.getPort()); 1005 exclList = proxy.getExclusionList(); 1006 } 1007 synchronized (ActivityManagerService.this) { 1008 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1009 ProcessRecord r = mLruProcesses.get(i); 1010 if (r.thread != null) { 1011 try { 1012 r.thread.setHttpProxy(host, port, exclList); 1013 } catch (RemoteException ex) { 1014 Slog.w(TAG, "Failed to update http proxy for: " + 1015 r.info.processName); 1016 } 1017 } 1018 } 1019 } 1020 } break; 1021 case SHOW_UID_ERROR_MSG: { 1022 String title = "System UIDs Inconsistent"; 1023 String text = "UIDs on the system are inconsistent, you need to wipe your" 1024 + " data partition or your device will be unstable."; 1025 Log.e(TAG, title + ": " + text); 1026 if (mShowDialogs) { 1027 // XXX This is a temporary dialog, no need to localize. 1028 AlertDialog d = new BaseErrorDialog(mContext); 1029 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1030 d.setCancelable(false); 1031 d.setTitle(title); 1032 d.setMessage(text); 1033 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1034 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1035 mUidAlert = d; 1036 d.show(); 1037 } 1038 } break; 1039 case IM_FEELING_LUCKY_MSG: { 1040 if (mUidAlert != null) { 1041 mUidAlert.dismiss(); 1042 mUidAlert = null; 1043 } 1044 } break; 1045 case PROC_START_TIMEOUT_MSG: { 1046 if (mDidDexOpt) { 1047 mDidDexOpt = false; 1048 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1049 nmsg.obj = msg.obj; 1050 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1051 return; 1052 } 1053 ProcessRecord app = (ProcessRecord)msg.obj; 1054 synchronized (ActivityManagerService.this) { 1055 processStartTimedOutLocked(app); 1056 } 1057 } break; 1058 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1059 synchronized (ActivityManagerService.this) { 1060 doPendingActivityLaunchesLocked(true); 1061 } 1062 } break; 1063 case KILL_APPLICATION_MSG: { 1064 synchronized (ActivityManagerService.this) { 1065 int uid = msg.arg1; 1066 boolean restart = (msg.arg2 == 1); 1067 String pkg = (String) msg.obj; 1068 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1069 UserId.getUserId(uid)); 1070 } 1071 } break; 1072 case FINALIZE_PENDING_INTENT_MSG: { 1073 ((PendingIntentRecord)msg.obj).completeFinalize(); 1074 } break; 1075 case POST_HEAVY_NOTIFICATION_MSG: { 1076 INotificationManager inm = NotificationManager.getService(); 1077 if (inm == null) { 1078 return; 1079 } 1080 1081 ActivityRecord root = (ActivityRecord)msg.obj; 1082 ProcessRecord process = root.app; 1083 if (process == null) { 1084 return; 1085 } 1086 1087 try { 1088 Context context = mContext.createPackageContext(process.info.packageName, 0); 1089 String text = mContext.getString(R.string.heavy_weight_notification, 1090 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1091 Notification notification = new Notification(); 1092 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1093 notification.when = 0; 1094 notification.flags = Notification.FLAG_ONGOING_EVENT; 1095 notification.tickerText = text; 1096 notification.defaults = 0; // please be quiet 1097 notification.sound = null; 1098 notification.vibrate = null; 1099 notification.setLatestEventInfo(context, text, 1100 mContext.getText(R.string.heavy_weight_notification_detail), 1101 PendingIntent.getActivity(mContext, 0, root.intent, 1102 PendingIntent.FLAG_CANCEL_CURRENT)); 1103 1104 try { 1105 int[] outId = new int[1]; 1106 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1107 notification, outId); 1108 } catch (RuntimeException e) { 1109 Slog.w(ActivityManagerService.TAG, 1110 "Error showing notification for heavy-weight app", e); 1111 } catch (RemoteException e) { 1112 } 1113 } catch (NameNotFoundException e) { 1114 Slog.w(TAG, "Unable to create context for heavy notification", e); 1115 } 1116 } break; 1117 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1118 INotificationManager inm = NotificationManager.getService(); 1119 if (inm == null) { 1120 return; 1121 } 1122 try { 1123 inm.cancelNotification("android", 1124 R.string.heavy_weight_notification); 1125 } catch (RuntimeException e) { 1126 Slog.w(ActivityManagerService.TAG, 1127 "Error canceling notification for service", e); 1128 } catch (RemoteException e) { 1129 } 1130 } break; 1131 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1132 synchronized (ActivityManagerService.this) { 1133 checkExcessivePowerUsageLocked(true); 1134 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1135 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1136 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1137 } 1138 } break; 1139 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1140 synchronized (ActivityManagerService.this) { 1141 ActivityRecord ar = (ActivityRecord)msg.obj; 1142 if (mCompatModeDialog != null) { 1143 if (mCompatModeDialog.mAppInfo.packageName.equals( 1144 ar.info.applicationInfo.packageName)) { 1145 return; 1146 } 1147 mCompatModeDialog.dismiss(); 1148 mCompatModeDialog = null; 1149 } 1150 if (ar != null && false) { 1151 if (mCompatModePackages.getPackageAskCompatModeLocked( 1152 ar.packageName)) { 1153 int mode = mCompatModePackages.computeCompatModeLocked( 1154 ar.info.applicationInfo); 1155 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1156 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1157 mCompatModeDialog = new CompatModeDialog( 1158 ActivityManagerService.this, mContext, 1159 ar.info.applicationInfo); 1160 mCompatModeDialog.show(); 1161 } 1162 } 1163 } 1164 } 1165 break; 1166 } 1167 case DISPATCH_PROCESSES_CHANGED: { 1168 dispatchProcessesChanged(); 1169 break; 1170 } 1171 case DISPATCH_PROCESS_DIED: { 1172 final int pid = msg.arg1; 1173 final int uid = msg.arg2; 1174 dispatchProcessDied(pid, uid); 1175 break; 1176 } 1177 case REPORT_MEM_USAGE: { 1178 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1179 if (!isDebuggable) { 1180 return; 1181 } 1182 synchronized (ActivityManagerService.this) { 1183 long now = SystemClock.uptimeMillis(); 1184 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1185 // Don't report more than every 5 minutes to somewhat 1186 // avoid spamming. 1187 return; 1188 } 1189 mLastMemUsageReportTime = now; 1190 } 1191 Thread thread = new Thread() { 1192 @Override public void run() { 1193 StringBuilder dropBuilder = new StringBuilder(1024); 1194 StringBuilder logBuilder = new StringBuilder(1024); 1195 StringWriter oomSw = new StringWriter(); 1196 PrintWriter oomPw = new PrintWriter(oomSw); 1197 StringWriter catSw = new StringWriter(); 1198 PrintWriter catPw = new PrintWriter(catSw); 1199 String[] emptyArgs = new String[] { }; 1200 StringBuilder tag = new StringBuilder(128); 1201 StringBuilder stack = new StringBuilder(128); 1202 tag.append("Low on memory -- "); 1203 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1204 tag, stack); 1205 dropBuilder.append(stack); 1206 dropBuilder.append('\n'); 1207 dropBuilder.append('\n'); 1208 String oomString = oomSw.toString(); 1209 dropBuilder.append(oomString); 1210 dropBuilder.append('\n'); 1211 logBuilder.append(oomString); 1212 try { 1213 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1214 "procrank", }); 1215 final InputStreamReader converter = new InputStreamReader( 1216 proc.getInputStream()); 1217 BufferedReader in = new BufferedReader(converter); 1218 String line; 1219 while (true) { 1220 line = in.readLine(); 1221 if (line == null) { 1222 break; 1223 } 1224 if (line.length() > 0) { 1225 logBuilder.append(line); 1226 logBuilder.append('\n'); 1227 } 1228 dropBuilder.append(line); 1229 dropBuilder.append('\n'); 1230 } 1231 converter.close(); 1232 } catch (IOException e) { 1233 } 1234 synchronized (ActivityManagerService.this) { 1235 catPw.println(); 1236 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1237 catPw.println(); 1238 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1239 false, false, null); 1240 catPw.println(); 1241 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1242 } 1243 dropBuilder.append(catSw.toString()); 1244 addErrorToDropBox("lowmem", null, "system_server", null, 1245 null, tag.toString(), dropBuilder.toString(), null, null); 1246 Slog.i(TAG, logBuilder.toString()); 1247 synchronized (ActivityManagerService.this) { 1248 long now = SystemClock.uptimeMillis(); 1249 if (mLastMemUsageReportTime < now) { 1250 mLastMemUsageReportTime = now; 1251 } 1252 } 1253 } 1254 }; 1255 thread.start(); 1256 break; 1257 } 1258 } 1259 } 1260 }; 1261 1262 public static void setSystemProcess() { 1263 try { 1264 ActivityManagerService m = mSelf; 1265 1266 ServiceManager.addService("activity", m, true); 1267 ServiceManager.addService("meminfo", new MemBinder(m)); 1268 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1269 ServiceManager.addService("dbinfo", new DbBinder(m)); 1270 if (MONITOR_CPU_USAGE) { 1271 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1272 } 1273 ServiceManager.addService("permission", new PermissionController(m)); 1274 1275 ApplicationInfo info = 1276 mSelf.mContext.getPackageManager().getApplicationInfo( 1277 "android", STOCK_PM_FLAGS); 1278 mSystemThread.installSystemApplicationInfo(info); 1279 1280 synchronized (mSelf) { 1281 ProcessRecord app = mSelf.newProcessRecordLocked( 1282 mSystemThread.getApplicationThread(), info, 1283 info.processName, false); 1284 app.persistent = true; 1285 app.pid = MY_PID; 1286 app.maxAdj = ProcessList.SYSTEM_ADJ; 1287 mSelf.mProcessNames.put(app.processName, app.uid, app); 1288 synchronized (mSelf.mPidsSelfLocked) { 1289 mSelf.mPidsSelfLocked.put(app.pid, app); 1290 } 1291 mSelf.updateLruProcessLocked(app, true, true); 1292 } 1293 } catch (PackageManager.NameNotFoundException e) { 1294 throw new RuntimeException( 1295 "Unable to find android system package", e); 1296 } 1297 } 1298 1299 public void setWindowManager(WindowManagerService wm) { 1300 mWindowManager = wm; 1301 } 1302 1303 public static final Context main(int factoryTest) { 1304 AThread thr = new AThread(); 1305 thr.start(); 1306 1307 synchronized (thr) { 1308 while (thr.mService == null) { 1309 try { 1310 thr.wait(); 1311 } catch (InterruptedException e) { 1312 } 1313 } 1314 } 1315 1316 ActivityManagerService m = thr.mService; 1317 mSelf = m; 1318 ActivityThread at = ActivityThread.systemMain(); 1319 mSystemThread = at; 1320 Context context = at.getSystemContext(); 1321 context.setTheme(android.R.style.Theme_Holo); 1322 m.mContext = context; 1323 m.mFactoryTest = factoryTest; 1324 m.mMainStack = new ActivityStack(m, context, true); 1325 1326 m.mBatteryStatsService.publish(context); 1327 m.mUsageStatsService.publish(context); 1328 1329 synchronized (thr) { 1330 thr.mReady = true; 1331 thr.notifyAll(); 1332 } 1333 1334 m.startRunning(null, null, null, null); 1335 1336 return context; 1337 } 1338 1339 public static ActivityManagerService self() { 1340 return mSelf; 1341 } 1342 1343 static class AThread extends Thread { 1344 ActivityManagerService mService; 1345 boolean mReady = false; 1346 1347 public AThread() { 1348 super("ActivityManager"); 1349 } 1350 1351 public void run() { 1352 Looper.prepare(); 1353 1354 android.os.Process.setThreadPriority( 1355 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1356 android.os.Process.setCanSelfBackground(false); 1357 1358 ActivityManagerService m = new ActivityManagerService(); 1359 1360 synchronized (this) { 1361 mService = m; 1362 notifyAll(); 1363 } 1364 1365 synchronized (this) { 1366 while (!mReady) { 1367 try { 1368 wait(); 1369 } catch (InterruptedException e) { 1370 } 1371 } 1372 } 1373 1374 // For debug builds, log event loop stalls to dropbox for analysis. 1375 if (StrictMode.conditionallyEnableDebugLogging()) { 1376 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1377 } 1378 1379 Looper.loop(); 1380 } 1381 } 1382 1383 static class MemBinder extends Binder { 1384 ActivityManagerService mActivityManagerService; 1385 MemBinder(ActivityManagerService activityManagerService) { 1386 mActivityManagerService = activityManagerService; 1387 } 1388 1389 @Override 1390 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1391 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1392 != PackageManager.PERMISSION_GRANTED) { 1393 pw.println("Permission Denial: can't dump meminfo from from pid=" 1394 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1395 + " without permission " + android.Manifest.permission.DUMP); 1396 return; 1397 } 1398 1399 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1400 false, null, null, null); 1401 } 1402 } 1403 1404 static class GraphicsBinder extends Binder { 1405 ActivityManagerService mActivityManagerService; 1406 GraphicsBinder(ActivityManagerService activityManagerService) { 1407 mActivityManagerService = activityManagerService; 1408 } 1409 1410 @Override 1411 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1412 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1413 != PackageManager.PERMISSION_GRANTED) { 1414 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1415 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1416 + " without permission " + android.Manifest.permission.DUMP); 1417 return; 1418 } 1419 1420 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1421 } 1422 } 1423 1424 static class DbBinder extends Binder { 1425 ActivityManagerService mActivityManagerService; 1426 DbBinder(ActivityManagerService activityManagerService) { 1427 mActivityManagerService = activityManagerService; 1428 } 1429 1430 @Override 1431 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1432 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1433 != PackageManager.PERMISSION_GRANTED) { 1434 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1435 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1436 + " without permission " + android.Manifest.permission.DUMP); 1437 return; 1438 } 1439 1440 mActivityManagerService.dumpDbInfo(fd, pw, args); 1441 } 1442 } 1443 1444 static class CpuBinder extends Binder { 1445 ActivityManagerService mActivityManagerService; 1446 CpuBinder(ActivityManagerService activityManagerService) { 1447 mActivityManagerService = activityManagerService; 1448 } 1449 1450 @Override 1451 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1452 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1453 != PackageManager.PERMISSION_GRANTED) { 1454 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1455 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1456 + " without permission " + android.Manifest.permission.DUMP); 1457 return; 1458 } 1459 1460 synchronized (mActivityManagerService.mProcessStatsThread) { 1461 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1462 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1463 SystemClock.uptimeMillis())); 1464 } 1465 } 1466 } 1467 1468 private ActivityManagerService() { 1469 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1470 1471 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1472 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1473 mBroadcastQueues[0] = mFgBroadcastQueue; 1474 mBroadcastQueues[1] = mBgBroadcastQueue; 1475 1476 mServices = new ActiveServices(this); 1477 1478 File dataDir = Environment.getDataDirectory(); 1479 File systemDir = new File(dataDir, "system"); 1480 systemDir.mkdirs(); 1481 mBatteryStatsService = new BatteryStatsService(new File( 1482 systemDir, "batterystats.bin").toString()); 1483 mBatteryStatsService.getActiveStatistics().readLocked(); 1484 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1485 mOnBattery = DEBUG_POWER ? true 1486 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1487 mBatteryStatsService.getActiveStatistics().setCallback(this); 1488 1489 mUsageStatsService = new UsageStatsService(new File( 1490 systemDir, "usagestats").toString()); 1491 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1492 1493 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1494 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1495 1496 mConfiguration.setToDefaults(); 1497 mConfiguration.locale = Locale.getDefault(); 1498 mConfigurationSeq = mConfiguration.seq = 1; 1499 mProcessStats.init(); 1500 1501 mCompatModePackages = new CompatModePackages(this, systemDir); 1502 1503 // Add ourself to the Watchdog monitors. 1504 Watchdog.getInstance().addMonitor(this); 1505 1506 mProcessStatsThread = new Thread("ProcessStats") { 1507 public void run() { 1508 while (true) { 1509 try { 1510 try { 1511 synchronized(this) { 1512 final long now = SystemClock.uptimeMillis(); 1513 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1514 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1515 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1516 // + ", write delay=" + nextWriteDelay); 1517 if (nextWriteDelay < nextCpuDelay) { 1518 nextCpuDelay = nextWriteDelay; 1519 } 1520 if (nextCpuDelay > 0) { 1521 mProcessStatsMutexFree.set(true); 1522 this.wait(nextCpuDelay); 1523 } 1524 } 1525 } catch (InterruptedException e) { 1526 } 1527 updateCpuStatsNow(); 1528 } catch (Exception e) { 1529 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1530 } 1531 } 1532 } 1533 }; 1534 mProcessStatsThread.start(); 1535 } 1536 1537 @Override 1538 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1539 throws RemoteException { 1540 if (code == SYSPROPS_TRANSACTION) { 1541 // We need to tell all apps about the system property change. 1542 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1543 synchronized(this) { 1544 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1545 final int NA = apps.size(); 1546 for (int ia=0; ia<NA; ia++) { 1547 ProcessRecord app = apps.valueAt(ia); 1548 if (app.thread != null) { 1549 procs.add(app.thread.asBinder()); 1550 } 1551 } 1552 } 1553 } 1554 1555 int N = procs.size(); 1556 for (int i=0; i<N; i++) { 1557 Parcel data2 = Parcel.obtain(); 1558 try { 1559 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1560 } catch (RemoteException e) { 1561 } 1562 data2.recycle(); 1563 } 1564 } 1565 try { 1566 return super.onTransact(code, data, reply, flags); 1567 } catch (RuntimeException e) { 1568 // The activity manager only throws security exceptions, so let's 1569 // log all others. 1570 if (!(e instanceof SecurityException)) { 1571 Slog.e(TAG, "Activity Manager Crash", e); 1572 } 1573 throw e; 1574 } 1575 } 1576 1577 void updateCpuStats() { 1578 final long now = SystemClock.uptimeMillis(); 1579 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1580 return; 1581 } 1582 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1583 synchronized (mProcessStatsThread) { 1584 mProcessStatsThread.notify(); 1585 } 1586 } 1587 } 1588 1589 void updateCpuStatsNow() { 1590 synchronized (mProcessStatsThread) { 1591 mProcessStatsMutexFree.set(false); 1592 final long now = SystemClock.uptimeMillis(); 1593 boolean haveNewCpuStats = false; 1594 1595 if (MONITOR_CPU_USAGE && 1596 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1597 mLastCpuTime.set(now); 1598 haveNewCpuStats = true; 1599 mProcessStats.update(); 1600 //Slog.i(TAG, mProcessStats.printCurrentState()); 1601 //Slog.i(TAG, "Total CPU usage: " 1602 // + mProcessStats.getTotalCpuPercent() + "%"); 1603 1604 // Slog the cpu usage if the property is set. 1605 if ("true".equals(SystemProperties.get("events.cpu"))) { 1606 int user = mProcessStats.getLastUserTime(); 1607 int system = mProcessStats.getLastSystemTime(); 1608 int iowait = mProcessStats.getLastIoWaitTime(); 1609 int irq = mProcessStats.getLastIrqTime(); 1610 int softIrq = mProcessStats.getLastSoftIrqTime(); 1611 int idle = mProcessStats.getLastIdleTime(); 1612 1613 int total = user + system + iowait + irq + softIrq + idle; 1614 if (total == 0) total = 1; 1615 1616 EventLog.writeEvent(EventLogTags.CPU, 1617 ((user+system+iowait+irq+softIrq) * 100) / total, 1618 (user * 100) / total, 1619 (system * 100) / total, 1620 (iowait * 100) / total, 1621 (irq * 100) / total, 1622 (softIrq * 100) / total); 1623 } 1624 } 1625 1626 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1627 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1628 synchronized(bstats) { 1629 synchronized(mPidsSelfLocked) { 1630 if (haveNewCpuStats) { 1631 if (mOnBattery) { 1632 int perc = bstats.startAddingCpuLocked(); 1633 int totalUTime = 0; 1634 int totalSTime = 0; 1635 final int N = mProcessStats.countStats(); 1636 for (int i=0; i<N; i++) { 1637 ProcessStats.Stats st = mProcessStats.getStats(i); 1638 if (!st.working) { 1639 continue; 1640 } 1641 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1642 int otherUTime = (st.rel_utime*perc)/100; 1643 int otherSTime = (st.rel_stime*perc)/100; 1644 totalUTime += otherUTime; 1645 totalSTime += otherSTime; 1646 if (pr != null) { 1647 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1648 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1649 st.rel_stime-otherSTime); 1650 ps.addSpeedStepTimes(cpuSpeedTimes); 1651 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1652 } else { 1653 BatteryStatsImpl.Uid.Proc ps = 1654 bstats.getProcessStatsLocked(st.name, st.pid); 1655 if (ps != null) { 1656 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1657 st.rel_stime-otherSTime); 1658 ps.addSpeedStepTimes(cpuSpeedTimes); 1659 } 1660 } 1661 } 1662 bstats.finishAddingCpuLocked(perc, totalUTime, 1663 totalSTime, cpuSpeedTimes); 1664 } 1665 } 1666 } 1667 1668 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1669 mLastWriteTime = now; 1670 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1671 } 1672 } 1673 } 1674 } 1675 1676 @Override 1677 public void batteryNeedsCpuUpdate() { 1678 updateCpuStatsNow(); 1679 } 1680 1681 @Override 1682 public void batteryPowerChanged(boolean onBattery) { 1683 // When plugging in, update the CPU stats first before changing 1684 // the plug state. 1685 updateCpuStatsNow(); 1686 synchronized (this) { 1687 synchronized(mPidsSelfLocked) { 1688 mOnBattery = DEBUG_POWER ? true : onBattery; 1689 } 1690 } 1691 } 1692 1693 /** 1694 * Initialize the application bind args. These are passed to each 1695 * process when the bindApplication() IPC is sent to the process. They're 1696 * lazily setup to make sure the services are running when they're asked for. 1697 */ 1698 private HashMap<String, IBinder> getCommonServicesLocked() { 1699 if (mAppBindArgs == null) { 1700 mAppBindArgs = new HashMap<String, IBinder>(); 1701 1702 // Setup the application init args 1703 mAppBindArgs.put("package", ServiceManager.getService("package")); 1704 mAppBindArgs.put("window", ServiceManager.getService("window")); 1705 mAppBindArgs.put(Context.ALARM_SERVICE, 1706 ServiceManager.getService(Context.ALARM_SERVICE)); 1707 } 1708 return mAppBindArgs; 1709 } 1710 1711 final void setFocusedActivityLocked(ActivityRecord r) { 1712 if (mFocusedActivity != r) { 1713 mFocusedActivity = r; 1714 if (r != null) { 1715 mWindowManager.setFocusedApp(r.appToken, true); 1716 } 1717 } 1718 } 1719 1720 private final void updateLruProcessInternalLocked(ProcessRecord app, 1721 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1722 // put it on the LRU to keep track of when it should be exited. 1723 int lrui = mLruProcesses.indexOf(app); 1724 if (lrui >= 0) mLruProcesses.remove(lrui); 1725 1726 int i = mLruProcesses.size()-1; 1727 int skipTop = 0; 1728 1729 app.lruSeq = mLruSeq; 1730 1731 // compute the new weight for this process. 1732 if (updateActivityTime) { 1733 app.lastActivityTime = SystemClock.uptimeMillis(); 1734 } 1735 if (app.activities.size() > 0) { 1736 // If this process has activities, we more strongly want to keep 1737 // it around. 1738 app.lruWeight = app.lastActivityTime; 1739 } else if (app.pubProviders.size() > 0) { 1740 // If this process contains content providers, we want to keep 1741 // it a little more strongly. 1742 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1743 // Also don't let it kick out the first few "real" hidden processes. 1744 skipTop = ProcessList.MIN_HIDDEN_APPS; 1745 } else { 1746 // If this process doesn't have activities, we less strongly 1747 // want to keep it around, and generally want to avoid getting 1748 // in front of any very recently used activities. 1749 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1750 // Also don't let it kick out the first few "real" hidden processes. 1751 skipTop = ProcessList.MIN_HIDDEN_APPS; 1752 } 1753 1754 while (i >= 0) { 1755 ProcessRecord p = mLruProcesses.get(i); 1756 // If this app shouldn't be in front of the first N background 1757 // apps, then skip over that many that are currently hidden. 1758 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1759 skipTop--; 1760 } 1761 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1762 mLruProcesses.add(i+1, app); 1763 break; 1764 } 1765 i--; 1766 } 1767 if (i < 0) { 1768 mLruProcesses.add(0, app); 1769 } 1770 1771 // If the app is currently using a content provider or service, 1772 // bump those processes as well. 1773 if (app.connections.size() > 0) { 1774 for (ConnectionRecord cr : app.connections) { 1775 if (cr.binding != null && cr.binding.service != null 1776 && cr.binding.service.app != null 1777 && cr.binding.service.app.lruSeq != mLruSeq) { 1778 updateLruProcessInternalLocked(cr.binding.service.app, false, 1779 updateActivityTime, i+1); 1780 } 1781 } 1782 } 1783 for (int j=app.conProviders.size()-1; j>=0; j--) { 1784 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1785 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1786 updateLruProcessInternalLocked(cpr.proc, false, 1787 updateActivityTime, i+1); 1788 } 1789 } 1790 1791 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1792 if (oomAdj) { 1793 updateOomAdjLocked(); 1794 } 1795 } 1796 1797 final void updateLruProcessLocked(ProcessRecord app, 1798 boolean oomAdj, boolean updateActivityTime) { 1799 mLruSeq++; 1800 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1801 } 1802 1803 final ProcessRecord getProcessRecordLocked( 1804 String processName, int uid) { 1805 if (uid == Process.SYSTEM_UID) { 1806 // The system gets to run in any process. If there are multiple 1807 // processes with the same uid, just pick the first (this 1808 // should never happen). 1809 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1810 processName); 1811 if (procs == null) return null; 1812 final int N = procs.size(); 1813 for (int i = 0; i < N; i++) { 1814 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1815 } 1816 } 1817 ProcessRecord proc = mProcessNames.get(processName, uid); 1818 return proc; 1819 } 1820 1821 void ensurePackageDexOpt(String packageName) { 1822 IPackageManager pm = AppGlobals.getPackageManager(); 1823 try { 1824 if (pm.performDexOpt(packageName)) { 1825 mDidDexOpt = true; 1826 } 1827 } catch (RemoteException e) { 1828 } 1829 } 1830 1831 boolean isNextTransitionForward() { 1832 int transit = mWindowManager.getPendingAppTransition(); 1833 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1834 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1835 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1836 } 1837 1838 final ProcessRecord startProcessLocked(String processName, 1839 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1840 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1841 boolean isolated) { 1842 ProcessRecord app; 1843 if (!isolated) { 1844 app = getProcessRecordLocked(processName, info.uid); 1845 } else { 1846 // If this is an isolated process, it can't re-use an existing process. 1847 app = null; 1848 } 1849 // We don't have to do anything more if: 1850 // (1) There is an existing application record; and 1851 // (2) The caller doesn't think it is dead, OR there is no thread 1852 // object attached to it so we know it couldn't have crashed; and 1853 // (3) There is a pid assigned to it, so it is either starting or 1854 // already running. 1855 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1856 + " app=" + app + " knownToBeDead=" + knownToBeDead 1857 + " thread=" + (app != null ? app.thread : null) 1858 + " pid=" + (app != null ? app.pid : -1)); 1859 if (app != null && app.pid > 0) { 1860 if (!knownToBeDead || app.thread == null) { 1861 // We already have the app running, or are waiting for it to 1862 // come up (we have a pid but not yet its thread), so keep it. 1863 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1864 // If this is a new package in the process, add the package to the list 1865 app.addPackage(info.packageName); 1866 return app; 1867 } else { 1868 // An application record is attached to a previous process, 1869 // clean it up now. 1870 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1871 handleAppDiedLocked(app, true, true); 1872 } 1873 } 1874 1875 String hostingNameStr = hostingName != null 1876 ? hostingName.flattenToShortString() : null; 1877 1878 if (!isolated) { 1879 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1880 // If we are in the background, then check to see if this process 1881 // is bad. If so, we will just silently fail. 1882 if (mBadProcesses.get(info.processName, info.uid) != null) { 1883 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1884 + "/" + info.processName); 1885 return null; 1886 } 1887 } else { 1888 // When the user is explicitly starting a process, then clear its 1889 // crash count so that we won't make it bad until they see at 1890 // least one crash dialog again, and make the process good again 1891 // if it had been bad. 1892 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1893 + "/" + info.processName); 1894 mProcessCrashTimes.remove(info.processName, info.uid); 1895 if (mBadProcesses.get(info.processName, info.uid) != null) { 1896 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1897 info.processName); 1898 mBadProcesses.remove(info.processName, info.uid); 1899 if (app != null) { 1900 app.bad = false; 1901 } 1902 } 1903 } 1904 } 1905 1906 if (app == null) { 1907 app = newProcessRecordLocked(null, info, processName, isolated); 1908 if (app == null) { 1909 Slog.w(TAG, "Failed making new process record for " 1910 + processName + "/" + info.uid + " isolated=" + isolated); 1911 return null; 1912 } 1913 mProcessNames.put(processName, app.uid, app); 1914 if (isolated) { 1915 mIsolatedProcesses.put(app.uid, app); 1916 } 1917 } else { 1918 // If this is a new package in the process, add the package to the list 1919 app.addPackage(info.packageName); 1920 } 1921 1922 // If the system is not ready yet, then hold off on starting this 1923 // process until it is. 1924 if (!mProcessesReady 1925 && !isAllowedWhileBooting(info) 1926 && !allowWhileBooting) { 1927 if (!mProcessesOnHold.contains(app)) { 1928 mProcessesOnHold.add(app); 1929 } 1930 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1931 return app; 1932 } 1933 1934 startProcessLocked(app, hostingType, hostingNameStr); 1935 return (app.pid != 0) ? app : null; 1936 } 1937 1938 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1939 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1940 } 1941 1942 private final void startProcessLocked(ProcessRecord app, 1943 String hostingType, String hostingNameStr) { 1944 if (app.pid > 0 && app.pid != MY_PID) { 1945 synchronized (mPidsSelfLocked) { 1946 mPidsSelfLocked.remove(app.pid); 1947 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1948 } 1949 app.pid = 0; 1950 } 1951 1952 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1953 "startProcessLocked removing on hold: " + app); 1954 mProcessesOnHold.remove(app); 1955 1956 updateCpuStats(); 1957 1958 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1959 mProcDeaths[0] = 0; 1960 1961 try { 1962 int uid = app.uid; 1963 1964 int[] gids = null; 1965 if (!app.isolated) { 1966 try { 1967 gids = mContext.getPackageManager().getPackageGids( 1968 app.info.packageName); 1969 } catch (PackageManager.NameNotFoundException e) { 1970 Slog.w(TAG, "Unable to retrieve gids", e); 1971 } 1972 } 1973 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1974 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1975 && mTopComponent != null 1976 && app.processName.equals(mTopComponent.getPackageName())) { 1977 uid = 0; 1978 } 1979 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1980 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1981 uid = 0; 1982 } 1983 } 1984 int debugFlags = 0; 1985 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1986 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1987 // Also turn on CheckJNI for debuggable apps. It's quite 1988 // awkward to turn on otherwise. 1989 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1990 } 1991 // Run the app in safe mode if its manifest requests so or the 1992 // system is booted in safe mode. 1993 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 1994 Zygote.systemInSafeMode == true) { 1995 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1996 } 1997 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1998 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1999 } 2000 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2001 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2002 } 2003 if ("1".equals(SystemProperties.get("debug.assert"))) { 2004 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2005 } 2006 2007 // Start the process. It will either succeed and return a result containing 2008 // the PID of the new process, or else throw a RuntimeException. 2009 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2010 app.processName, uid, uid, gids, debugFlags, 2011 app.info.targetSdkVersion, null, null); 2012 2013 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2014 synchronized (bs) { 2015 if (bs.isOnBattery()) { 2016 app.batteryStats.incStartsLocked(); 2017 } 2018 } 2019 2020 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2021 app.processName, hostingType, 2022 hostingNameStr != null ? hostingNameStr : ""); 2023 2024 if (app.persistent) { 2025 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2026 } 2027 2028 StringBuilder buf = mStringBuilder; 2029 buf.setLength(0); 2030 buf.append("Start proc "); 2031 buf.append(app.processName); 2032 buf.append(" for "); 2033 buf.append(hostingType); 2034 if (hostingNameStr != null) { 2035 buf.append(" "); 2036 buf.append(hostingNameStr); 2037 } 2038 buf.append(": pid="); 2039 buf.append(startResult.pid); 2040 buf.append(" uid="); 2041 buf.append(uid); 2042 buf.append(" gids={"); 2043 if (gids != null) { 2044 for (int gi=0; gi<gids.length; gi++) { 2045 if (gi != 0) buf.append(", "); 2046 buf.append(gids[gi]); 2047 2048 } 2049 } 2050 buf.append("}"); 2051 Slog.i(TAG, buf.toString()); 2052 app.pid = startResult.pid; 2053 app.usingWrapper = startResult.usingWrapper; 2054 app.removed = false; 2055 synchronized (mPidsSelfLocked) { 2056 this.mPidsSelfLocked.put(startResult.pid, app); 2057 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2058 msg.obj = app; 2059 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2060 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2061 } 2062 } catch (RuntimeException e) { 2063 // XXX do better error recovery. 2064 app.pid = 0; 2065 Slog.e(TAG, "Failure starting process " + app.processName, e); 2066 } 2067 } 2068 2069 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2070 if (resumed) { 2071 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2072 } else { 2073 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2074 } 2075 } 2076 2077 boolean startHomeActivityLocked(int userId) { 2078 if (mHeadless) { 2079 // Added because none of the other calls to ensureBootCompleted seem to fire 2080 // when running headless. 2081 ensureBootCompleted(); 2082 return false; 2083 } 2084 2085 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2086 && mTopAction == null) { 2087 // We are running in factory test mode, but unable to find 2088 // the factory test app, so just sit around displaying the 2089 // error message and don't try to start anything. 2090 return false; 2091 } 2092 Intent intent = new Intent( 2093 mTopAction, 2094 mTopData != null ? Uri.parse(mTopData) : null); 2095 intent.setComponent(mTopComponent); 2096 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2097 intent.addCategory(Intent.CATEGORY_HOME); 2098 } 2099 ActivityInfo aInfo = 2100 intent.resolveActivityInfo(mContext.getPackageManager(), 2101 STOCK_PM_FLAGS); 2102 if (aInfo != null) { 2103 intent.setComponent(new ComponentName( 2104 aInfo.applicationInfo.packageName, aInfo.name)); 2105 // Don't do this if the home app is currently being 2106 // instrumented. 2107 aInfo = new ActivityInfo(aInfo); 2108 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2109 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2110 aInfo.applicationInfo.uid); 2111 if (app == null || app.instrumentationClass == null) { 2112 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2113 mMainStack.startActivityLocked(null, intent, null, aInfo, 2114 null, null, 0, 0, 0, 0, null, false, null); 2115 } 2116 } 2117 2118 return true; 2119 } 2120 2121 /** 2122 * Starts the "new version setup screen" if appropriate. 2123 */ 2124 void startSetupActivityLocked() { 2125 // Only do this once per boot. 2126 if (mCheckedForSetup) { 2127 return; 2128 } 2129 2130 // We will show this screen if the current one is a different 2131 // version than the last one shown, and we are not running in 2132 // low-level factory test mode. 2133 final ContentResolver resolver = mContext.getContentResolver(); 2134 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2135 Settings.Secure.getInt(resolver, 2136 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2137 mCheckedForSetup = true; 2138 2139 // See if we should be showing the platform update setup UI. 2140 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2141 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2142 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2143 2144 // We don't allow third party apps to replace this. 2145 ResolveInfo ri = null; 2146 for (int i=0; ris != null && i<ris.size(); i++) { 2147 if ((ris.get(i).activityInfo.applicationInfo.flags 2148 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2149 ri = ris.get(i); 2150 break; 2151 } 2152 } 2153 2154 if (ri != null) { 2155 String vers = ri.activityInfo.metaData != null 2156 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2157 : null; 2158 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2159 vers = ri.activityInfo.applicationInfo.metaData.getString( 2160 Intent.METADATA_SETUP_VERSION); 2161 } 2162 String lastVers = Settings.Secure.getString( 2163 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2164 if (vers != null && !vers.equals(lastVers)) { 2165 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2166 intent.setComponent(new ComponentName( 2167 ri.activityInfo.packageName, ri.activityInfo.name)); 2168 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2169 null, null, 0, 0, 0, 0, null, false, null); 2170 } 2171 } 2172 } 2173 } 2174 2175 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2176 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2177 } 2178 2179 void enforceNotIsolatedCaller(String caller) { 2180 if (UserId.isIsolated(Binder.getCallingUid())) { 2181 throw new SecurityException("Isolated process not allowed to call " + caller); 2182 } 2183 } 2184 2185 public int getFrontActivityScreenCompatMode() { 2186 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2187 synchronized (this) { 2188 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2189 } 2190 } 2191 2192 public void setFrontActivityScreenCompatMode(int mode) { 2193 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2194 "setFrontActivityScreenCompatMode"); 2195 synchronized (this) { 2196 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2197 } 2198 } 2199 2200 public int getPackageScreenCompatMode(String packageName) { 2201 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2202 synchronized (this) { 2203 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2204 } 2205 } 2206 2207 public void setPackageScreenCompatMode(String packageName, int mode) { 2208 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2209 "setPackageScreenCompatMode"); 2210 synchronized (this) { 2211 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2212 } 2213 } 2214 2215 public boolean getPackageAskScreenCompat(String packageName) { 2216 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2217 synchronized (this) { 2218 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2219 } 2220 } 2221 2222 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2223 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2224 "setPackageAskScreenCompat"); 2225 synchronized (this) { 2226 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2227 } 2228 } 2229 2230 void reportResumedActivityLocked(ActivityRecord r) { 2231 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2232 updateUsageStats(r, true); 2233 } 2234 2235 private void dispatchProcessesChanged() { 2236 int N; 2237 synchronized (this) { 2238 N = mPendingProcessChanges.size(); 2239 if (mActiveProcessChanges.length < N) { 2240 mActiveProcessChanges = new ProcessChangeItem[N]; 2241 } 2242 mPendingProcessChanges.toArray(mActiveProcessChanges); 2243 mAvailProcessChanges.addAll(mPendingProcessChanges); 2244 mPendingProcessChanges.clear(); 2245 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2246 } 2247 int i = mProcessObservers.beginBroadcast(); 2248 while (i > 0) { 2249 i--; 2250 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2251 if (observer != null) { 2252 try { 2253 for (int j=0; j<N; j++) { 2254 ProcessChangeItem item = mActiveProcessChanges[j]; 2255 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2256 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2257 + item.pid + " uid=" + item.uid + ": " 2258 + item.foregroundActivities); 2259 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2260 item.foregroundActivities); 2261 } 2262 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2263 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2264 + item.pid + " uid=" + item.uid + ": " + item.importance); 2265 observer.onImportanceChanged(item.pid, item.uid, 2266 item.importance); 2267 } 2268 } 2269 } catch (RemoteException e) { 2270 } 2271 } 2272 } 2273 mProcessObservers.finishBroadcast(); 2274 } 2275 2276 private void dispatchProcessDied(int pid, int uid) { 2277 int i = mProcessObservers.beginBroadcast(); 2278 while (i > 0) { 2279 i--; 2280 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2281 if (observer != null) { 2282 try { 2283 observer.onProcessDied(pid, uid); 2284 } catch (RemoteException e) { 2285 } 2286 } 2287 } 2288 mProcessObservers.finishBroadcast(); 2289 } 2290 2291 final void doPendingActivityLaunchesLocked(boolean doResume) { 2292 final int N = mPendingActivityLaunches.size(); 2293 if (N <= 0) { 2294 return; 2295 } 2296 for (int i=0; i<N; i++) { 2297 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2298 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2299 pal.startFlags, doResume && i == (N-1), null); 2300 } 2301 mPendingActivityLaunches.clear(); 2302 } 2303 2304 public final int startActivity(IApplicationThread caller, 2305 Intent intent, String resolvedType, IBinder resultTo, 2306 String resultWho, int requestCode, int startFlags, 2307 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2308 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2309 startFlags, profileFile, profileFd, options, UserId.getCallingUserId()); 2310 } 2311 2312 public final int startActivityAsUser(IApplicationThread caller, 2313 Intent intent, String resolvedType, IBinder resultTo, 2314 String resultWho, int requestCode, int startFlags, 2315 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2316 enforceNotIsolatedCaller("startActivity"); 2317 if (userId != UserId.getCallingUserId()) { 2318 // Requesting a different user, make sure that they have the permission 2319 if (checkComponentPermission( 2320 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2321 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2322 == PackageManager.PERMISSION_GRANTED) { 2323 // Translate to the current user id, if caller wasn't aware 2324 if (userId == UserId.USER_CURRENT) { 2325 userId = mCurrentUserId; 2326 } 2327 } else { 2328 String msg = "Permission Denial: " 2329 + "Request to startActivity as user " + userId 2330 + " but is calling from user " + UserId.getCallingUserId() 2331 + "; this requires " 2332 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2333 Slog.w(TAG, msg); 2334 throw new SecurityException(msg); 2335 } 2336 } else { 2337 if (intent.getCategories() != null 2338 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2339 // Requesting home, set the identity to the current user 2340 // HACK! 2341 userId = mCurrentUserId; 2342 } else { 2343 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2344 // the current user's userId 2345 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2346 userId = 0; 2347 } else { 2348 userId = Binder.getOrigCallingUser(); 2349 } 2350 } 2351 } 2352 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2353 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2354 null, null, options, userId); 2355 } 2356 2357 public final WaitResult startActivityAndWait(IApplicationThread caller, 2358 Intent intent, String resolvedType, IBinder resultTo, 2359 String resultWho, int requestCode, int startFlags, String profileFile, 2360 ParcelFileDescriptor profileFd, Bundle options) { 2361 enforceNotIsolatedCaller("startActivityAndWait"); 2362 WaitResult res = new WaitResult(); 2363 int userId = Binder.getOrigCallingUser(); 2364 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2365 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2366 res, null, options, userId); 2367 return res; 2368 } 2369 2370 public final int startActivityWithConfig(IApplicationThread caller, 2371 Intent intent, String resolvedType, IBinder resultTo, 2372 String resultWho, int requestCode, int startFlags, Configuration config, 2373 Bundle options) { 2374 enforceNotIsolatedCaller("startActivityWithConfig"); 2375 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2376 resultTo, resultWho, requestCode, startFlags, 2377 null, null, null, config, options, Binder.getOrigCallingUser()); 2378 return ret; 2379 } 2380 2381 public int startActivityIntentSender(IApplicationThread caller, 2382 IntentSender intent, Intent fillInIntent, String resolvedType, 2383 IBinder resultTo, String resultWho, int requestCode, 2384 int flagsMask, int flagsValues, Bundle options) { 2385 enforceNotIsolatedCaller("startActivityIntentSender"); 2386 // Refuse possible leaked file descriptors 2387 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2388 throw new IllegalArgumentException("File descriptors passed in Intent"); 2389 } 2390 2391 IIntentSender sender = intent.getTarget(); 2392 if (!(sender instanceof PendingIntentRecord)) { 2393 throw new IllegalArgumentException("Bad PendingIntent object"); 2394 } 2395 2396 PendingIntentRecord pir = (PendingIntentRecord)sender; 2397 2398 synchronized (this) { 2399 // If this is coming from the currently resumed activity, it is 2400 // effectively saying that app switches are allowed at this point. 2401 if (mMainStack.mResumedActivity != null 2402 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2403 Binder.getCallingUid()) { 2404 mAppSwitchesAllowedTime = 0; 2405 } 2406 } 2407 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2408 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2409 return ret; 2410 } 2411 2412 public boolean startNextMatchingActivity(IBinder callingActivity, 2413 Intent intent, Bundle options) { 2414 // Refuse possible leaked file descriptors 2415 if (intent != null && intent.hasFileDescriptors() == true) { 2416 throw new IllegalArgumentException("File descriptors passed in Intent"); 2417 } 2418 2419 synchronized (this) { 2420 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2421 if (r == null) { 2422 ActivityOptions.abort(options); 2423 return false; 2424 } 2425 if (r.app == null || r.app.thread == null) { 2426 // The caller is not running... d'oh! 2427 ActivityOptions.abort(options); 2428 return false; 2429 } 2430 intent = new Intent(intent); 2431 // The caller is not allowed to change the data. 2432 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2433 // And we are resetting to find the next component... 2434 intent.setComponent(null); 2435 2436 ActivityInfo aInfo = null; 2437 try { 2438 List<ResolveInfo> resolves = 2439 AppGlobals.getPackageManager().queryIntentActivities( 2440 intent, r.resolvedType, 2441 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2442 UserId.getCallingUserId()); 2443 2444 // Look for the original activity in the list... 2445 final int N = resolves != null ? resolves.size() : 0; 2446 for (int i=0; i<N; i++) { 2447 ResolveInfo rInfo = resolves.get(i); 2448 if (rInfo.activityInfo.packageName.equals(r.packageName) 2449 && rInfo.activityInfo.name.equals(r.info.name)) { 2450 // We found the current one... the next matching is 2451 // after it. 2452 i++; 2453 if (i<N) { 2454 aInfo = resolves.get(i).activityInfo; 2455 } 2456 break; 2457 } 2458 } 2459 } catch (RemoteException e) { 2460 } 2461 2462 if (aInfo == null) { 2463 // Nobody who is next! 2464 ActivityOptions.abort(options); 2465 return false; 2466 } 2467 2468 intent.setComponent(new ComponentName( 2469 aInfo.applicationInfo.packageName, aInfo.name)); 2470 intent.setFlags(intent.getFlags()&~( 2471 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2472 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2473 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2474 Intent.FLAG_ACTIVITY_NEW_TASK)); 2475 2476 // Okay now we need to start the new activity, replacing the 2477 // currently running activity. This is a little tricky because 2478 // we want to start the new one as if the current one is finished, 2479 // but not finish the current one first so that there is no flicker. 2480 // And thus... 2481 final boolean wasFinishing = r.finishing; 2482 r.finishing = true; 2483 2484 // Propagate reply information over to the new activity. 2485 final ActivityRecord resultTo = r.resultTo; 2486 final String resultWho = r.resultWho; 2487 final int requestCode = r.requestCode; 2488 r.resultTo = null; 2489 if (resultTo != null) { 2490 resultTo.removeResultsLocked(r, resultWho, requestCode); 2491 } 2492 2493 final long origId = Binder.clearCallingIdentity(); 2494 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2495 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2496 resultWho, requestCode, -1, r.launchedFromUid, 0, 2497 options, false, null); 2498 Binder.restoreCallingIdentity(origId); 2499 2500 r.finishing = wasFinishing; 2501 if (res != ActivityManager.START_SUCCESS) { 2502 return false; 2503 } 2504 return true; 2505 } 2506 } 2507 2508 public final int startActivityInPackage(int uid, 2509 Intent intent, String resolvedType, IBinder resultTo, 2510 String resultWho, int requestCode, int startFlags, Bundle options) { 2511 2512 // This is so super not safe, that only the system (or okay root) 2513 // can do it. 2514 int userId = Binder.getOrigCallingUser(); 2515 final int callingUid = Binder.getCallingUid(); 2516 if (callingUid != 0 && callingUid != Process.myUid()) { 2517 throw new SecurityException( 2518 "startActivityInPackage only available to the system"); 2519 } 2520 2521 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2522 resultTo, resultWho, requestCode, startFlags, 2523 null, null, null, null, options, userId); 2524 return ret; 2525 } 2526 2527 public final int startActivities(IApplicationThread caller, 2528 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2529 enforceNotIsolatedCaller("startActivities"); 2530 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2531 options, Binder.getOrigCallingUser()); 2532 return ret; 2533 } 2534 2535 public final int startActivitiesInPackage(int uid, 2536 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2537 Bundle options) { 2538 2539 // This is so super not safe, that only the system (or okay root) 2540 // can do it. 2541 final int callingUid = Binder.getCallingUid(); 2542 if (callingUid != 0 && callingUid != Process.myUid()) { 2543 throw new SecurityException( 2544 "startActivityInPackage only available to the system"); 2545 } 2546 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2547 options, UserId.getUserId(uid)); 2548 return ret; 2549 } 2550 2551 final void addRecentTaskLocked(TaskRecord task) { 2552 int N = mRecentTasks.size(); 2553 // Quick case: check if the top-most recent task is the same. 2554 if (N > 0 && mRecentTasks.get(0) == task) { 2555 return; 2556 } 2557 // Remove any existing entries that are the same kind of task. 2558 for (int i=0; i<N; i++) { 2559 TaskRecord tr = mRecentTasks.get(i); 2560 if (task.userId == tr.userId 2561 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2562 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2563 mRecentTasks.remove(i); 2564 i--; 2565 N--; 2566 if (task.intent == null) { 2567 // If the new recent task we are adding is not fully 2568 // specified, then replace it with the existing recent task. 2569 task = tr; 2570 } 2571 } 2572 } 2573 if (N >= MAX_RECENT_TASKS) { 2574 mRecentTasks.remove(N-1); 2575 } 2576 mRecentTasks.add(0, task); 2577 } 2578 2579 public void setRequestedOrientation(IBinder token, 2580 int requestedOrientation) { 2581 synchronized (this) { 2582 ActivityRecord r = mMainStack.isInStackLocked(token); 2583 if (r == null) { 2584 return; 2585 } 2586 final long origId = Binder.clearCallingIdentity(); 2587 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2588 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2589 mConfiguration, 2590 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2591 if (config != null) { 2592 r.frozenBeforeDestroy = true; 2593 if (!updateConfigurationLocked(config, r, false, false)) { 2594 mMainStack.resumeTopActivityLocked(null); 2595 } 2596 } 2597 Binder.restoreCallingIdentity(origId); 2598 } 2599 } 2600 2601 public int getRequestedOrientation(IBinder token) { 2602 synchronized (this) { 2603 ActivityRecord r = mMainStack.isInStackLocked(token); 2604 if (r == null) { 2605 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2606 } 2607 return mWindowManager.getAppOrientation(r.appToken); 2608 } 2609 } 2610 2611 /** 2612 * This is the internal entry point for handling Activity.finish(). 2613 * 2614 * @param token The Binder token referencing the Activity we want to finish. 2615 * @param resultCode Result code, if any, from this Activity. 2616 * @param resultData Result data (Intent), if any, from this Activity. 2617 * 2618 * @return Returns true if the activity successfully finished, or false if it is still running. 2619 */ 2620 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2621 // Refuse possible leaked file descriptors 2622 if (resultData != null && resultData.hasFileDescriptors() == true) { 2623 throw new IllegalArgumentException("File descriptors passed in Intent"); 2624 } 2625 2626 synchronized(this) { 2627 if (mController != null) { 2628 // Find the first activity that is not finishing. 2629 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2630 if (next != null) { 2631 // ask watcher if this is allowed 2632 boolean resumeOK = true; 2633 try { 2634 resumeOK = mController.activityResuming(next.packageName); 2635 } catch (RemoteException e) { 2636 mController = null; 2637 } 2638 2639 if (!resumeOK) { 2640 return false; 2641 } 2642 } 2643 } 2644 final long origId = Binder.clearCallingIdentity(); 2645 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2646 resultData, "app-request"); 2647 Binder.restoreCallingIdentity(origId); 2648 return res; 2649 } 2650 } 2651 2652 public final void finishHeavyWeightApp() { 2653 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2654 != PackageManager.PERMISSION_GRANTED) { 2655 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2656 + Binder.getCallingPid() 2657 + ", uid=" + Binder.getCallingUid() 2658 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2659 Slog.w(TAG, msg); 2660 throw new SecurityException(msg); 2661 } 2662 2663 synchronized(this) { 2664 if (mHeavyWeightProcess == null) { 2665 return; 2666 } 2667 2668 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2669 mHeavyWeightProcess.activities); 2670 for (int i=0; i<activities.size(); i++) { 2671 ActivityRecord r = activities.get(i); 2672 if (!r.finishing) { 2673 int index = mMainStack.indexOfTokenLocked(r.appToken); 2674 if (index >= 0) { 2675 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2676 null, "finish-heavy"); 2677 } 2678 } 2679 } 2680 2681 mHeavyWeightProcess = null; 2682 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2683 } 2684 } 2685 2686 public void crashApplication(int uid, int initialPid, String packageName, 2687 String message) { 2688 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2689 != PackageManager.PERMISSION_GRANTED) { 2690 String msg = "Permission Denial: crashApplication() from pid=" 2691 + Binder.getCallingPid() 2692 + ", uid=" + Binder.getCallingUid() 2693 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2694 Slog.w(TAG, msg); 2695 throw new SecurityException(msg); 2696 } 2697 2698 synchronized(this) { 2699 ProcessRecord proc = null; 2700 2701 // Figure out which process to kill. We don't trust that initialPid 2702 // still has any relation to current pids, so must scan through the 2703 // list. 2704 synchronized (mPidsSelfLocked) { 2705 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2706 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2707 if (p.uid != uid) { 2708 continue; 2709 } 2710 if (p.pid == initialPid) { 2711 proc = p; 2712 break; 2713 } 2714 for (String str : p.pkgList) { 2715 if (str.equals(packageName)) { 2716 proc = p; 2717 } 2718 } 2719 } 2720 } 2721 2722 if (proc == null) { 2723 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2724 + " initialPid=" + initialPid 2725 + " packageName=" + packageName); 2726 return; 2727 } 2728 2729 if (proc.thread != null) { 2730 if (proc.pid == Process.myPid()) { 2731 Log.w(TAG, "crashApplication: trying to crash self!"); 2732 return; 2733 } 2734 long ident = Binder.clearCallingIdentity(); 2735 try { 2736 proc.thread.scheduleCrash(message); 2737 } catch (RemoteException e) { 2738 } 2739 Binder.restoreCallingIdentity(ident); 2740 } 2741 } 2742 } 2743 2744 public final void finishSubActivity(IBinder token, String resultWho, 2745 int requestCode) { 2746 synchronized(this) { 2747 final long origId = Binder.clearCallingIdentity(); 2748 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2749 Binder.restoreCallingIdentity(origId); 2750 } 2751 } 2752 2753 public boolean finishActivityAffinity(IBinder token) { 2754 synchronized(this) { 2755 final long origId = Binder.clearCallingIdentity(); 2756 boolean res = mMainStack.finishActivityAffinityLocked(token); 2757 Binder.restoreCallingIdentity(origId); 2758 return res; 2759 } 2760 } 2761 2762 public boolean willActivityBeVisible(IBinder token) { 2763 synchronized(this) { 2764 int i; 2765 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2766 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2767 if (r.appToken == token) { 2768 return true; 2769 } 2770 if (r.fullscreen && !r.finishing) { 2771 return false; 2772 } 2773 } 2774 return true; 2775 } 2776 } 2777 2778 public void overridePendingTransition(IBinder token, String packageName, 2779 int enterAnim, int exitAnim) { 2780 synchronized(this) { 2781 ActivityRecord self = mMainStack.isInStackLocked(token); 2782 if (self == null) { 2783 return; 2784 } 2785 2786 final long origId = Binder.clearCallingIdentity(); 2787 2788 if (self.state == ActivityState.RESUMED 2789 || self.state == ActivityState.PAUSING) { 2790 mWindowManager.overridePendingAppTransition(packageName, 2791 enterAnim, exitAnim, null); 2792 } 2793 2794 Binder.restoreCallingIdentity(origId); 2795 } 2796 } 2797 2798 /** 2799 * Main function for removing an existing process from the activity manager 2800 * as a result of that process going away. Clears out all connections 2801 * to the process. 2802 */ 2803 private final void handleAppDiedLocked(ProcessRecord app, 2804 boolean restarting, boolean allowRestart) { 2805 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2806 if (!restarting) { 2807 mLruProcesses.remove(app); 2808 } 2809 2810 if (mProfileProc == app) { 2811 clearProfilerLocked(); 2812 } 2813 2814 // Just in case... 2815 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2816 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2817 mMainStack.mPausingActivity = null; 2818 } 2819 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2820 mMainStack.mLastPausedActivity = null; 2821 } 2822 2823 // Remove this application's activities from active lists. 2824 mMainStack.removeHistoryRecordsForAppLocked(app); 2825 2826 boolean atTop = true; 2827 boolean hasVisibleActivities = false; 2828 2829 // Clean out the history list. 2830 int i = mMainStack.mHistory.size(); 2831 if (localLOGV) Slog.v( 2832 TAG, "Removing app " + app + " from history with " + i + " entries"); 2833 while (i > 0) { 2834 i--; 2835 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2836 if (localLOGV) Slog.v( 2837 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2838 if (r.app == app) { 2839 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2840 if (ActivityStack.DEBUG_ADD_REMOVE) { 2841 RuntimeException here = new RuntimeException("here"); 2842 here.fillInStackTrace(); 2843 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2844 + ": haveState=" + r.haveState 2845 + " stateNotNeeded=" + r.stateNotNeeded 2846 + " finishing=" + r.finishing 2847 + " state=" + r.state, here); 2848 } 2849 if (!r.finishing) { 2850 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2851 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2852 System.identityHashCode(r), 2853 r.task.taskId, r.shortComponentName, 2854 "proc died without state saved"); 2855 } 2856 mMainStack.removeActivityFromHistoryLocked(r); 2857 2858 } else { 2859 // We have the current state for this activity, so 2860 // it can be restarted later when needed. 2861 if (localLOGV) Slog.v( 2862 TAG, "Keeping entry, setting app to null"); 2863 if (r.visible) { 2864 hasVisibleActivities = true; 2865 } 2866 r.app = null; 2867 r.nowVisible = false; 2868 if (!r.haveState) { 2869 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2870 "App died, clearing saved state of " + r); 2871 r.icicle = null; 2872 } 2873 } 2874 2875 r.stack.cleanUpActivityLocked(r, true, true); 2876 } 2877 atTop = false; 2878 } 2879 2880 app.activities.clear(); 2881 2882 if (app.instrumentationClass != null) { 2883 Slog.w(TAG, "Crash of app " + app.processName 2884 + " running instrumentation " + app.instrumentationClass); 2885 Bundle info = new Bundle(); 2886 info.putString("shortMsg", "Process crashed."); 2887 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2888 } 2889 2890 if (!restarting) { 2891 if (!mMainStack.resumeTopActivityLocked(null)) { 2892 // If there was nothing to resume, and we are not already 2893 // restarting this process, but there is a visible activity that 2894 // is hosted by the process... then make sure all visible 2895 // activities are running, taking care of restarting this 2896 // process. 2897 if (hasVisibleActivities) { 2898 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2899 } 2900 } 2901 } 2902 } 2903 2904 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2905 IBinder threadBinder = thread.asBinder(); 2906 // Find the application record. 2907 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2908 ProcessRecord rec = mLruProcesses.get(i); 2909 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2910 return i; 2911 } 2912 } 2913 return -1; 2914 } 2915 2916 final ProcessRecord getRecordForAppLocked( 2917 IApplicationThread thread) { 2918 if (thread == null) { 2919 return null; 2920 } 2921 2922 int appIndex = getLRURecordIndexForAppLocked(thread); 2923 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2924 } 2925 2926 final void appDiedLocked(ProcessRecord app, int pid, 2927 IApplicationThread thread) { 2928 2929 mProcDeaths[0]++; 2930 2931 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2932 synchronized (stats) { 2933 stats.noteProcessDiedLocked(app.info.uid, pid); 2934 } 2935 2936 // Clean up already done if the process has been re-started. 2937 if (app.pid == pid && app.thread != null && 2938 app.thread.asBinder() == thread.asBinder()) { 2939 if (!app.killedBackground) { 2940 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2941 + ") has died."); 2942 } 2943 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2944 if (localLOGV) Slog.v( 2945 TAG, "Dying app: " + app + ", pid: " + pid 2946 + ", thread: " + thread.asBinder()); 2947 boolean doLowMem = app.instrumentationClass == null; 2948 handleAppDiedLocked(app, false, true); 2949 2950 if (doLowMem) { 2951 // If there are no longer any background processes running, 2952 // and the app that died was not running instrumentation, 2953 // then tell everyone we are now low on memory. 2954 boolean haveBg = false; 2955 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2956 ProcessRecord rec = mLruProcesses.get(i); 2957 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2958 haveBg = true; 2959 break; 2960 } 2961 } 2962 2963 if (!haveBg) { 2964 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2965 long now = SystemClock.uptimeMillis(); 2966 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2967 ProcessRecord rec = mLruProcesses.get(i); 2968 if (rec != app && rec.thread != null && 2969 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2970 // The low memory report is overriding any current 2971 // state for a GC request. Make sure to do 2972 // heavy/important/visible/foreground processes first. 2973 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2974 rec.lastRequestedGc = 0; 2975 } else { 2976 rec.lastRequestedGc = rec.lastLowMemory; 2977 } 2978 rec.reportLowMemory = true; 2979 rec.lastLowMemory = now; 2980 mProcessesToGc.remove(rec); 2981 addProcessToGcListLocked(rec); 2982 } 2983 } 2984 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 2985 scheduleAppGcsLocked(); 2986 } 2987 } 2988 } else if (app.pid != pid) { 2989 // A new process has already been started. 2990 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2991 + ") has died and restarted (pid " + app.pid + ")."); 2992 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2993 } else if (DEBUG_PROCESSES) { 2994 Slog.d(TAG, "Received spurious death notification for thread " 2995 + thread.asBinder()); 2996 } 2997 } 2998 2999 /** 3000 * If a stack trace dump file is configured, dump process stack traces. 3001 * @param clearTraces causes the dump file to be erased prior to the new 3002 * traces being written, if true; when false, the new traces will be 3003 * appended to any existing file content. 3004 * @param firstPids of dalvik VM processes to dump stack traces for first 3005 * @param lastPids of dalvik VM processes to dump stack traces for last 3006 * @param nativeProcs optional list of native process names to dump stack crawls 3007 * @return file containing stack traces, or null if no dump file is configured 3008 */ 3009 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3010 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3011 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3012 if (tracesPath == null || tracesPath.length() == 0) { 3013 return null; 3014 } 3015 3016 File tracesFile = new File(tracesPath); 3017 try { 3018 File tracesDir = tracesFile.getParentFile(); 3019 if (!tracesDir.exists()) tracesFile.mkdirs(); 3020 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3021 3022 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3023 tracesFile.createNewFile(); 3024 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3025 } catch (IOException e) { 3026 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3027 return null; 3028 } 3029 3030 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3031 return tracesFile; 3032 } 3033 3034 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3035 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3036 // Use a FileObserver to detect when traces finish writing. 3037 // The order of traces is considered important to maintain for legibility. 3038 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3039 public synchronized void onEvent(int event, String path) { notify(); } 3040 }; 3041 3042 try { 3043 observer.startWatching(); 3044 3045 // First collect all of the stacks of the most important pids. 3046 if (firstPids != null) { 3047 try { 3048 int num = firstPids.size(); 3049 for (int i = 0; i < num; i++) { 3050 synchronized (observer) { 3051 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3052 observer.wait(200); // Wait for write-close, give up after 200msec 3053 } 3054 } 3055 } catch (InterruptedException e) { 3056 Log.wtf(TAG, e); 3057 } 3058 } 3059 3060 // Next measure CPU usage. 3061 if (processStats != null) { 3062 processStats.init(); 3063 System.gc(); 3064 processStats.update(); 3065 try { 3066 synchronized (processStats) { 3067 processStats.wait(500); // measure over 1/2 second. 3068 } 3069 } catch (InterruptedException e) { 3070 } 3071 processStats.update(); 3072 3073 // We'll take the stack crawls of just the top apps using CPU. 3074 final int N = processStats.countWorkingStats(); 3075 int numProcs = 0; 3076 for (int i=0; i<N && numProcs<5; i++) { 3077 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3078 if (lastPids.indexOfKey(stats.pid) >= 0) { 3079 numProcs++; 3080 try { 3081 synchronized (observer) { 3082 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3083 observer.wait(200); // Wait for write-close, give up after 200msec 3084 } 3085 } catch (InterruptedException e) { 3086 Log.wtf(TAG, e); 3087 } 3088 3089 } 3090 } 3091 } 3092 3093 } finally { 3094 observer.stopWatching(); 3095 } 3096 3097 if (nativeProcs != null) { 3098 int[] pids = Process.getPidsForCommands(nativeProcs); 3099 if (pids != null) { 3100 for (int pid : pids) { 3101 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3102 } 3103 } 3104 } 3105 } 3106 3107 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3108 if (true || IS_USER_BUILD) { 3109 return; 3110 } 3111 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3112 if (tracesPath == null || tracesPath.length() == 0) { 3113 return; 3114 } 3115 3116 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3117 StrictMode.allowThreadDiskWrites(); 3118 try { 3119 final File tracesFile = new File(tracesPath); 3120 final File tracesDir = tracesFile.getParentFile(); 3121 final File tracesTmp = new File(tracesDir, "__tmp__"); 3122 try { 3123 if (!tracesDir.exists()) tracesFile.mkdirs(); 3124 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3125 3126 if (tracesFile.exists()) { 3127 tracesTmp.delete(); 3128 tracesFile.renameTo(tracesTmp); 3129 } 3130 StringBuilder sb = new StringBuilder(); 3131 Time tobj = new Time(); 3132 tobj.set(System.currentTimeMillis()); 3133 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3134 sb.append(": "); 3135 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3136 sb.append(" since "); 3137 sb.append(msg); 3138 FileOutputStream fos = new FileOutputStream(tracesFile); 3139 fos.write(sb.toString().getBytes()); 3140 if (app == null) { 3141 fos.write("\n*** No application process!".getBytes()); 3142 } 3143 fos.close(); 3144 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3145 } catch (IOException e) { 3146 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3147 return; 3148 } 3149 3150 if (app != null) { 3151 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3152 firstPids.add(app.pid); 3153 dumpStackTraces(tracesPath, firstPids, null, null, null); 3154 } 3155 3156 File lastTracesFile = null; 3157 File curTracesFile = null; 3158 for (int i=9; i>=0; i--) { 3159 String name = String.format("slow%02d.txt", i); 3160 curTracesFile = new File(tracesDir, name); 3161 if (curTracesFile.exists()) { 3162 if (lastTracesFile != null) { 3163 curTracesFile.renameTo(lastTracesFile); 3164 } else { 3165 curTracesFile.delete(); 3166 } 3167 } 3168 lastTracesFile = curTracesFile; 3169 } 3170 tracesFile.renameTo(curTracesFile); 3171 if (tracesTmp.exists()) { 3172 tracesTmp.renameTo(tracesFile); 3173 } 3174 } finally { 3175 StrictMode.setThreadPolicy(oldPolicy); 3176 } 3177 } 3178 3179 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3180 ActivityRecord parent, final String annotation) { 3181 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3182 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3183 3184 if (mController != null) { 3185 try { 3186 // 0 == continue, -1 = kill process immediately 3187 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3188 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3189 } catch (RemoteException e) { 3190 mController = null; 3191 } 3192 } 3193 3194 long anrTime = SystemClock.uptimeMillis(); 3195 if (MONITOR_CPU_USAGE) { 3196 updateCpuStatsNow(); 3197 } 3198 3199 synchronized (this) { 3200 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3201 if (mShuttingDown) { 3202 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3203 return; 3204 } else if (app.notResponding) { 3205 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3206 return; 3207 } else if (app.crashing) { 3208 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3209 return; 3210 } 3211 3212 // In case we come through here for the same app before completing 3213 // this one, mark as anring now so we will bail out. 3214 app.notResponding = true; 3215 3216 // Log the ANR to the event log. 3217 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3218 annotation); 3219 3220 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3221 firstPids.add(app.pid); 3222 3223 int parentPid = app.pid; 3224 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3225 if (parentPid != app.pid) firstPids.add(parentPid); 3226 3227 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3228 3229 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3230 ProcessRecord r = mLruProcesses.get(i); 3231 if (r != null && r.thread != null) { 3232 int pid = r.pid; 3233 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3234 if (r.persistent) { 3235 firstPids.add(pid); 3236 } else { 3237 lastPids.put(pid, Boolean.TRUE); 3238 } 3239 } 3240 } 3241 } 3242 } 3243 3244 // Log the ANR to the main log. 3245 StringBuilder info = new StringBuilder(); 3246 info.setLength(0); 3247 info.append("ANR in ").append(app.processName); 3248 if (activity != null && activity.shortComponentName != null) { 3249 info.append(" (").append(activity.shortComponentName).append(")"); 3250 } 3251 info.append("\n"); 3252 if (annotation != null) { 3253 info.append("Reason: ").append(annotation).append("\n"); 3254 } 3255 if (parent != null && parent != activity) { 3256 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3257 } 3258 3259 final ProcessStats processStats = new ProcessStats(true); 3260 3261 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3262 3263 String cpuInfo = null; 3264 if (MONITOR_CPU_USAGE) { 3265 updateCpuStatsNow(); 3266 synchronized (mProcessStatsThread) { 3267 cpuInfo = mProcessStats.printCurrentState(anrTime); 3268 } 3269 info.append(processStats.printCurrentLoad()); 3270 info.append(cpuInfo); 3271 } 3272 3273 info.append(processStats.printCurrentState(anrTime)); 3274 3275 Slog.e(TAG, info.toString()); 3276 if (tracesFile == null) { 3277 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3278 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3279 } 3280 3281 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3282 cpuInfo, tracesFile, null); 3283 3284 if (mController != null) { 3285 try { 3286 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3287 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3288 if (res != 0) { 3289 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3290 return; 3291 } 3292 } catch (RemoteException e) { 3293 mController = null; 3294 } 3295 } 3296 3297 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3298 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3299 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3300 3301 synchronized (this) { 3302 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3303 Slog.w(TAG, "Killing " + app + ": background ANR"); 3304 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3305 app.processName, app.setAdj, "background ANR"); 3306 Process.killProcessQuiet(app.pid); 3307 return; 3308 } 3309 3310 // Set the app's notResponding state, and look up the errorReportReceiver 3311 makeAppNotRespondingLocked(app, 3312 activity != null ? activity.shortComponentName : null, 3313 annotation != null ? "ANR " + annotation : "ANR", 3314 info.toString()); 3315 3316 // Bring up the infamous App Not Responding dialog 3317 Message msg = Message.obtain(); 3318 HashMap map = new HashMap(); 3319 msg.what = SHOW_NOT_RESPONDING_MSG; 3320 msg.obj = map; 3321 map.put("app", app); 3322 if (activity != null) { 3323 map.put("activity", activity); 3324 } 3325 3326 mHandler.sendMessage(msg); 3327 } 3328 } 3329 3330 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3331 if (!mLaunchWarningShown) { 3332 mLaunchWarningShown = true; 3333 mHandler.post(new Runnable() { 3334 @Override 3335 public void run() { 3336 synchronized (ActivityManagerService.this) { 3337 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3338 d.show(); 3339 mHandler.postDelayed(new Runnable() { 3340 @Override 3341 public void run() { 3342 synchronized (ActivityManagerService.this) { 3343 d.dismiss(); 3344 mLaunchWarningShown = false; 3345 } 3346 } 3347 }, 4000); 3348 } 3349 } 3350 }); 3351 } 3352 } 3353 3354 public boolean clearApplicationUserData(final String packageName, 3355 final IPackageDataObserver observer, final int userId) { 3356 enforceNotIsolatedCaller("clearApplicationUserData"); 3357 int uid = Binder.getCallingUid(); 3358 int pid = Binder.getCallingPid(); 3359 long callingId = Binder.clearCallingIdentity(); 3360 try { 3361 IPackageManager pm = AppGlobals.getPackageManager(); 3362 int pkgUid = -1; 3363 synchronized(this) { 3364 try { 3365 pkgUid = pm.getPackageUid(packageName, userId); 3366 } catch (RemoteException e) { 3367 } 3368 if (pkgUid == -1) { 3369 Slog.w(TAG, "Invalid packageName:" + packageName); 3370 return false; 3371 } 3372 if (uid == pkgUid || checkComponentPermission( 3373 android.Manifest.permission.CLEAR_APP_USER_DATA, 3374 pid, uid, -1, true) 3375 == PackageManager.PERMISSION_GRANTED) { 3376 forceStopPackageLocked(packageName, pkgUid); 3377 } else { 3378 throw new SecurityException(pid+" does not have permission:"+ 3379 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3380 "for process:"+packageName); 3381 } 3382 } 3383 3384 try { 3385 //clear application user data 3386 pm.clearApplicationUserData(packageName, observer, userId); 3387 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3388 Uri.fromParts("package", packageName, null)); 3389 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3390 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3391 null, null, 0, null, null, null, false, false, userId); 3392 } catch (RemoteException e) { 3393 } 3394 } finally { 3395 Binder.restoreCallingIdentity(callingId); 3396 } 3397 return true; 3398 } 3399 3400 public void killBackgroundProcesses(final String packageName) { 3401 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3402 != PackageManager.PERMISSION_GRANTED && 3403 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3404 != PackageManager.PERMISSION_GRANTED) { 3405 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3406 + Binder.getCallingPid() 3407 + ", uid=" + Binder.getCallingUid() 3408 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3409 Slog.w(TAG, msg); 3410 throw new SecurityException(msg); 3411 } 3412 3413 int userId = UserId.getCallingUserId(); 3414 long callingId = Binder.clearCallingIdentity(); 3415 try { 3416 IPackageManager pm = AppGlobals.getPackageManager(); 3417 int pkgUid = -1; 3418 synchronized(this) { 3419 try { 3420 pkgUid = pm.getPackageUid(packageName, userId); 3421 } catch (RemoteException e) { 3422 } 3423 if (pkgUid == -1) { 3424 Slog.w(TAG, "Invalid packageName: " + packageName); 3425 return; 3426 } 3427 killPackageProcessesLocked(packageName, pkgUid, 3428 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3429 } 3430 } finally { 3431 Binder.restoreCallingIdentity(callingId); 3432 } 3433 } 3434 3435 public void killAllBackgroundProcesses() { 3436 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3437 != PackageManager.PERMISSION_GRANTED) { 3438 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3439 + Binder.getCallingPid() 3440 + ", uid=" + Binder.getCallingUid() 3441 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3442 Slog.w(TAG, msg); 3443 throw new SecurityException(msg); 3444 } 3445 3446 long callingId = Binder.clearCallingIdentity(); 3447 try { 3448 synchronized(this) { 3449 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3450 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3451 final int NA = apps.size(); 3452 for (int ia=0; ia<NA; ia++) { 3453 ProcessRecord app = apps.valueAt(ia); 3454 if (app.persistent) { 3455 // we don't kill persistent processes 3456 continue; 3457 } 3458 if (app.removed) { 3459 procs.add(app); 3460 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3461 app.removed = true; 3462 procs.add(app); 3463 } 3464 } 3465 } 3466 3467 int N = procs.size(); 3468 for (int i=0; i<N; i++) { 3469 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3470 } 3471 } 3472 } finally { 3473 Binder.restoreCallingIdentity(callingId); 3474 } 3475 } 3476 3477 public void forceStopPackage(final String packageName) { 3478 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3479 != PackageManager.PERMISSION_GRANTED) { 3480 String msg = "Permission Denial: forceStopPackage() from pid=" 3481 + Binder.getCallingPid() 3482 + ", uid=" + Binder.getCallingUid() 3483 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3484 Slog.w(TAG, msg); 3485 throw new SecurityException(msg); 3486 } 3487 final int userId = UserId.getCallingUserId(); 3488 long callingId = Binder.clearCallingIdentity(); 3489 try { 3490 IPackageManager pm = AppGlobals.getPackageManager(); 3491 int pkgUid = -1; 3492 synchronized(this) { 3493 try { 3494 pkgUid = pm.getPackageUid(packageName, userId); 3495 } catch (RemoteException e) { 3496 } 3497 if (pkgUid == -1) { 3498 Slog.w(TAG, "Invalid packageName: " + packageName); 3499 return; 3500 } 3501 forceStopPackageLocked(packageName, pkgUid); 3502 try { 3503 pm.setPackageStoppedState(packageName, true, userId); 3504 } catch (RemoteException e) { 3505 } catch (IllegalArgumentException e) { 3506 Slog.w(TAG, "Failed trying to unstop package " 3507 + packageName + ": " + e); 3508 } 3509 } 3510 } finally { 3511 Binder.restoreCallingIdentity(callingId); 3512 } 3513 } 3514 3515 /* 3516 * The pkg name and uid have to be specified. 3517 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3518 */ 3519 public void killApplicationWithUid(String pkg, int uid) { 3520 if (pkg == null) { 3521 return; 3522 } 3523 // Make sure the uid is valid. 3524 if (uid < 0) { 3525 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3526 return; 3527 } 3528 int callerUid = Binder.getCallingUid(); 3529 // Only the system server can kill an application 3530 if (callerUid == Process.SYSTEM_UID) { 3531 // Post an aysnc message to kill the application 3532 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3533 msg.arg1 = uid; 3534 msg.arg2 = 0; 3535 msg.obj = pkg; 3536 mHandler.sendMessage(msg); 3537 } else { 3538 throw new SecurityException(callerUid + " cannot kill pkg: " + 3539 pkg); 3540 } 3541 } 3542 3543 public void closeSystemDialogs(String reason) { 3544 enforceNotIsolatedCaller("closeSystemDialogs"); 3545 3546 final int uid = Binder.getCallingUid(); 3547 final long origId = Binder.clearCallingIdentity(); 3548 synchronized (this) { 3549 closeSystemDialogsLocked(uid, reason); 3550 } 3551 Binder.restoreCallingIdentity(origId); 3552 } 3553 3554 void closeSystemDialogsLocked(int callingUid, String reason) { 3555 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3557 if (reason != null) { 3558 intent.putExtra("reason", reason); 3559 } 3560 mWindowManager.closeSystemDialogs(reason); 3561 3562 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3563 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3564 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3565 r.stack.finishActivityLocked(r, i, 3566 Activity.RESULT_CANCELED, null, "close-sys"); 3567 } 3568 } 3569 3570 broadcastIntentLocked(null, null, intent, null, 3571 null, 0, null, null, null, false, false, -1, 3572 callingUid, 0 /* TODO: Verify */); 3573 } 3574 3575 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3576 throws RemoteException { 3577 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3578 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3579 for (int i=pids.length-1; i>=0; i--) { 3580 infos[i] = new Debug.MemoryInfo(); 3581 Debug.getMemoryInfo(pids[i], infos[i]); 3582 } 3583 return infos; 3584 } 3585 3586 public long[] getProcessPss(int[] pids) throws RemoteException { 3587 enforceNotIsolatedCaller("getProcessPss"); 3588 long[] pss = new long[pids.length]; 3589 for (int i=pids.length-1; i>=0; i--) { 3590 pss[i] = Debug.getPss(pids[i]); 3591 } 3592 return pss; 3593 } 3594 3595 public void killApplicationProcess(String processName, int uid) { 3596 if (processName == null) { 3597 return; 3598 } 3599 3600 int callerUid = Binder.getCallingUid(); 3601 // Only the system server can kill an application 3602 if (callerUid == Process.SYSTEM_UID) { 3603 synchronized (this) { 3604 ProcessRecord app = getProcessRecordLocked(processName, uid); 3605 if (app != null && app.thread != null) { 3606 try { 3607 app.thread.scheduleSuicide(); 3608 } catch (RemoteException e) { 3609 // If the other end already died, then our work here is done. 3610 } 3611 } else { 3612 Slog.w(TAG, "Process/uid not found attempting kill of " 3613 + processName + " / " + uid); 3614 } 3615 } 3616 } else { 3617 throw new SecurityException(callerUid + " cannot kill app process: " + 3618 processName); 3619 } 3620 } 3621 3622 private void forceStopPackageLocked(final String packageName, int uid) { 3623 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); 3624 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3625 Uri.fromParts("package", packageName, null)); 3626 if (!mProcessesReady) { 3627 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3628 } 3629 intent.putExtra(Intent.EXTRA_UID, uid); 3630 broadcastIntentLocked(null, null, intent, 3631 null, null, 0, null, null, null, 3632 false, false, 3633 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid)); 3634 } 3635 3636 private final boolean killPackageProcessesLocked(String packageName, int uid, 3637 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3638 boolean evenPersistent, String reason) { 3639 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3640 3641 // Remove all processes this package may have touched: all with the 3642 // same UID (except for the system or root user), and all whose name 3643 // matches the package name. 3644 final String procNamePrefix = packageName + ":"; 3645 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3646 final int NA = apps.size(); 3647 for (int ia=0; ia<NA; ia++) { 3648 ProcessRecord app = apps.valueAt(ia); 3649 if (app.persistent && !evenPersistent) { 3650 // we don't kill persistent processes 3651 continue; 3652 } 3653 if (app.removed) { 3654 if (doit) { 3655 procs.add(app); 3656 } 3657 // If uid is specified and the uid and process name match 3658 // Or, the uid is not specified and the process name matches 3659 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3660 || ((app.processName.equals(packageName) 3661 || app.processName.startsWith(procNamePrefix)) 3662 && uid < 0))) { 3663 if (app.setAdj >= minOomAdj) { 3664 if (!doit) { 3665 return true; 3666 } 3667 app.removed = true; 3668 procs.add(app); 3669 } 3670 } 3671 } 3672 } 3673 3674 int N = procs.size(); 3675 for (int i=0; i<N; i++) { 3676 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3677 } 3678 return N > 0; 3679 } 3680 3681 private final boolean forceStopPackageLocked(String name, int uid, 3682 boolean callerWillRestart, boolean purgeCache, boolean doit, 3683 boolean evenPersistent, int userId) { 3684 int i; 3685 int N; 3686 3687 if (uid < 0) { 3688 try { 3689 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3690 } catch (RemoteException e) { 3691 } 3692 } 3693 3694 if (doit) { 3695 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3696 3697 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3698 while (badApps.hasNext()) { 3699 SparseArray<Long> ba = badApps.next(); 3700 if (ba.get(uid) != null) { 3701 badApps.remove(); 3702 } 3703 } 3704 } 3705 3706 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3707 callerWillRestart, false, doit, evenPersistent, "force stop"); 3708 3709 TaskRecord lastTask = null; 3710 for (i=0; i<mMainStack.mHistory.size(); i++) { 3711 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3712 final boolean samePackage = r.packageName.equals(name); 3713 if (r.userId == userId 3714 && (samePackage || r.task == lastTask) 3715 && (r.app == null || evenPersistent || !r.app.persistent)) { 3716 if (!doit) { 3717 if (r.finishing) { 3718 // If this activity is just finishing, then it is not 3719 // interesting as far as something to stop. 3720 continue; 3721 } 3722 return true; 3723 } 3724 didSomething = true; 3725 Slog.i(TAG, " Force finishing activity " + r); 3726 if (samePackage) { 3727 if (r.app != null) { 3728 r.app.removed = true; 3729 } 3730 r.app = null; 3731 } 3732 lastTask = r.task; 3733 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3734 null, "force-stop", true)) { 3735 i--; 3736 } 3737 } 3738 } 3739 3740 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3741 if (!doit) { 3742 return true; 3743 } 3744 didSomething = true; 3745 } 3746 3747 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3748 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3749 if (provider.info.packageName.equals(name) 3750 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3751 if (!doit) { 3752 return true; 3753 } 3754 didSomething = true; 3755 providers.add(provider); 3756 } 3757 } 3758 3759 N = providers.size(); 3760 for (i=0; i<N; i++) { 3761 removeDyingProviderLocked(null, providers.get(i), true); 3762 } 3763 3764 if (doit) { 3765 if (purgeCache) { 3766 AttributeCache ac = AttributeCache.instance(); 3767 if (ac != null) { 3768 ac.removePackage(name); 3769 } 3770 } 3771 if (mBooted) { 3772 mMainStack.resumeTopActivityLocked(null); 3773 mMainStack.scheduleIdleLocked(); 3774 } 3775 } 3776 3777 return didSomething; 3778 } 3779 3780 private final boolean removeProcessLocked(ProcessRecord app, 3781 boolean callerWillRestart, boolean allowRestart, String reason) { 3782 final String name = app.processName; 3783 final int uid = app.uid; 3784 if (DEBUG_PROCESSES) Slog.d( 3785 TAG, "Force removing proc " + app.toShortString() + " (" + name 3786 + "/" + uid + ")"); 3787 3788 mProcessNames.remove(name, uid); 3789 mIsolatedProcesses.remove(app.uid); 3790 if (mHeavyWeightProcess == app) { 3791 mHeavyWeightProcess = null; 3792 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3793 } 3794 boolean needRestart = false; 3795 if (app.pid > 0 && app.pid != MY_PID) { 3796 int pid = app.pid; 3797 synchronized (mPidsSelfLocked) { 3798 mPidsSelfLocked.remove(pid); 3799 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3800 } 3801 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3802 handleAppDiedLocked(app, true, allowRestart); 3803 mLruProcesses.remove(app); 3804 Process.killProcessQuiet(pid); 3805 3806 if (app.persistent && !app.isolated) { 3807 if (!callerWillRestart) { 3808 addAppLocked(app.info, false); 3809 } else { 3810 needRestart = true; 3811 } 3812 } 3813 } else { 3814 mRemovedProcesses.add(app); 3815 } 3816 3817 return needRestart; 3818 } 3819 3820 private final void processStartTimedOutLocked(ProcessRecord app) { 3821 final int pid = app.pid; 3822 boolean gone = false; 3823 synchronized (mPidsSelfLocked) { 3824 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3825 if (knownApp != null && knownApp.thread == null) { 3826 mPidsSelfLocked.remove(pid); 3827 gone = true; 3828 } 3829 } 3830 3831 if (gone) { 3832 Slog.w(TAG, "Process " + app + " failed to attach"); 3833 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3834 app.processName); 3835 mProcessNames.remove(app.processName, app.uid); 3836 mIsolatedProcesses.remove(app.uid); 3837 if (mHeavyWeightProcess == app) { 3838 mHeavyWeightProcess = null; 3839 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3840 } 3841 // Take care of any launching providers waiting for this process. 3842 checkAppInLaunchingProvidersLocked(app, true); 3843 // Take care of any services that are waiting for the process. 3844 mServices.processStartTimedOutLocked(app); 3845 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3846 app.processName, app.setAdj, "start timeout"); 3847 Process.killProcessQuiet(pid); 3848 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3849 Slog.w(TAG, "Unattached app died before backup, skipping"); 3850 try { 3851 IBackupManager bm = IBackupManager.Stub.asInterface( 3852 ServiceManager.getService(Context.BACKUP_SERVICE)); 3853 bm.agentDisconnected(app.info.packageName); 3854 } catch (RemoteException e) { 3855 // Can't happen; the backup manager is local 3856 } 3857 } 3858 if (isPendingBroadcastProcessLocked(pid)) { 3859 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3860 skipPendingBroadcastLocked(pid); 3861 } 3862 } else { 3863 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3864 } 3865 } 3866 3867 private final boolean attachApplicationLocked(IApplicationThread thread, 3868 int pid) { 3869 3870 // Find the application record that is being attached... either via 3871 // the pid if we are running in multiple processes, or just pull the 3872 // next app record if we are emulating process with anonymous threads. 3873 ProcessRecord app; 3874 if (pid != MY_PID && pid >= 0) { 3875 synchronized (mPidsSelfLocked) { 3876 app = mPidsSelfLocked.get(pid); 3877 } 3878 } else { 3879 app = null; 3880 } 3881 3882 if (app == null) { 3883 Slog.w(TAG, "No pending application record for pid " + pid 3884 + " (IApplicationThread " + thread + "); dropping process"); 3885 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3886 if (pid > 0 && pid != MY_PID) { 3887 Process.killProcessQuiet(pid); 3888 } else { 3889 try { 3890 thread.scheduleExit(); 3891 } catch (Exception e) { 3892 // Ignore exceptions. 3893 } 3894 } 3895 return false; 3896 } 3897 3898 // If this application record is still attached to a previous 3899 // process, clean it up now. 3900 if (app.thread != null) { 3901 handleAppDiedLocked(app, true, true); 3902 } 3903 3904 // Tell the process all about itself. 3905 3906 if (localLOGV) Slog.v( 3907 TAG, "Binding process pid " + pid + " to record " + app); 3908 3909 String processName = app.processName; 3910 try { 3911 AppDeathRecipient adr = new AppDeathRecipient( 3912 app, pid, thread); 3913 thread.asBinder().linkToDeath(adr, 0); 3914 app.deathRecipient = adr; 3915 } catch (RemoteException e) { 3916 app.resetPackageList(); 3917 startProcessLocked(app, "link fail", processName); 3918 return false; 3919 } 3920 3921 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3922 3923 app.thread = thread; 3924 app.curAdj = app.setAdj = -100; 3925 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3926 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3927 app.forcingToForeground = null; 3928 app.foregroundServices = false; 3929 app.hasShownUi = false; 3930 app.debugging = false; 3931 3932 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3933 3934 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3935 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3936 3937 if (!normalMode) { 3938 Slog.i(TAG, "Launching preboot mode app: " + app); 3939 } 3940 3941 if (localLOGV) Slog.v( 3942 TAG, "New app record " + app 3943 + " thread=" + thread.asBinder() + " pid=" + pid); 3944 try { 3945 int testMode = IApplicationThread.DEBUG_OFF; 3946 if (mDebugApp != null && mDebugApp.equals(processName)) { 3947 testMode = mWaitForDebugger 3948 ? IApplicationThread.DEBUG_WAIT 3949 : IApplicationThread.DEBUG_ON; 3950 app.debugging = true; 3951 if (mDebugTransient) { 3952 mDebugApp = mOrigDebugApp; 3953 mWaitForDebugger = mOrigWaitForDebugger; 3954 } 3955 } 3956 String profileFile = app.instrumentationProfileFile; 3957 ParcelFileDescriptor profileFd = null; 3958 boolean profileAutoStop = false; 3959 if (mProfileApp != null && mProfileApp.equals(processName)) { 3960 mProfileProc = app; 3961 profileFile = mProfileFile; 3962 profileFd = mProfileFd; 3963 profileAutoStop = mAutoStopProfiler; 3964 } 3965 boolean enableOpenGlTrace = false; 3966 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3967 enableOpenGlTrace = true; 3968 mOpenGlTraceApp = null; 3969 } 3970 3971 // If the app is being launched for restore or full backup, set it up specially 3972 boolean isRestrictedBackupMode = false; 3973 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3974 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3975 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3976 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3977 } 3978 3979 ensurePackageDexOpt(app.instrumentationInfo != null 3980 ? app.instrumentationInfo.packageName 3981 : app.info.packageName); 3982 if (app.instrumentationClass != null) { 3983 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 3984 } 3985 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 3986 + processName + " with config " + mConfiguration); 3987 ApplicationInfo appInfo = app.instrumentationInfo != null 3988 ? app.instrumentationInfo : app.info; 3989 app.compat = compatibilityInfoForPackageLocked(appInfo); 3990 if (profileFd != null) { 3991 profileFd = profileFd.dup(); 3992 } 3993 thread.bindApplication(processName, appInfo, providers, 3994 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 3995 app.instrumentationArguments, app.instrumentationWatcher, testMode, 3996 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 3997 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 3998 mCoreSettingsObserver.getCoreSettingsLocked()); 3999 updateLruProcessLocked(app, false, true); 4000 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4001 } catch (Exception e) { 4002 // todo: Yikes! What should we do? For now we will try to 4003 // start another process, but that could easily get us in 4004 // an infinite loop of restarting processes... 4005 Slog.w(TAG, "Exception thrown during bind!", e); 4006 4007 app.resetPackageList(); 4008 app.unlinkDeathRecipient(); 4009 startProcessLocked(app, "bind fail", processName); 4010 return false; 4011 } 4012 4013 // Remove this record from the list of starting applications. 4014 mPersistentStartingProcesses.remove(app); 4015 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4016 "Attach application locked removing on hold: " + app); 4017 mProcessesOnHold.remove(app); 4018 4019 boolean badApp = false; 4020 boolean didSomething = false; 4021 4022 // See if the top visible activity is waiting to run in this process... 4023 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4024 if (hr != null && normalMode) { 4025 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4026 && processName.equals(hr.processName)) { 4027 try { 4028 if (mHeadless) { 4029 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4030 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4031 didSomething = true; 4032 } 4033 } catch (Exception e) { 4034 Slog.w(TAG, "Exception in new application when starting activity " 4035 + hr.intent.getComponent().flattenToShortString(), e); 4036 badApp = true; 4037 } 4038 } else { 4039 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4040 } 4041 } 4042 4043 // Find any services that should be running in this process... 4044 if (!badApp) { 4045 try { 4046 didSomething |= mServices.attachApplicationLocked(app, processName); 4047 } catch (Exception e) { 4048 badApp = true; 4049 } 4050 } 4051 4052 // Check if a next-broadcast receiver is in this process... 4053 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4054 try { 4055 didSomething = sendPendingBroadcastsLocked(app); 4056 } catch (Exception e) { 4057 // If the app died trying to launch the receiver we declare it 'bad' 4058 badApp = true; 4059 } 4060 } 4061 4062 // Check whether the next backup agent is in this process... 4063 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4064 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4065 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4066 try { 4067 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4068 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4069 mBackupTarget.backupMode); 4070 } catch (Exception e) { 4071 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4072 e.printStackTrace(); 4073 } 4074 } 4075 4076 if (badApp) { 4077 // todo: Also need to kill application to deal with all 4078 // kinds of exceptions. 4079 handleAppDiedLocked(app, false, true); 4080 return false; 4081 } 4082 4083 if (!didSomething) { 4084 updateOomAdjLocked(); 4085 } 4086 4087 return true; 4088 } 4089 4090 public final void attachApplication(IApplicationThread thread) { 4091 synchronized (this) { 4092 int callingPid = Binder.getCallingPid(); 4093 final long origId = Binder.clearCallingIdentity(); 4094 attachApplicationLocked(thread, callingPid); 4095 Binder.restoreCallingIdentity(origId); 4096 } 4097 } 4098 4099 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4100 final long origId = Binder.clearCallingIdentity(); 4101 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4102 if (stopProfiling) { 4103 synchronized (this) { 4104 if (mProfileProc == r.app) { 4105 if (mProfileFd != null) { 4106 try { 4107 mProfileFd.close(); 4108 } catch (IOException e) { 4109 } 4110 clearProfilerLocked(); 4111 } 4112 } 4113 } 4114 } 4115 Binder.restoreCallingIdentity(origId); 4116 } 4117 4118 void enableScreenAfterBoot() { 4119 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4120 SystemClock.uptimeMillis()); 4121 mWindowManager.enableScreenAfterBoot(); 4122 4123 synchronized (this) { 4124 updateEventDispatchingLocked(); 4125 } 4126 } 4127 4128 public void showBootMessage(final CharSequence msg, final boolean always) { 4129 enforceNotIsolatedCaller("showBootMessage"); 4130 mWindowManager.showBootMessage(msg, always); 4131 } 4132 4133 public void dismissKeyguardOnNextActivity() { 4134 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4135 final long token = Binder.clearCallingIdentity(); 4136 try { 4137 synchronized (this) { 4138 if (mLockScreenShown) { 4139 mLockScreenShown = false; 4140 comeOutOfSleepIfNeededLocked(); 4141 } 4142 mMainStack.dismissKeyguardOnNextActivityLocked(); 4143 } 4144 } finally { 4145 Binder.restoreCallingIdentity(token); 4146 } 4147 } 4148 4149 final void finishBooting() { 4150 IntentFilter pkgFilter = new IntentFilter(); 4151 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4152 pkgFilter.addDataScheme("package"); 4153 mContext.registerReceiver(new BroadcastReceiver() { 4154 @Override 4155 public void onReceive(Context context, Intent intent) { 4156 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4157 if (pkgs != null) { 4158 for (String pkg : pkgs) { 4159 synchronized (ActivityManagerService.this) { 4160 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4161 setResultCode(Activity.RESULT_OK); 4162 return; 4163 } 4164 } 4165 } 4166 } 4167 } 4168 }, pkgFilter); 4169 4170 IntentFilter userFilter = new IntentFilter(); 4171 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4172 mContext.registerReceiver(new BroadcastReceiver() { 4173 @Override 4174 public void onReceive(Context context, Intent intent) { 4175 onUserRemoved(intent); 4176 } 4177 }, userFilter); 4178 4179 synchronized (this) { 4180 // Ensure that any processes we had put on hold are now started 4181 // up. 4182 final int NP = mProcessesOnHold.size(); 4183 if (NP > 0) { 4184 ArrayList<ProcessRecord> procs = 4185 new ArrayList<ProcessRecord>(mProcessesOnHold); 4186 for (int ip=0; ip<NP; ip++) { 4187 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4188 + procs.get(ip)); 4189 startProcessLocked(procs.get(ip), "on-hold", null); 4190 } 4191 } 4192 4193 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4194 // Start looking for apps that are abusing wake locks. 4195 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4196 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4197 // Tell anyone interested that we are done booting! 4198 SystemProperties.set("sys.boot_completed", "1"); 4199 SystemProperties.set("dev.bootcomplete", "1"); 4200 /* TODO: Send this to all users that are to be logged in on startup */ 4201 broadcastIntentLocked(null, null, 4202 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4203 null, null, 0, null, null, 4204 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4205 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser()); 4206 } 4207 } 4208 } 4209 4210 final void ensureBootCompleted() { 4211 boolean booting; 4212 boolean enableScreen; 4213 synchronized (this) { 4214 booting = mBooting; 4215 mBooting = false; 4216 enableScreen = !mBooted; 4217 mBooted = true; 4218 } 4219 4220 if (booting) { 4221 finishBooting(); 4222 } 4223 4224 if (enableScreen) { 4225 enableScreenAfterBoot(); 4226 } 4227 } 4228 4229 public final void activityPaused(IBinder token) { 4230 final long origId = Binder.clearCallingIdentity(); 4231 mMainStack.activityPaused(token, false); 4232 Binder.restoreCallingIdentity(origId); 4233 } 4234 4235 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4236 CharSequence description) { 4237 if (localLOGV) Slog.v( 4238 TAG, "Activity stopped: token=" + token); 4239 4240 // Refuse possible leaked file descriptors 4241 if (icicle != null && icicle.hasFileDescriptors()) { 4242 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4243 } 4244 4245 ActivityRecord r = null; 4246 4247 final long origId = Binder.clearCallingIdentity(); 4248 4249 synchronized (this) { 4250 r = mMainStack.isInStackLocked(token); 4251 if (r != null) { 4252 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4253 } 4254 } 4255 4256 if (r != null) { 4257 sendPendingThumbnail(r, null, null, null, false); 4258 } 4259 4260 trimApplications(); 4261 4262 Binder.restoreCallingIdentity(origId); 4263 } 4264 4265 public final void activityDestroyed(IBinder token) { 4266 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4267 mMainStack.activityDestroyed(token); 4268 } 4269 4270 public String getCallingPackage(IBinder token) { 4271 synchronized (this) { 4272 ActivityRecord r = getCallingRecordLocked(token); 4273 return r != null && r.app != null ? r.info.packageName : null; 4274 } 4275 } 4276 4277 public ComponentName getCallingActivity(IBinder token) { 4278 synchronized (this) { 4279 ActivityRecord r = getCallingRecordLocked(token); 4280 return r != null ? r.intent.getComponent() : null; 4281 } 4282 } 4283 4284 private ActivityRecord getCallingRecordLocked(IBinder token) { 4285 ActivityRecord r = mMainStack.isInStackLocked(token); 4286 if (r == null) { 4287 return null; 4288 } 4289 return r.resultTo; 4290 } 4291 4292 public ComponentName getActivityClassForToken(IBinder token) { 4293 synchronized(this) { 4294 ActivityRecord r = mMainStack.isInStackLocked(token); 4295 if (r == null) { 4296 return null; 4297 } 4298 return r.intent.getComponent(); 4299 } 4300 } 4301 4302 public String getPackageForToken(IBinder token) { 4303 synchronized(this) { 4304 ActivityRecord r = mMainStack.isInStackLocked(token); 4305 if (r == null) { 4306 return null; 4307 } 4308 return r.packageName; 4309 } 4310 } 4311 4312 public IIntentSender getIntentSender(int type, 4313 String packageName, IBinder token, String resultWho, 4314 int requestCode, Intent[] intents, String[] resolvedTypes, 4315 int flags, Bundle options) { 4316 enforceNotIsolatedCaller("getIntentSender"); 4317 // Refuse possible leaked file descriptors 4318 if (intents != null) { 4319 if (intents.length < 1) { 4320 throw new IllegalArgumentException("Intents array length must be >= 1"); 4321 } 4322 for (int i=0; i<intents.length; i++) { 4323 Intent intent = intents[i]; 4324 if (intent != null) { 4325 if (intent.hasFileDescriptors()) { 4326 throw new IllegalArgumentException("File descriptors passed in Intent"); 4327 } 4328 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4329 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4330 throw new IllegalArgumentException( 4331 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4332 } 4333 intents[i] = new Intent(intent); 4334 } 4335 } 4336 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4337 throw new IllegalArgumentException( 4338 "Intent array length does not match resolvedTypes length"); 4339 } 4340 } 4341 if (options != null) { 4342 if (options.hasFileDescriptors()) { 4343 throw new IllegalArgumentException("File descriptors passed in options"); 4344 } 4345 } 4346 4347 synchronized(this) { 4348 int callingUid = Binder.getCallingUid(); 4349 try { 4350 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4351 int uid = AppGlobals.getPackageManager() 4352 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4353 if (!UserId.isSameApp(callingUid, uid)) { 4354 String msg = "Permission Denial: getIntentSender() from pid=" 4355 + Binder.getCallingPid() 4356 + ", uid=" + Binder.getCallingUid() 4357 + ", (need uid=" + uid + ")" 4358 + " is not allowed to send as package " + packageName; 4359 Slog.w(TAG, msg); 4360 throw new SecurityException(msg); 4361 } 4362 } 4363 4364 if (DEBUG_MU) 4365 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4366 + Binder.getOrigCallingUid()); 4367 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4368 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4369 4370 } catch (RemoteException e) { 4371 throw new SecurityException(e); 4372 } 4373 } 4374 } 4375 4376 IIntentSender getIntentSenderLocked(int type, 4377 String packageName, int callingUid, IBinder token, String resultWho, 4378 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4379 Bundle options) { 4380 if (DEBUG_MU) 4381 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4382 ActivityRecord activity = null; 4383 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4384 activity = mMainStack.isInStackLocked(token); 4385 if (activity == null) { 4386 return null; 4387 } 4388 if (activity.finishing) { 4389 return null; 4390 } 4391 } 4392 4393 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4394 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4395 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4396 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4397 |PendingIntent.FLAG_UPDATE_CURRENT); 4398 4399 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4400 type, packageName, activity, resultWho, 4401 requestCode, intents, resolvedTypes, flags, options); 4402 WeakReference<PendingIntentRecord> ref; 4403 ref = mIntentSenderRecords.get(key); 4404 PendingIntentRecord rec = ref != null ? ref.get() : null; 4405 if (rec != null) { 4406 if (!cancelCurrent) { 4407 if (updateCurrent) { 4408 if (rec.key.requestIntent != null) { 4409 rec.key.requestIntent.replaceExtras(intents != null ? 4410 intents[intents.length - 1] : null); 4411 } 4412 if (intents != null) { 4413 intents[intents.length-1] = rec.key.requestIntent; 4414 rec.key.allIntents = intents; 4415 rec.key.allResolvedTypes = resolvedTypes; 4416 } else { 4417 rec.key.allIntents = null; 4418 rec.key.allResolvedTypes = null; 4419 } 4420 } 4421 return rec; 4422 } 4423 rec.canceled = true; 4424 mIntentSenderRecords.remove(key); 4425 } 4426 if (noCreate) { 4427 return rec; 4428 } 4429 rec = new PendingIntentRecord(this, key, callingUid); 4430 mIntentSenderRecords.put(key, rec.ref); 4431 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4432 if (activity.pendingResults == null) { 4433 activity.pendingResults 4434 = new HashSet<WeakReference<PendingIntentRecord>>(); 4435 } 4436 activity.pendingResults.add(rec.ref); 4437 } 4438 return rec; 4439 } 4440 4441 public void cancelIntentSender(IIntentSender sender) { 4442 if (!(sender instanceof PendingIntentRecord)) { 4443 return; 4444 } 4445 synchronized(this) { 4446 PendingIntentRecord rec = (PendingIntentRecord)sender; 4447 try { 4448 int uid = AppGlobals.getPackageManager() 4449 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4450 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4451 String msg = "Permission Denial: cancelIntentSender() from pid=" 4452 + Binder.getCallingPid() 4453 + ", uid=" + Binder.getCallingUid() 4454 + " is not allowed to cancel packges " 4455 + rec.key.packageName; 4456 Slog.w(TAG, msg); 4457 throw new SecurityException(msg); 4458 } 4459 } catch (RemoteException e) { 4460 throw new SecurityException(e); 4461 } 4462 cancelIntentSenderLocked(rec, true); 4463 } 4464 } 4465 4466 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4467 rec.canceled = true; 4468 mIntentSenderRecords.remove(rec.key); 4469 if (cleanActivity && rec.key.activity != null) { 4470 rec.key.activity.pendingResults.remove(rec.ref); 4471 } 4472 } 4473 4474 public String getPackageForIntentSender(IIntentSender pendingResult) { 4475 if (!(pendingResult instanceof PendingIntentRecord)) { 4476 return null; 4477 } 4478 try { 4479 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4480 return res.key.packageName; 4481 } catch (ClassCastException e) { 4482 } 4483 return null; 4484 } 4485 4486 public int getUidForIntentSender(IIntentSender sender) { 4487 if (sender instanceof PendingIntentRecord) { 4488 try { 4489 PendingIntentRecord res = (PendingIntentRecord)sender; 4490 return res.uid; 4491 } catch (ClassCastException e) { 4492 } 4493 } 4494 return -1; 4495 } 4496 4497 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4498 if (!(pendingResult instanceof PendingIntentRecord)) { 4499 return false; 4500 } 4501 try { 4502 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4503 if (res.key.allIntents == null) { 4504 return false; 4505 } 4506 for (int i=0; i<res.key.allIntents.length; i++) { 4507 Intent intent = res.key.allIntents[i]; 4508 if (intent.getPackage() != null && intent.getComponent() != null) { 4509 return false; 4510 } 4511 } 4512 return true; 4513 } catch (ClassCastException e) { 4514 } 4515 return false; 4516 } 4517 4518 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4519 if (!(pendingResult instanceof PendingIntentRecord)) { 4520 return false; 4521 } 4522 try { 4523 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4524 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4525 return true; 4526 } 4527 return false; 4528 } catch (ClassCastException e) { 4529 } 4530 return false; 4531 } 4532 4533 public void setProcessLimit(int max) { 4534 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4535 "setProcessLimit()"); 4536 synchronized (this) { 4537 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4538 mProcessLimitOverride = max; 4539 } 4540 trimApplications(); 4541 } 4542 4543 public int getProcessLimit() { 4544 synchronized (this) { 4545 return mProcessLimitOverride; 4546 } 4547 } 4548 4549 void foregroundTokenDied(ForegroundToken token) { 4550 synchronized (ActivityManagerService.this) { 4551 synchronized (mPidsSelfLocked) { 4552 ForegroundToken cur 4553 = mForegroundProcesses.get(token.pid); 4554 if (cur != token) { 4555 return; 4556 } 4557 mForegroundProcesses.remove(token.pid); 4558 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4559 if (pr == null) { 4560 return; 4561 } 4562 pr.forcingToForeground = null; 4563 pr.foregroundServices = false; 4564 } 4565 updateOomAdjLocked(); 4566 } 4567 } 4568 4569 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4570 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4571 "setProcessForeground()"); 4572 synchronized(this) { 4573 boolean changed = false; 4574 4575 synchronized (mPidsSelfLocked) { 4576 ProcessRecord pr = mPidsSelfLocked.get(pid); 4577 if (pr == null && isForeground) { 4578 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4579 return; 4580 } 4581 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4582 if (oldToken != null) { 4583 oldToken.token.unlinkToDeath(oldToken, 0); 4584 mForegroundProcesses.remove(pid); 4585 if (pr != null) { 4586 pr.forcingToForeground = null; 4587 } 4588 changed = true; 4589 } 4590 if (isForeground && token != null) { 4591 ForegroundToken newToken = new ForegroundToken() { 4592 public void binderDied() { 4593 foregroundTokenDied(this); 4594 } 4595 }; 4596 newToken.pid = pid; 4597 newToken.token = token; 4598 try { 4599 token.linkToDeath(newToken, 0); 4600 mForegroundProcesses.put(pid, newToken); 4601 pr.forcingToForeground = token; 4602 changed = true; 4603 } catch (RemoteException e) { 4604 // If the process died while doing this, we will later 4605 // do the cleanup with the process death link. 4606 } 4607 } 4608 } 4609 4610 if (changed) { 4611 updateOomAdjLocked(); 4612 } 4613 } 4614 } 4615 4616 // ========================================================= 4617 // PERMISSIONS 4618 // ========================================================= 4619 4620 static class PermissionController extends IPermissionController.Stub { 4621 ActivityManagerService mActivityManagerService; 4622 PermissionController(ActivityManagerService activityManagerService) { 4623 mActivityManagerService = activityManagerService; 4624 } 4625 4626 public boolean checkPermission(String permission, int pid, int uid) { 4627 return mActivityManagerService.checkPermission(permission, pid, 4628 uid) == PackageManager.PERMISSION_GRANTED; 4629 } 4630 } 4631 4632 /** 4633 * This can be called with or without the global lock held. 4634 */ 4635 int checkComponentPermission(String permission, int pid, int uid, 4636 int owningUid, boolean exported) { 4637 // We might be performing an operation on behalf of an indirect binder 4638 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4639 // client identity accordingly before proceeding. 4640 Identity tlsIdentity = sCallerIdentity.get(); 4641 if (tlsIdentity != null) { 4642 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4643 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4644 uid = tlsIdentity.uid; 4645 pid = tlsIdentity.pid; 4646 } 4647 4648 if (pid == MY_PID) { 4649 return PackageManager.PERMISSION_GRANTED; 4650 } 4651 4652 return ActivityManager.checkComponentPermission(permission, uid, 4653 owningUid, exported); 4654 } 4655 4656 /** 4657 * As the only public entry point for permissions checking, this method 4658 * can enforce the semantic that requesting a check on a null global 4659 * permission is automatically denied. (Internally a null permission 4660 * string is used when calling {@link #checkComponentPermission} in cases 4661 * when only uid-based security is needed.) 4662 * 4663 * This can be called with or without the global lock held. 4664 */ 4665 public int checkPermission(String permission, int pid, int uid) { 4666 if (permission == null) { 4667 return PackageManager.PERMISSION_DENIED; 4668 } 4669 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4670 } 4671 4672 /** 4673 * Binder IPC calls go through the public entry point. 4674 * This can be called with or without the global lock held. 4675 */ 4676 int checkCallingPermission(String permission) { 4677 return checkPermission(permission, 4678 Binder.getCallingPid(), 4679 UserId.getAppId(Binder.getCallingUid())); 4680 } 4681 4682 /** 4683 * This can be called with or without the global lock held. 4684 */ 4685 void enforceCallingPermission(String permission, String func) { 4686 if (checkCallingPermission(permission) 4687 == PackageManager.PERMISSION_GRANTED) { 4688 return; 4689 } 4690 4691 String msg = "Permission Denial: " + func + " from pid=" 4692 + Binder.getCallingPid() 4693 + ", uid=" + Binder.getCallingUid() 4694 + " requires " + permission; 4695 Slog.w(TAG, msg); 4696 throw new SecurityException(msg); 4697 } 4698 4699 /** 4700 * Determine if UID is holding permissions required to access {@link Uri} in 4701 * the given {@link ProviderInfo}. Final permission checking is always done 4702 * in {@link ContentProvider}. 4703 */ 4704 private final boolean checkHoldingPermissionsLocked( 4705 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4706 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4707 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4708 4709 if (pi.applicationInfo.uid == uid) { 4710 return true; 4711 } else if (!pi.exported) { 4712 return false; 4713 } 4714 4715 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4716 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4717 try { 4718 // check if target holds top-level <provider> permissions 4719 if (!readMet && pi.readPermission != null 4720 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4721 readMet = true; 4722 } 4723 if (!writeMet && pi.writePermission != null 4724 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4725 writeMet = true; 4726 } 4727 4728 // track if unprotected read/write is allowed; any denied 4729 // <path-permission> below removes this ability 4730 boolean allowDefaultRead = pi.readPermission == null; 4731 boolean allowDefaultWrite = pi.writePermission == null; 4732 4733 // check if target holds any <path-permission> that match uri 4734 final PathPermission[] pps = pi.pathPermissions; 4735 if (pps != null) { 4736 final String path = uri.getPath(); 4737 int i = pps.length; 4738 while (i > 0 && (!readMet || !writeMet)) { 4739 i--; 4740 PathPermission pp = pps[i]; 4741 if (pp.match(path)) { 4742 if (!readMet) { 4743 final String pprperm = pp.getReadPermission(); 4744 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4745 + pprperm + " for " + pp.getPath() 4746 + ": match=" + pp.match(path) 4747 + " check=" + pm.checkUidPermission(pprperm, uid)); 4748 if (pprperm != null) { 4749 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4750 readMet = true; 4751 } else { 4752 allowDefaultRead = false; 4753 } 4754 } 4755 } 4756 if (!writeMet) { 4757 final String ppwperm = pp.getWritePermission(); 4758 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4759 + ppwperm + " for " + pp.getPath() 4760 + ": match=" + pp.match(path) 4761 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4762 if (ppwperm != null) { 4763 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4764 writeMet = true; 4765 } else { 4766 allowDefaultWrite = false; 4767 } 4768 } 4769 } 4770 } 4771 } 4772 } 4773 4774 // grant unprotected <provider> read/write, if not blocked by 4775 // <path-permission> above 4776 if (allowDefaultRead) readMet = true; 4777 if (allowDefaultWrite) writeMet = true; 4778 4779 } catch (RemoteException e) { 4780 return false; 4781 } 4782 4783 return readMet && writeMet; 4784 } 4785 4786 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4787 int modeFlags) { 4788 // Root gets to do everything. 4789 if (uid == 0) { 4790 return true; 4791 } 4792 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4793 if (perms == null) return false; 4794 UriPermission perm = perms.get(uri); 4795 if (perm == null) return false; 4796 return (modeFlags&perm.modeFlags) == modeFlags; 4797 } 4798 4799 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4800 enforceNotIsolatedCaller("checkUriPermission"); 4801 4802 // Another redirected-binder-call permissions check as in 4803 // {@link checkComponentPermission}. 4804 Identity tlsIdentity = sCallerIdentity.get(); 4805 if (tlsIdentity != null) { 4806 uid = tlsIdentity.uid; 4807 pid = tlsIdentity.pid; 4808 } 4809 4810 uid = UserId.getAppId(uid); 4811 // Our own process gets to do everything. 4812 if (pid == MY_PID) { 4813 return PackageManager.PERMISSION_GRANTED; 4814 } 4815 synchronized(this) { 4816 return checkUriPermissionLocked(uri, uid, modeFlags) 4817 ? PackageManager.PERMISSION_GRANTED 4818 : PackageManager.PERMISSION_DENIED; 4819 } 4820 } 4821 4822 /** 4823 * Check if the targetPkg can be granted permission to access uri by 4824 * the callingUid using the given modeFlags. Throws a security exception 4825 * if callingUid is not allowed to do this. Returns the uid of the target 4826 * if the URI permission grant should be performed; returns -1 if it is not 4827 * needed (for example targetPkg already has permission to access the URI). 4828 * If you already know the uid of the target, you can supply it in 4829 * lastTargetUid else set that to -1. 4830 */ 4831 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4832 Uri uri, int modeFlags, int lastTargetUid) { 4833 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4834 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4835 if (modeFlags == 0) { 4836 return -1; 4837 } 4838 4839 if (targetPkg != null) { 4840 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4841 "Checking grant " + targetPkg + " permission to " + uri); 4842 } 4843 4844 final IPackageManager pm = AppGlobals.getPackageManager(); 4845 4846 // If this is not a content: uri, we can't do anything with it. 4847 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4848 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4849 "Can't grant URI permission for non-content URI: " + uri); 4850 return -1; 4851 } 4852 4853 String name = uri.getAuthority(); 4854 ProviderInfo pi = null; 4855 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4856 UserId.getUserId(callingUid)); 4857 if (cpr != null) { 4858 pi = cpr.info; 4859 } else { 4860 try { 4861 pi = pm.resolveContentProvider(name, 4862 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4863 } catch (RemoteException ex) { 4864 } 4865 } 4866 if (pi == null) { 4867 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4868 return -1; 4869 } 4870 4871 int targetUid = lastTargetUid; 4872 if (targetUid < 0 && targetPkg != null) { 4873 try { 4874 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4875 if (targetUid < 0) { 4876 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4877 "Can't grant URI permission no uid for: " + targetPkg); 4878 return -1; 4879 } 4880 } catch (RemoteException ex) { 4881 return -1; 4882 } 4883 } 4884 4885 if (targetUid >= 0) { 4886 // First... does the target actually need this permission? 4887 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4888 // No need to grant the target this permission. 4889 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4890 "Target " + targetPkg + " already has full permission to " + uri); 4891 return -1; 4892 } 4893 } else { 4894 // First... there is no target package, so can anyone access it? 4895 boolean allowed = pi.exported; 4896 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4897 if (pi.readPermission != null) { 4898 allowed = false; 4899 } 4900 } 4901 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4902 if (pi.writePermission != null) { 4903 allowed = false; 4904 } 4905 } 4906 if (allowed) { 4907 return -1; 4908 } 4909 } 4910 4911 // Second... is the provider allowing granting of URI permissions? 4912 if (!pi.grantUriPermissions) { 4913 throw new SecurityException("Provider " + pi.packageName 4914 + "/" + pi.name 4915 + " does not allow granting of Uri permissions (uri " 4916 + uri + ")"); 4917 } 4918 if (pi.uriPermissionPatterns != null) { 4919 final int N = pi.uriPermissionPatterns.length; 4920 boolean allowed = false; 4921 for (int i=0; i<N; i++) { 4922 if (pi.uriPermissionPatterns[i] != null 4923 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4924 allowed = true; 4925 break; 4926 } 4927 } 4928 if (!allowed) { 4929 throw new SecurityException("Provider " + pi.packageName 4930 + "/" + pi.name 4931 + " does not allow granting of permission to path of Uri " 4932 + uri); 4933 } 4934 } 4935 4936 // Third... does the caller itself have permission to access 4937 // this uri? 4938 if (callingUid != Process.myUid()) { 4939 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4940 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4941 throw new SecurityException("Uid " + callingUid 4942 + " does not have permission to uri " + uri); 4943 } 4944 } 4945 } 4946 4947 return targetUid; 4948 } 4949 4950 public int checkGrantUriPermission(int callingUid, String targetPkg, 4951 Uri uri, int modeFlags) { 4952 enforceNotIsolatedCaller("checkGrantUriPermission"); 4953 synchronized(this) { 4954 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4955 } 4956 } 4957 4958 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4959 Uri uri, int modeFlags, UriPermissionOwner owner) { 4960 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4961 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4962 if (modeFlags == 0) { 4963 return; 4964 } 4965 4966 // So here we are: the caller has the assumed permission 4967 // to the uri, and the target doesn't. Let's now give this to 4968 // the target. 4969 4970 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4971 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4972 4973 HashMap<Uri, UriPermission> targetUris 4974 = mGrantedUriPermissions.get(targetUid); 4975 if (targetUris == null) { 4976 targetUris = new HashMap<Uri, UriPermission>(); 4977 mGrantedUriPermissions.put(targetUid, targetUris); 4978 } 4979 4980 UriPermission perm = targetUris.get(uri); 4981 if (perm == null) { 4982 perm = new UriPermission(targetUid, uri); 4983 targetUris.put(uri, perm); 4984 } 4985 4986 perm.modeFlags |= modeFlags; 4987 if (owner == null) { 4988 perm.globalModeFlags |= modeFlags; 4989 } else { 4990 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4991 perm.readOwners.add(owner); 4992 owner.addReadPermission(perm); 4993 } 4994 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4995 perm.writeOwners.add(owner); 4996 owner.addWritePermission(perm); 4997 } 4998 } 4999 } 5000 5001 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5002 int modeFlags, UriPermissionOwner owner) { 5003 if (targetPkg == null) { 5004 throw new NullPointerException("targetPkg"); 5005 } 5006 5007 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5008 if (targetUid < 0) { 5009 return; 5010 } 5011 5012 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5013 } 5014 5015 static class NeededUriGrants extends ArrayList<Uri> { 5016 final String targetPkg; 5017 final int targetUid; 5018 final int flags; 5019 5020 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5021 targetPkg = _targetPkg; 5022 targetUid = _targetUid; 5023 flags = _flags; 5024 } 5025 } 5026 5027 /** 5028 * Like checkGrantUriPermissionLocked, but takes an Intent. 5029 */ 5030 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5031 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5032 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5033 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5034 + " clip=" + (intent != null ? intent.getClipData() : null) 5035 + " from " + intent + "; flags=0x" 5036 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5037 5038 if (targetPkg == null) { 5039 throw new NullPointerException("targetPkg"); 5040 } 5041 5042 if (intent == null) { 5043 return null; 5044 } 5045 Uri data = intent.getData(); 5046 ClipData clip = intent.getClipData(); 5047 if (data == null && clip == null) { 5048 return null; 5049 } 5050 if (data != null) { 5051 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5052 mode, needed != null ? needed.targetUid : -1); 5053 if (target > 0) { 5054 if (needed == null) { 5055 needed = new NeededUriGrants(targetPkg, target, mode); 5056 } 5057 needed.add(data); 5058 } 5059 } 5060 if (clip != null) { 5061 for (int i=0; i<clip.getItemCount(); i++) { 5062 Uri uri = clip.getItemAt(i).getUri(); 5063 if (uri != null) { 5064 int target = -1; 5065 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5066 mode, needed != null ? needed.targetUid : -1); 5067 if (target > 0) { 5068 if (needed == null) { 5069 needed = new NeededUriGrants(targetPkg, target, mode); 5070 } 5071 needed.add(uri); 5072 } 5073 } else { 5074 Intent clipIntent = clip.getItemAt(i).getIntent(); 5075 if (clipIntent != null) { 5076 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5077 callingUid, targetPkg, clipIntent, mode, needed); 5078 if (newNeeded != null) { 5079 needed = newNeeded; 5080 } 5081 } 5082 } 5083 } 5084 } 5085 5086 return needed; 5087 } 5088 5089 /** 5090 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5091 */ 5092 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5093 UriPermissionOwner owner) { 5094 if (needed != null) { 5095 for (int i=0; i<needed.size(); i++) { 5096 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5097 needed.get(i), needed.flags, owner); 5098 } 5099 } 5100 } 5101 5102 void grantUriPermissionFromIntentLocked(int callingUid, 5103 String targetPkg, Intent intent, UriPermissionOwner owner) { 5104 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5105 intent, intent != null ? intent.getFlags() : 0, null); 5106 if (needed == null) { 5107 return; 5108 } 5109 5110 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5111 } 5112 5113 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5114 Uri uri, int modeFlags) { 5115 enforceNotIsolatedCaller("grantUriPermission"); 5116 synchronized(this) { 5117 final ProcessRecord r = getRecordForAppLocked(caller); 5118 if (r == null) { 5119 throw new SecurityException("Unable to find app for caller " 5120 + caller 5121 + " when granting permission to uri " + uri); 5122 } 5123 if (targetPkg == null) { 5124 throw new IllegalArgumentException("null target"); 5125 } 5126 if (uri == null) { 5127 throw new IllegalArgumentException("null uri"); 5128 } 5129 5130 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5131 null); 5132 } 5133 } 5134 5135 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5136 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5137 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5138 HashMap<Uri, UriPermission> perms 5139 = mGrantedUriPermissions.get(perm.uid); 5140 if (perms != null) { 5141 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5142 "Removing " + perm.uid + " permission to " + perm.uri); 5143 perms.remove(perm.uri); 5144 if (perms.size() == 0) { 5145 mGrantedUriPermissions.remove(perm.uid); 5146 } 5147 } 5148 } 5149 } 5150 5151 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5152 int modeFlags) { 5153 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5154 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5155 if (modeFlags == 0) { 5156 return; 5157 } 5158 5159 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5160 "Revoking all granted permissions to " + uri); 5161 5162 final IPackageManager pm = AppGlobals.getPackageManager(); 5163 5164 final String authority = uri.getAuthority(); 5165 ProviderInfo pi = null; 5166 int userId = UserId.getUserId(callingUid); 5167 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5168 if (cpr != null) { 5169 pi = cpr.info; 5170 } else { 5171 try { 5172 pi = pm.resolveContentProvider(authority, 5173 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5174 } catch (RemoteException ex) { 5175 } 5176 } 5177 if (pi == null) { 5178 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5179 return; 5180 } 5181 5182 // Does the caller have this permission on the URI? 5183 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5184 // Right now, if you are not the original owner of the permission, 5185 // you are not allowed to revoke it. 5186 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5187 throw new SecurityException("Uid " + callingUid 5188 + " does not have permission to uri " + uri); 5189 //} 5190 } 5191 5192 // Go through all of the permissions and remove any that match. 5193 final List<String> SEGMENTS = uri.getPathSegments(); 5194 if (SEGMENTS != null) { 5195 final int NS = SEGMENTS.size(); 5196 int N = mGrantedUriPermissions.size(); 5197 for (int i=0; i<N; i++) { 5198 HashMap<Uri, UriPermission> perms 5199 = mGrantedUriPermissions.valueAt(i); 5200 Iterator<UriPermission> it = perms.values().iterator(); 5201 toploop: 5202 while (it.hasNext()) { 5203 UriPermission perm = it.next(); 5204 Uri targetUri = perm.uri; 5205 if (!authority.equals(targetUri.getAuthority())) { 5206 continue; 5207 } 5208 List<String> targetSegments = targetUri.getPathSegments(); 5209 if (targetSegments == null) { 5210 continue; 5211 } 5212 if (targetSegments.size() < NS) { 5213 continue; 5214 } 5215 for (int j=0; j<NS; j++) { 5216 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5217 continue toploop; 5218 } 5219 } 5220 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5221 "Revoking " + perm.uid + " permission to " + perm.uri); 5222 perm.clearModes(modeFlags); 5223 if (perm.modeFlags == 0) { 5224 it.remove(); 5225 } 5226 } 5227 if (perms.size() == 0) { 5228 mGrantedUriPermissions.remove( 5229 mGrantedUriPermissions.keyAt(i)); 5230 N--; 5231 i--; 5232 } 5233 } 5234 } 5235 } 5236 5237 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5238 int modeFlags) { 5239 enforceNotIsolatedCaller("revokeUriPermission"); 5240 synchronized(this) { 5241 final ProcessRecord r = getRecordForAppLocked(caller); 5242 if (r == null) { 5243 throw new SecurityException("Unable to find app for caller " 5244 + caller 5245 + " when revoking permission to uri " + uri); 5246 } 5247 if (uri == null) { 5248 Slog.w(TAG, "revokeUriPermission: null uri"); 5249 return; 5250 } 5251 5252 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5253 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5254 if (modeFlags == 0) { 5255 return; 5256 } 5257 5258 final IPackageManager pm = AppGlobals.getPackageManager(); 5259 5260 final String authority = uri.getAuthority(); 5261 ProviderInfo pi = null; 5262 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5263 if (cpr != null) { 5264 pi = cpr.info; 5265 } else { 5266 try { 5267 pi = pm.resolveContentProvider(authority, 5268 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5269 } catch (RemoteException ex) { 5270 } 5271 } 5272 if (pi == null) { 5273 Slog.w(TAG, "No content provider found for permission revoke: " 5274 + uri.toSafeString()); 5275 return; 5276 } 5277 5278 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5279 } 5280 } 5281 5282 @Override 5283 public IBinder newUriPermissionOwner(String name) { 5284 enforceNotIsolatedCaller("newUriPermissionOwner"); 5285 synchronized(this) { 5286 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5287 return owner.getExternalTokenLocked(); 5288 } 5289 } 5290 5291 @Override 5292 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5293 Uri uri, int modeFlags) { 5294 synchronized(this) { 5295 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5296 if (owner == null) { 5297 throw new IllegalArgumentException("Unknown owner: " + token); 5298 } 5299 if (fromUid != Binder.getCallingUid()) { 5300 if (Binder.getCallingUid() != Process.myUid()) { 5301 // Only system code can grant URI permissions on behalf 5302 // of other users. 5303 throw new SecurityException("nice try"); 5304 } 5305 } 5306 if (targetPkg == null) { 5307 throw new IllegalArgumentException("null target"); 5308 } 5309 if (uri == null) { 5310 throw new IllegalArgumentException("null uri"); 5311 } 5312 5313 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5314 } 5315 } 5316 5317 @Override 5318 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5319 synchronized(this) { 5320 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5321 if (owner == null) { 5322 throw new IllegalArgumentException("Unknown owner: " + token); 5323 } 5324 5325 if (uri == null) { 5326 owner.removeUriPermissionsLocked(mode); 5327 } else { 5328 owner.removeUriPermissionLocked(uri, mode); 5329 } 5330 } 5331 } 5332 5333 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5334 synchronized (this) { 5335 ProcessRecord app = 5336 who != null ? getRecordForAppLocked(who) : null; 5337 if (app == null) return; 5338 5339 Message msg = Message.obtain(); 5340 msg.what = WAIT_FOR_DEBUGGER_MSG; 5341 msg.obj = app; 5342 msg.arg1 = waiting ? 1 : 0; 5343 mHandler.sendMessage(msg); 5344 } 5345 } 5346 5347 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5348 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5349 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5350 outInfo.availMem = Process.getFreeMemory(); 5351 outInfo.totalMem = Process.getTotalMemory(); 5352 outInfo.threshold = homeAppMem; 5353 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5354 outInfo.hiddenAppThreshold = hiddenAppMem; 5355 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5356 ProcessList.SERVICE_ADJ); 5357 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5358 ProcessList.VISIBLE_APP_ADJ); 5359 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5360 ProcessList.FOREGROUND_APP_ADJ); 5361 } 5362 5363 // ========================================================= 5364 // TASK MANAGEMENT 5365 // ========================================================= 5366 5367 public List getTasks(int maxNum, int flags, 5368 IThumbnailReceiver receiver) { 5369 ArrayList list = new ArrayList(); 5370 5371 PendingThumbnailsRecord pending = null; 5372 IApplicationThread topThumbnail = null; 5373 ActivityRecord topRecord = null; 5374 5375 synchronized(this) { 5376 if (localLOGV) Slog.v( 5377 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5378 + ", receiver=" + receiver); 5379 5380 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5381 != PackageManager.PERMISSION_GRANTED) { 5382 if (receiver != null) { 5383 // If the caller wants to wait for pending thumbnails, 5384 // it ain't gonna get them. 5385 try { 5386 receiver.finished(); 5387 } catch (RemoteException ex) { 5388 } 5389 } 5390 String msg = "Permission Denial: getTasks() from pid=" 5391 + Binder.getCallingPid() 5392 + ", uid=" + Binder.getCallingUid() 5393 + " requires " + android.Manifest.permission.GET_TASKS; 5394 Slog.w(TAG, msg); 5395 throw new SecurityException(msg); 5396 } 5397 5398 int pos = mMainStack.mHistory.size()-1; 5399 ActivityRecord next = 5400 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5401 ActivityRecord top = null; 5402 TaskRecord curTask = null; 5403 int numActivities = 0; 5404 int numRunning = 0; 5405 while (pos >= 0 && maxNum > 0) { 5406 final ActivityRecord r = next; 5407 pos--; 5408 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5409 5410 // Initialize state for next task if needed. 5411 if (top == null || 5412 (top.state == ActivityState.INITIALIZING 5413 && top.task == r.task)) { 5414 top = r; 5415 curTask = r.task; 5416 numActivities = numRunning = 0; 5417 } 5418 5419 // Add 'r' into the current task. 5420 numActivities++; 5421 if (r.app != null && r.app.thread != null) { 5422 numRunning++; 5423 } 5424 5425 if (localLOGV) Slog.v( 5426 TAG, r.intent.getComponent().flattenToShortString() 5427 + ": task=" + r.task); 5428 5429 // If the next one is a different task, generate a new 5430 // TaskInfo entry for what we have. 5431 if (next == null || next.task != curTask) { 5432 ActivityManager.RunningTaskInfo ci 5433 = new ActivityManager.RunningTaskInfo(); 5434 ci.id = curTask.taskId; 5435 ci.baseActivity = r.intent.getComponent(); 5436 ci.topActivity = top.intent.getComponent(); 5437 if (top.thumbHolder != null) { 5438 ci.description = top.thumbHolder.lastDescription; 5439 } 5440 ci.numActivities = numActivities; 5441 ci.numRunning = numRunning; 5442 //System.out.println( 5443 // "#" + maxNum + ": " + " descr=" + ci.description); 5444 if (ci.thumbnail == null && receiver != null) { 5445 if (localLOGV) Slog.v( 5446 TAG, "State=" + top.state + "Idle=" + top.idle 5447 + " app=" + top.app 5448 + " thr=" + (top.app != null ? top.app.thread : null)); 5449 if (top.state == ActivityState.RESUMED 5450 || top.state == ActivityState.PAUSING) { 5451 if (top.idle && top.app != null 5452 && top.app.thread != null) { 5453 topRecord = top; 5454 topThumbnail = top.app.thread; 5455 } else { 5456 top.thumbnailNeeded = true; 5457 } 5458 } 5459 if (pending == null) { 5460 pending = new PendingThumbnailsRecord(receiver); 5461 } 5462 pending.pendingRecords.add(top); 5463 } 5464 list.add(ci); 5465 maxNum--; 5466 top = null; 5467 } 5468 } 5469 5470 if (pending != null) { 5471 mPendingThumbnails.add(pending); 5472 } 5473 } 5474 5475 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5476 5477 if (topThumbnail != null) { 5478 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5479 try { 5480 topThumbnail.requestThumbnail(topRecord.appToken); 5481 } catch (Exception e) { 5482 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5483 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5484 } 5485 } 5486 5487 if (pending == null && receiver != null) { 5488 // In this case all thumbnails were available and the client 5489 // is being asked to be told when the remaining ones come in... 5490 // which is unusually, since the top-most currently running 5491 // activity should never have a canned thumbnail! Oh well. 5492 try { 5493 receiver.finished(); 5494 } catch (RemoteException ex) { 5495 } 5496 } 5497 5498 return list; 5499 } 5500 5501 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5502 int flags, int userId) { 5503 final int callingUid = Binder.getCallingUid(); 5504 if (userId != UserId.getCallingUserId()) { 5505 // Check if the caller is holding permissions for cross-user requests. 5506 if (checkComponentPermission( 5507 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5508 Binder.getCallingPid(), callingUid, -1, true) 5509 != PackageManager.PERMISSION_GRANTED) { 5510 String msg = "Permission Denial: " 5511 + "Request to get recent tasks for user " + userId 5512 + " but is calling from user " + UserId.getUserId(callingUid) 5513 + "; this requires " 5514 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5515 Slog.w(TAG, msg); 5516 throw new SecurityException(msg); 5517 } else { 5518 if (userId == UserId.USER_CURRENT) { 5519 userId = mCurrentUserId; 5520 } 5521 } 5522 } 5523 5524 synchronized (this) { 5525 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5526 "getRecentTasks()"); 5527 final boolean detailed = checkCallingPermission( 5528 android.Manifest.permission.GET_DETAILED_TASKS) 5529 == PackageManager.PERMISSION_GRANTED; 5530 5531 IPackageManager pm = AppGlobals.getPackageManager(); 5532 5533 final int N = mRecentTasks.size(); 5534 ArrayList<ActivityManager.RecentTaskInfo> res 5535 = new ArrayList<ActivityManager.RecentTaskInfo>( 5536 maxNum < N ? maxNum : N); 5537 for (int i=0; i<N && maxNum > 0; i++) { 5538 TaskRecord tr = mRecentTasks.get(i); 5539 // Only add calling user's recent tasks 5540 if (tr.userId != userId) continue; 5541 // Return the entry if desired by the caller. We always return 5542 // the first entry, because callers always expect this to be the 5543 // foreground app. We may filter others if the caller has 5544 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5545 // we should exclude the entry. 5546 5547 if (i == 0 5548 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5549 || (tr.intent == null) 5550 || ((tr.intent.getFlags() 5551 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5552 ActivityManager.RecentTaskInfo rti 5553 = new ActivityManager.RecentTaskInfo(); 5554 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5555 rti.persistentId = tr.taskId; 5556 rti.baseIntent = new Intent( 5557 tr.intent != null ? tr.intent : tr.affinityIntent); 5558 if (!detailed) { 5559 rti.baseIntent.replaceExtras((Bundle)null); 5560 } 5561 rti.origActivity = tr.origActivity; 5562 rti.description = tr.lastDescription; 5563 5564 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5565 // Check whether this activity is currently available. 5566 try { 5567 if (rti.origActivity != null) { 5568 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5569 == null) { 5570 continue; 5571 } 5572 } else if (rti.baseIntent != null) { 5573 if (pm.queryIntentActivities(rti.baseIntent, 5574 null, 0, userId) == null) { 5575 continue; 5576 } 5577 } 5578 } catch (RemoteException e) { 5579 // Will never happen. 5580 } 5581 } 5582 5583 res.add(rti); 5584 maxNum--; 5585 } 5586 } 5587 return res; 5588 } 5589 } 5590 5591 private TaskRecord taskForIdLocked(int id) { 5592 final int N = mRecentTasks.size(); 5593 for (int i=0; i<N; i++) { 5594 TaskRecord tr = mRecentTasks.get(i); 5595 if (tr.taskId == id) { 5596 return tr; 5597 } 5598 } 5599 return null; 5600 } 5601 5602 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5603 synchronized (this) { 5604 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5605 "getTaskThumbnails()"); 5606 TaskRecord tr = taskForIdLocked(id); 5607 if (tr != null) { 5608 return mMainStack.getTaskThumbnailsLocked(tr); 5609 } 5610 } 5611 return null; 5612 } 5613 5614 public boolean removeSubTask(int taskId, int subTaskIndex) { 5615 synchronized (this) { 5616 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5617 "removeSubTask()"); 5618 long ident = Binder.clearCallingIdentity(); 5619 try { 5620 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5621 true) != null; 5622 } finally { 5623 Binder.restoreCallingIdentity(ident); 5624 } 5625 } 5626 } 5627 5628 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5629 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5630 Intent baseIntent = new Intent( 5631 tr.intent != null ? tr.intent : tr.affinityIntent); 5632 ComponentName component = baseIntent.getComponent(); 5633 if (component == null) { 5634 Slog.w(TAG, "Now component for base intent of task: " + tr); 5635 return; 5636 } 5637 5638 // Find any running services associated with this app. 5639 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5640 5641 if (killProcesses) { 5642 // Find any running processes associated with this app. 5643 final String pkg = component.getPackageName(); 5644 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5645 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5646 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5647 for (int i=0; i<uids.size(); i++) { 5648 ProcessRecord proc = uids.valueAt(i); 5649 if (proc.userId != tr.userId) { 5650 continue; 5651 } 5652 if (!proc.pkgList.contains(pkg)) { 5653 continue; 5654 } 5655 procs.add(proc); 5656 } 5657 } 5658 5659 // Kill the running processes. 5660 for (int i=0; i<procs.size(); i++) { 5661 ProcessRecord pr = procs.get(i); 5662 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5663 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5664 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5665 pr.processName, pr.setAdj, "remove task"); 5666 pr.killedBackground = true; 5667 Process.killProcessQuiet(pr.pid); 5668 } else { 5669 pr.waitingToKill = "remove task"; 5670 } 5671 } 5672 } 5673 } 5674 5675 public boolean removeTask(int taskId, int flags) { 5676 synchronized (this) { 5677 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5678 "removeTask()"); 5679 long ident = Binder.clearCallingIdentity(); 5680 try { 5681 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5682 false); 5683 if (r != null) { 5684 mRecentTasks.remove(r.task); 5685 cleanUpRemovedTaskLocked(r.task, flags); 5686 return true; 5687 } else { 5688 TaskRecord tr = null; 5689 int i=0; 5690 while (i < mRecentTasks.size()) { 5691 TaskRecord t = mRecentTasks.get(i); 5692 if (t.taskId == taskId) { 5693 tr = t; 5694 break; 5695 } 5696 i++; 5697 } 5698 if (tr != null) { 5699 if (tr.numActivities <= 0) { 5700 // Caller is just removing a recent task that is 5701 // not actively running. That is easy! 5702 mRecentTasks.remove(i); 5703 cleanUpRemovedTaskLocked(tr, flags); 5704 return true; 5705 } else { 5706 Slog.w(TAG, "removeTask: task " + taskId 5707 + " does not have activities to remove, " 5708 + " but numActivities=" + tr.numActivities 5709 + ": " + tr); 5710 } 5711 } 5712 } 5713 } finally { 5714 Binder.restoreCallingIdentity(ident); 5715 } 5716 } 5717 return false; 5718 } 5719 5720 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5721 int j; 5722 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5723 TaskRecord jt = startTask; 5724 5725 // First look backwards 5726 for (j=startIndex-1; j>=0; j--) { 5727 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5728 if (r.task != jt) { 5729 jt = r.task; 5730 if (affinity.equals(jt.affinity)) { 5731 return j; 5732 } 5733 } 5734 } 5735 5736 // Now look forwards 5737 final int N = mMainStack.mHistory.size(); 5738 jt = startTask; 5739 for (j=startIndex+1; j<N; j++) { 5740 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5741 if (r.task != jt) { 5742 if (affinity.equals(jt.affinity)) { 5743 return j; 5744 } 5745 jt = r.task; 5746 } 5747 } 5748 5749 // Might it be at the top? 5750 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5751 return N-1; 5752 } 5753 5754 return -1; 5755 } 5756 5757 /** 5758 * TODO: Add mController hook 5759 */ 5760 public void moveTaskToFront(int task, int flags, Bundle options) { 5761 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5762 "moveTaskToFront()"); 5763 5764 synchronized(this) { 5765 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5766 Binder.getCallingUid(), "Task to front")) { 5767 ActivityOptions.abort(options); 5768 return; 5769 } 5770 final long origId = Binder.clearCallingIdentity(); 5771 try { 5772 TaskRecord tr = taskForIdLocked(task); 5773 if (tr != null) { 5774 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5775 mMainStack.mUserLeaving = true; 5776 } 5777 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5778 // Caller wants the home activity moved with it. To accomplish this, 5779 // we'll just move the home task to the top first. 5780 mMainStack.moveHomeToFrontLocked(); 5781 } 5782 mMainStack.moveTaskToFrontLocked(tr, null, options); 5783 return; 5784 } 5785 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5786 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5787 if (hr.task.taskId == task) { 5788 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5789 mMainStack.mUserLeaving = true; 5790 } 5791 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5792 // Caller wants the home activity moved with it. To accomplish this, 5793 // we'll just move the home task to the top first. 5794 mMainStack.moveHomeToFrontLocked(); 5795 } 5796 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5797 return; 5798 } 5799 } 5800 } finally { 5801 Binder.restoreCallingIdentity(origId); 5802 } 5803 ActivityOptions.abort(options); 5804 } 5805 } 5806 5807 public void moveTaskToBack(int task) { 5808 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5809 "moveTaskToBack()"); 5810 5811 synchronized(this) { 5812 if (mMainStack.mResumedActivity != null 5813 && mMainStack.mResumedActivity.task.taskId == task) { 5814 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5815 Binder.getCallingUid(), "Task to back")) { 5816 return; 5817 } 5818 } 5819 final long origId = Binder.clearCallingIdentity(); 5820 mMainStack.moveTaskToBackLocked(task, null); 5821 Binder.restoreCallingIdentity(origId); 5822 } 5823 } 5824 5825 /** 5826 * Moves an activity, and all of the other activities within the same task, to the bottom 5827 * of the history stack. The activity's order within the task is unchanged. 5828 * 5829 * @param token A reference to the activity we wish to move 5830 * @param nonRoot If false then this only works if the activity is the root 5831 * of a task; if true it will work for any activity in a task. 5832 * @return Returns true if the move completed, false if not. 5833 */ 5834 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5835 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5836 synchronized(this) { 5837 final long origId = Binder.clearCallingIdentity(); 5838 int taskId = getTaskForActivityLocked(token, !nonRoot); 5839 if (taskId >= 0) { 5840 return mMainStack.moveTaskToBackLocked(taskId, null); 5841 } 5842 Binder.restoreCallingIdentity(origId); 5843 } 5844 return false; 5845 } 5846 5847 public void moveTaskBackwards(int task) { 5848 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5849 "moveTaskBackwards()"); 5850 5851 synchronized(this) { 5852 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5853 Binder.getCallingUid(), "Task backwards")) { 5854 return; 5855 } 5856 final long origId = Binder.clearCallingIdentity(); 5857 moveTaskBackwardsLocked(task); 5858 Binder.restoreCallingIdentity(origId); 5859 } 5860 } 5861 5862 private final void moveTaskBackwardsLocked(int task) { 5863 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5864 } 5865 5866 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5867 synchronized(this) { 5868 return getTaskForActivityLocked(token, onlyRoot); 5869 } 5870 } 5871 5872 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5873 final int N = mMainStack.mHistory.size(); 5874 TaskRecord lastTask = null; 5875 for (int i=0; i<N; i++) { 5876 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5877 if (r.appToken == token) { 5878 if (!onlyRoot || lastTask != r.task) { 5879 return r.task.taskId; 5880 } 5881 return -1; 5882 } 5883 lastTask = r.task; 5884 } 5885 5886 return -1; 5887 } 5888 5889 // ========================================================= 5890 // THUMBNAILS 5891 // ========================================================= 5892 5893 public void reportThumbnail(IBinder token, 5894 Bitmap thumbnail, CharSequence description) { 5895 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5896 final long origId = Binder.clearCallingIdentity(); 5897 sendPendingThumbnail(null, token, thumbnail, description, true); 5898 Binder.restoreCallingIdentity(origId); 5899 } 5900 5901 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5902 Bitmap thumbnail, CharSequence description, boolean always) { 5903 TaskRecord task = null; 5904 ArrayList receivers = null; 5905 5906 //System.out.println("Send pending thumbnail: " + r); 5907 5908 synchronized(this) { 5909 if (r == null) { 5910 r = mMainStack.isInStackLocked(token); 5911 if (r == null) { 5912 return; 5913 } 5914 } 5915 if (thumbnail == null && r.thumbHolder != null) { 5916 thumbnail = r.thumbHolder.lastThumbnail; 5917 description = r.thumbHolder.lastDescription; 5918 } 5919 if (thumbnail == null && !always) { 5920 // If there is no thumbnail, and this entry is not actually 5921 // going away, then abort for now and pick up the next 5922 // thumbnail we get. 5923 return; 5924 } 5925 task = r.task; 5926 5927 int N = mPendingThumbnails.size(); 5928 int i=0; 5929 while (i<N) { 5930 PendingThumbnailsRecord pr = 5931 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5932 //System.out.println("Looking in " + pr.pendingRecords); 5933 if (pr.pendingRecords.remove(r)) { 5934 if (receivers == null) { 5935 receivers = new ArrayList(); 5936 } 5937 receivers.add(pr); 5938 if (pr.pendingRecords.size() == 0) { 5939 pr.finished = true; 5940 mPendingThumbnails.remove(i); 5941 N--; 5942 continue; 5943 } 5944 } 5945 i++; 5946 } 5947 } 5948 5949 if (receivers != null) { 5950 final int N = receivers.size(); 5951 for (int i=0; i<N; i++) { 5952 try { 5953 PendingThumbnailsRecord pr = 5954 (PendingThumbnailsRecord)receivers.get(i); 5955 pr.receiver.newThumbnail( 5956 task != null ? task.taskId : -1, thumbnail, description); 5957 if (pr.finished) { 5958 pr.receiver.finished(); 5959 } 5960 } catch (Exception e) { 5961 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5962 } 5963 } 5964 } 5965 } 5966 5967 // ========================================================= 5968 // CONTENT PROVIDERS 5969 // ========================================================= 5970 5971 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5972 List<ProviderInfo> providers = null; 5973 try { 5974 providers = AppGlobals.getPackageManager(). 5975 queryContentProviders(app.processName, app.uid, 5976 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5977 } catch (RemoteException ex) { 5978 } 5979 if (DEBUG_MU) 5980 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 5981 int userId = app.userId; 5982 if (providers != null) { 5983 int N = providers.size(); 5984 for (int i=0; i<N; i++) { 5985 ProviderInfo cpi = 5986 (ProviderInfo)providers.get(i); 5987 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 5988 cpi.name, cpi.flags); 5989 if (singleton && UserId.getUserId(app.uid) != 0) { 5990 // This is a singleton provider, but a user besides the 5991 // default user is asking to initialize a process it runs 5992 // in... well, no, it doesn't actually run in this process, 5993 // it runs in the process of the default user. Get rid of it. 5994 providers.remove(i); 5995 N--; 5996 continue; 5997 } 5998 5999 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6000 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6001 if (cpr == null) { 6002 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6003 mProviderMap.putProviderByClass(comp, cpr); 6004 } 6005 if (DEBUG_MU) 6006 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6007 app.pubProviders.put(cpi.name, cpr); 6008 app.addPackage(cpi.applicationInfo.packageName); 6009 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6010 } 6011 } 6012 return providers; 6013 } 6014 6015 /** 6016 * Check if {@link ProcessRecord} has a possible chance at accessing the 6017 * given {@link ProviderInfo}. Final permission checking is always done 6018 * in {@link ContentProvider}. 6019 */ 6020 private final String checkContentProviderPermissionLocked( 6021 ProviderInfo cpi, ProcessRecord r) { 6022 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6023 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6024 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6025 cpi.applicationInfo.uid, cpi.exported) 6026 == PackageManager.PERMISSION_GRANTED) { 6027 return null; 6028 } 6029 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6030 cpi.applicationInfo.uid, cpi.exported) 6031 == PackageManager.PERMISSION_GRANTED) { 6032 return null; 6033 } 6034 6035 PathPermission[] pps = cpi.pathPermissions; 6036 if (pps != null) { 6037 int i = pps.length; 6038 while (i > 0) { 6039 i--; 6040 PathPermission pp = pps[i]; 6041 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6042 cpi.applicationInfo.uid, cpi.exported) 6043 == PackageManager.PERMISSION_GRANTED) { 6044 return null; 6045 } 6046 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6047 cpi.applicationInfo.uid, cpi.exported) 6048 == PackageManager.PERMISSION_GRANTED) { 6049 return null; 6050 } 6051 } 6052 } 6053 6054 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6055 if (perms != null) { 6056 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6057 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6058 return null; 6059 } 6060 } 6061 } 6062 6063 String msg; 6064 if (!cpi.exported) { 6065 msg = "Permission Denial: opening provider " + cpi.name 6066 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6067 + ", uid=" + callingUid + ") that is not exported from uid " 6068 + cpi.applicationInfo.uid; 6069 } else { 6070 msg = "Permission Denial: opening provider " + cpi.name 6071 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6072 + ", uid=" + callingUid + ") requires " 6073 + cpi.readPermission + " or " + cpi.writePermission; 6074 } 6075 Slog.w(TAG, msg); 6076 return msg; 6077 } 6078 6079 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6080 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6081 if (r != null) { 6082 for (int i=0; i<r.conProviders.size(); i++) { 6083 ContentProviderConnection conn = r.conProviders.get(i); 6084 if (conn.provider == cpr) { 6085 if (DEBUG_PROVIDER) Slog.v(TAG, 6086 "Adding provider requested by " 6087 + r.processName + " from process " 6088 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6089 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6090 if (stable) { 6091 conn.stableCount++; 6092 conn.numStableIncs++; 6093 } else { 6094 conn.unstableCount++; 6095 conn.numUnstableIncs++; 6096 } 6097 return conn; 6098 } 6099 } 6100 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6101 if (stable) { 6102 conn.stableCount = 1; 6103 conn.numStableIncs = 1; 6104 } else { 6105 conn.unstableCount = 1; 6106 conn.numUnstableIncs = 1; 6107 } 6108 cpr.connections.add(conn); 6109 r.conProviders.add(conn); 6110 return conn; 6111 } 6112 cpr.addExternalProcessHandleLocked(externalProcessToken); 6113 return null; 6114 } 6115 6116 boolean decProviderCountLocked(ContentProviderConnection conn, 6117 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6118 if (conn != null) { 6119 cpr = conn.provider; 6120 if (DEBUG_PROVIDER) Slog.v(TAG, 6121 "Removing provider requested by " 6122 + conn.client.processName + " from process " 6123 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6124 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6125 if (stable) { 6126 conn.stableCount--; 6127 } else { 6128 conn.unstableCount--; 6129 } 6130 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6131 cpr.connections.remove(conn); 6132 conn.client.conProviders.remove(conn); 6133 return true; 6134 } 6135 return false; 6136 } 6137 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6138 return false; 6139 } 6140 6141 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6142 String name, IBinder token, boolean stable) { 6143 ContentProviderRecord cpr; 6144 ContentProviderConnection conn = null; 6145 ProviderInfo cpi = null; 6146 6147 synchronized(this) { 6148 ProcessRecord r = null; 6149 if (caller != null) { 6150 r = getRecordForAppLocked(caller); 6151 if (r == null) { 6152 throw new SecurityException( 6153 "Unable to find app for caller " + caller 6154 + " (pid=" + Binder.getCallingPid() 6155 + ") when getting content provider " + name); 6156 } 6157 } 6158 6159 // First check if this content provider has been published... 6160 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6161 cpr = mProviderMap.getProviderByName(name, userId); 6162 boolean providerRunning = cpr != null; 6163 if (providerRunning) { 6164 cpi = cpr.info; 6165 String msg; 6166 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6167 throw new SecurityException(msg); 6168 } 6169 6170 if (r != null && cpr.canRunHere(r)) { 6171 // This provider has been published or is in the process 6172 // of being published... but it is also allowed to run 6173 // in the caller's process, so don't make a connection 6174 // and just let the caller instantiate its own instance. 6175 ContentProviderHolder holder = cpr.newHolder(null); 6176 // don't give caller the provider object, it needs 6177 // to make its own. 6178 holder.provider = null; 6179 return holder; 6180 } 6181 6182 final long origId = Binder.clearCallingIdentity(); 6183 6184 // In this case the provider instance already exists, so we can 6185 // return it right away. 6186 conn = incProviderCountLocked(r, cpr, token, stable); 6187 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6188 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6189 // If this is a perceptible app accessing the provider, 6190 // make sure to count it as being accessed and thus 6191 // back up on the LRU list. This is good because 6192 // content providers are often expensive to start. 6193 updateLruProcessLocked(cpr.proc, false, true); 6194 } 6195 } 6196 6197 if (cpr.proc != null) { 6198 if (false) { 6199 if (cpr.name.flattenToShortString().equals( 6200 "com.android.providers.calendar/.CalendarProvider2")) { 6201 Slog.v(TAG, "****************** KILLING " 6202 + cpr.name.flattenToShortString()); 6203 Process.killProcess(cpr.proc.pid); 6204 } 6205 } 6206 boolean success = updateOomAdjLocked(cpr.proc); 6207 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6208 // NOTE: there is still a race here where a signal could be 6209 // pending on the process even though we managed to update its 6210 // adj level. Not sure what to do about this, but at least 6211 // the race is now smaller. 6212 if (!success) { 6213 // Uh oh... it looks like the provider's process 6214 // has been killed on us. We need to wait for a new 6215 // process to be started, and make sure its death 6216 // doesn't kill our process. 6217 Slog.i(TAG, 6218 "Existing provider " + cpr.name.flattenToShortString() 6219 + " is crashing; detaching " + r); 6220 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6221 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6222 if (!lastRef) { 6223 // This wasn't the last ref our process had on 6224 // the provider... we have now been killed, bail. 6225 return null; 6226 } 6227 providerRunning = false; 6228 conn = null; 6229 } 6230 } 6231 6232 Binder.restoreCallingIdentity(origId); 6233 } 6234 6235 boolean singleton; 6236 if (!providerRunning) { 6237 try { 6238 cpi = AppGlobals.getPackageManager(). 6239 resolveContentProvider(name, 6240 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6241 } catch (RemoteException ex) { 6242 } 6243 if (cpi == null) { 6244 return null; 6245 } 6246 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6247 cpi.name, cpi.flags); 6248 if (singleton) { 6249 userId = 0; 6250 } 6251 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6252 6253 String msg; 6254 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6255 throw new SecurityException(msg); 6256 } 6257 6258 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6259 && !cpi.processName.equals("system")) { 6260 // If this content provider does not run in the system 6261 // process, and the system is not yet ready to run other 6262 // processes, then fail fast instead of hanging. 6263 throw new IllegalArgumentException( 6264 "Attempt to launch content provider before system ready"); 6265 } 6266 6267 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6268 cpr = mProviderMap.getProviderByClass(comp, userId); 6269 final boolean firstClass = cpr == null; 6270 if (firstClass) { 6271 try { 6272 ApplicationInfo ai = 6273 AppGlobals.getPackageManager(). 6274 getApplicationInfo( 6275 cpi.applicationInfo.packageName, 6276 STOCK_PM_FLAGS, userId); 6277 if (ai == null) { 6278 Slog.w(TAG, "No package info for content provider " 6279 + cpi.name); 6280 return null; 6281 } 6282 ai = getAppInfoForUser(ai, userId); 6283 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6284 } catch (RemoteException ex) { 6285 // pm is in same process, this will never happen. 6286 } 6287 } 6288 6289 if (r != null && cpr.canRunHere(r)) { 6290 // If this is a multiprocess provider, then just return its 6291 // info and allow the caller to instantiate it. Only do 6292 // this if the provider is the same user as the caller's 6293 // process, or can run as root (so can be in any process). 6294 return cpr.newHolder(null); 6295 } 6296 6297 if (DEBUG_PROVIDER) { 6298 RuntimeException e = new RuntimeException("here"); 6299 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6300 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6301 } 6302 6303 // This is single process, and our app is now connecting to it. 6304 // See if we are already in the process of launching this 6305 // provider. 6306 final int N = mLaunchingProviders.size(); 6307 int i; 6308 for (i=0; i<N; i++) { 6309 if (mLaunchingProviders.get(i) == cpr) { 6310 break; 6311 } 6312 } 6313 6314 // If the provider is not already being launched, then get it 6315 // started. 6316 if (i >= N) { 6317 final long origId = Binder.clearCallingIdentity(); 6318 6319 try { 6320 // Content provider is now in use, its package can't be stopped. 6321 try { 6322 AppGlobals.getPackageManager().setPackageStoppedState( 6323 cpr.appInfo.packageName, false, userId); 6324 } catch (RemoteException e) { 6325 } catch (IllegalArgumentException e) { 6326 Slog.w(TAG, "Failed trying to unstop package " 6327 + cpr.appInfo.packageName + ": " + e); 6328 } 6329 6330 ProcessRecord proc = startProcessLocked(cpi.processName, 6331 cpr.appInfo, false, 0, "content provider", 6332 new ComponentName(cpi.applicationInfo.packageName, 6333 cpi.name), false, false); 6334 if (proc == null) { 6335 Slog.w(TAG, "Unable to launch app " 6336 + cpi.applicationInfo.packageName + "/" 6337 + cpi.applicationInfo.uid + " for provider " 6338 + name + ": process is bad"); 6339 return null; 6340 } 6341 cpr.launchingApp = proc; 6342 mLaunchingProviders.add(cpr); 6343 } finally { 6344 Binder.restoreCallingIdentity(origId); 6345 } 6346 } 6347 6348 // Make sure the provider is published (the same provider class 6349 // may be published under multiple names). 6350 if (firstClass) { 6351 mProviderMap.putProviderByClass(comp, cpr); 6352 } 6353 6354 mProviderMap.putProviderByName(name, cpr); 6355 conn = incProviderCountLocked(r, cpr, token, stable); 6356 if (conn != null) { 6357 conn.waiting = true; 6358 } 6359 } 6360 } 6361 6362 // Wait for the provider to be published... 6363 synchronized (cpr) { 6364 while (cpr.provider == null) { 6365 if (cpr.launchingApp == null) { 6366 Slog.w(TAG, "Unable to launch app " 6367 + cpi.applicationInfo.packageName + "/" 6368 + cpi.applicationInfo.uid + " for provider " 6369 + name + ": launching app became null"); 6370 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6371 cpi.applicationInfo.packageName, 6372 cpi.applicationInfo.uid, name); 6373 return null; 6374 } 6375 try { 6376 if (DEBUG_MU) { 6377 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6378 + cpr.launchingApp); 6379 } 6380 if (conn != null) { 6381 conn.waiting = true; 6382 } 6383 cpr.wait(); 6384 } catch (InterruptedException ex) { 6385 } finally { 6386 if (conn != null) { 6387 conn.waiting = false; 6388 } 6389 } 6390 } 6391 } 6392 return cpr != null ? cpr.newHolder(conn) : null; 6393 } 6394 6395 public final ContentProviderHolder getContentProvider( 6396 IApplicationThread caller, String name, boolean stable) { 6397 enforceNotIsolatedCaller("getContentProvider"); 6398 if (caller == null) { 6399 String msg = "null IApplicationThread when getting content provider " 6400 + name; 6401 Slog.w(TAG, msg); 6402 throw new SecurityException(msg); 6403 } 6404 6405 return getContentProviderImpl(caller, name, null, stable); 6406 } 6407 6408 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6409 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6410 "Do not have permission in call getContentProviderExternal()"); 6411 return getContentProviderExternalUnchecked(name, token); 6412 } 6413 6414 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6415 return getContentProviderImpl(null, name, token, true); 6416 } 6417 6418 /** 6419 * Drop a content provider from a ProcessRecord's bookkeeping 6420 * @param cpr 6421 */ 6422 public void removeContentProvider(IBinder connection, boolean stable) { 6423 enforceNotIsolatedCaller("removeContentProvider"); 6424 synchronized (this) { 6425 ContentProviderConnection conn; 6426 try { 6427 conn = (ContentProviderConnection)connection; 6428 } catch (ClassCastException e) { 6429 String msg ="removeContentProvider: " + connection 6430 + " not a ContentProviderConnection"; 6431 Slog.w(TAG, msg); 6432 throw new IllegalArgumentException(msg); 6433 } 6434 if (conn == null) { 6435 throw new NullPointerException("connection is null"); 6436 } 6437 if (decProviderCountLocked(conn, null, null, stable)) { 6438 updateOomAdjLocked(); 6439 } 6440 } 6441 } 6442 6443 public void removeContentProviderExternal(String name, IBinder token) { 6444 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6445 "Do not have permission in call removeContentProviderExternal()"); 6446 removeContentProviderExternalUnchecked(name, token); 6447 } 6448 6449 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6450 synchronized (this) { 6451 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6452 Binder.getOrigCallingUser()); 6453 if(cpr == null) { 6454 //remove from mProvidersByClass 6455 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6456 return; 6457 } 6458 6459 //update content provider record entry info 6460 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6461 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6462 Binder.getOrigCallingUser()); 6463 if (localCpr.hasExternalProcessHandles()) { 6464 if (localCpr.removeExternalProcessHandleLocked(token)) { 6465 updateOomAdjLocked(); 6466 } else { 6467 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6468 + " with no external reference for token: " 6469 + token + "."); 6470 } 6471 } else { 6472 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6473 + " with no external references."); 6474 } 6475 } 6476 } 6477 6478 public final void publishContentProviders(IApplicationThread caller, 6479 List<ContentProviderHolder> providers) { 6480 if (providers == null) { 6481 return; 6482 } 6483 6484 enforceNotIsolatedCaller("publishContentProviders"); 6485 synchronized (this) { 6486 final ProcessRecord r = getRecordForAppLocked(caller); 6487 if (DEBUG_MU) 6488 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6489 if (r == null) { 6490 throw new SecurityException( 6491 "Unable to find app for caller " + caller 6492 + " (pid=" + Binder.getCallingPid() 6493 + ") when publishing content providers"); 6494 } 6495 6496 final long origId = Binder.clearCallingIdentity(); 6497 6498 final int N = providers.size(); 6499 for (int i=0; i<N; i++) { 6500 ContentProviderHolder src = providers.get(i); 6501 if (src == null || src.info == null || src.provider == null) { 6502 continue; 6503 } 6504 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6505 if (DEBUG_MU) 6506 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6507 if (dst != null) { 6508 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6509 mProviderMap.putProviderByClass(comp, dst); 6510 String names[] = dst.info.authority.split(";"); 6511 for (int j = 0; j < names.length; j++) { 6512 mProviderMap.putProviderByName(names[j], dst); 6513 } 6514 6515 int NL = mLaunchingProviders.size(); 6516 int j; 6517 for (j=0; j<NL; j++) { 6518 if (mLaunchingProviders.get(j) == dst) { 6519 mLaunchingProviders.remove(j); 6520 j--; 6521 NL--; 6522 } 6523 } 6524 synchronized (dst) { 6525 dst.provider = src.provider; 6526 dst.proc = r; 6527 dst.notifyAll(); 6528 } 6529 updateOomAdjLocked(r); 6530 } 6531 } 6532 6533 Binder.restoreCallingIdentity(origId); 6534 } 6535 } 6536 6537 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6538 ContentProviderConnection conn; 6539 try { 6540 conn = (ContentProviderConnection)connection; 6541 } catch (ClassCastException e) { 6542 String msg ="refContentProvider: " + connection 6543 + " not a ContentProviderConnection"; 6544 Slog.w(TAG, msg); 6545 throw new IllegalArgumentException(msg); 6546 } 6547 if (conn == null) { 6548 throw new NullPointerException("connection is null"); 6549 } 6550 6551 synchronized (this) { 6552 if (stable > 0) { 6553 conn.numStableIncs += stable; 6554 } 6555 stable = conn.stableCount + stable; 6556 if (stable < 0) { 6557 throw new IllegalStateException("stableCount < 0: " + stable); 6558 } 6559 6560 if (unstable > 0) { 6561 conn.numUnstableIncs += unstable; 6562 } 6563 unstable = conn.unstableCount + unstable; 6564 if (unstable < 0) { 6565 throw new IllegalStateException("unstableCount < 0: " + unstable); 6566 } 6567 6568 if ((stable+unstable) <= 0) { 6569 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6570 + stable + " unstable=" + unstable); 6571 } 6572 conn.stableCount = stable; 6573 conn.unstableCount = unstable; 6574 return !conn.dead; 6575 } 6576 } 6577 6578 public void unstableProviderDied(IBinder connection) { 6579 ContentProviderConnection conn; 6580 try { 6581 conn = (ContentProviderConnection)connection; 6582 } catch (ClassCastException e) { 6583 String msg ="refContentProvider: " + connection 6584 + " not a ContentProviderConnection"; 6585 Slog.w(TAG, msg); 6586 throw new IllegalArgumentException(msg); 6587 } 6588 if (conn == null) { 6589 throw new NullPointerException("connection is null"); 6590 } 6591 6592 // Safely retrieve the content provider associated with the connection. 6593 IContentProvider provider; 6594 synchronized (this) { 6595 provider = conn.provider.provider; 6596 } 6597 6598 if (provider == null) { 6599 // Um, yeah, we're way ahead of you. 6600 return; 6601 } 6602 6603 // Make sure the caller is being honest with us. 6604 if (provider.asBinder().pingBinder()) { 6605 // Er, no, still looks good to us. 6606 synchronized (this) { 6607 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6608 + " says " + conn + " died, but we don't agree"); 6609 return; 6610 } 6611 } 6612 6613 // Well look at that! It's dead! 6614 synchronized (this) { 6615 if (conn.provider.provider != provider) { 6616 // But something changed... good enough. 6617 return; 6618 } 6619 6620 ProcessRecord proc = conn.provider.proc; 6621 if (proc == null || proc.thread == null) { 6622 // Seems like the process is already cleaned up. 6623 return; 6624 } 6625 6626 // As far as we're concerned, this is just like receiving a 6627 // death notification... just a bit prematurely. 6628 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6629 + ") early provider death"); 6630 final long ident = Binder.clearCallingIdentity(); 6631 try { 6632 appDiedLocked(proc, proc.pid, proc.thread); 6633 } finally { 6634 Binder.restoreCallingIdentity(ident); 6635 } 6636 } 6637 } 6638 6639 public static final void installSystemProviders() { 6640 List<ProviderInfo> providers; 6641 synchronized (mSelf) { 6642 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6643 providers = mSelf.generateApplicationProvidersLocked(app); 6644 if (providers != null) { 6645 for (int i=providers.size()-1; i>=0; i--) { 6646 ProviderInfo pi = (ProviderInfo)providers.get(i); 6647 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6648 Slog.w(TAG, "Not installing system proc provider " + pi.name 6649 + ": not system .apk"); 6650 providers.remove(i); 6651 } 6652 } 6653 } 6654 } 6655 if (providers != null) { 6656 mSystemThread.installSystemProviders(providers); 6657 } 6658 6659 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6660 6661 mSelf.mUsageStatsService.monitorPackages(); 6662 } 6663 6664 /** 6665 * Allows app to retrieve the MIME type of a URI without having permission 6666 * to access its content provider. 6667 * 6668 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6669 * 6670 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6671 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6672 */ 6673 public String getProviderMimeType(Uri uri) { 6674 enforceNotIsolatedCaller("getProviderMimeType"); 6675 final String name = uri.getAuthority(); 6676 final long ident = Binder.clearCallingIdentity(); 6677 ContentProviderHolder holder = null; 6678 6679 try { 6680 holder = getContentProviderExternalUnchecked(name, null); 6681 if (holder != null) { 6682 return holder.provider.getType(uri); 6683 } 6684 } catch (RemoteException e) { 6685 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6686 return null; 6687 } finally { 6688 if (holder != null) { 6689 removeContentProviderExternalUnchecked(name, null); 6690 } 6691 Binder.restoreCallingIdentity(ident); 6692 } 6693 6694 return null; 6695 } 6696 6697 // ========================================================= 6698 // GLOBAL MANAGEMENT 6699 // ========================================================= 6700 6701 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6702 ApplicationInfo info, String customProcess, boolean isolated) { 6703 String proc = customProcess != null ? customProcess : info.processName; 6704 BatteryStatsImpl.Uid.Proc ps = null; 6705 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6706 int uid = info.uid; 6707 if (isolated) { 6708 int userId = UserId.getUserId(uid); 6709 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6710 uid = 0; 6711 while (true) { 6712 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6713 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6714 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6715 } 6716 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6717 mNextIsolatedProcessUid++; 6718 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6719 // No process for this uid, use it. 6720 break; 6721 } 6722 stepsLeft--; 6723 if (stepsLeft <= 0) { 6724 return null; 6725 } 6726 } 6727 } 6728 synchronized (stats) { 6729 ps = stats.getProcessStatsLocked(info.uid, proc); 6730 } 6731 return new ProcessRecord(ps, thread, info, proc, uid); 6732 } 6733 6734 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6735 ProcessRecord app; 6736 if (!isolated) { 6737 app = getProcessRecordLocked(info.processName, info.uid); 6738 } else { 6739 app = null; 6740 } 6741 6742 if (app == null) { 6743 app = newProcessRecordLocked(null, info, null, isolated); 6744 mProcessNames.put(info.processName, app.uid, app); 6745 if (isolated) { 6746 mIsolatedProcesses.put(app.uid, app); 6747 } 6748 updateLruProcessLocked(app, true, true); 6749 } 6750 6751 // This package really, really can not be stopped. 6752 try { 6753 AppGlobals.getPackageManager().setPackageStoppedState( 6754 info.packageName, false, UserId.getUserId(app.uid)); 6755 } catch (RemoteException e) { 6756 } catch (IllegalArgumentException e) { 6757 Slog.w(TAG, "Failed trying to unstop package " 6758 + info.packageName + ": " + e); 6759 } 6760 6761 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6762 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6763 app.persistent = true; 6764 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6765 } 6766 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6767 mPersistentStartingProcesses.add(app); 6768 startProcessLocked(app, "added application", app.processName); 6769 } 6770 6771 return app; 6772 } 6773 6774 public void unhandledBack() { 6775 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6776 "unhandledBack()"); 6777 6778 synchronized(this) { 6779 int count = mMainStack.mHistory.size(); 6780 if (DEBUG_SWITCH) Slog.d( 6781 TAG, "Performing unhandledBack(): stack size = " + count); 6782 if (count > 1) { 6783 final long origId = Binder.clearCallingIdentity(); 6784 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6785 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6786 Binder.restoreCallingIdentity(origId); 6787 } 6788 } 6789 } 6790 6791 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6792 enforceNotIsolatedCaller("openContentUri"); 6793 String name = uri.getAuthority(); 6794 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6795 ParcelFileDescriptor pfd = null; 6796 if (cph != null) { 6797 // We record the binder invoker's uid in thread-local storage before 6798 // going to the content provider to open the file. Later, in the code 6799 // that handles all permissions checks, we look for this uid and use 6800 // that rather than the Activity Manager's own uid. The effect is that 6801 // we do the check against the caller's permissions even though it looks 6802 // to the content provider like the Activity Manager itself is making 6803 // the request. 6804 sCallerIdentity.set(new Identity( 6805 Binder.getCallingPid(), Binder.getCallingUid())); 6806 try { 6807 pfd = cph.provider.openFile(uri, "r"); 6808 } catch (FileNotFoundException e) { 6809 // do nothing; pfd will be returned null 6810 } finally { 6811 // Ensure that whatever happens, we clean up the identity state 6812 sCallerIdentity.remove(); 6813 } 6814 6815 // We've got the fd now, so we're done with the provider. 6816 removeContentProviderExternalUnchecked(name, null); 6817 } else { 6818 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6819 } 6820 return pfd; 6821 } 6822 6823 // Actually is sleeping or shutting down or whatever else in the future 6824 // is an inactive state. 6825 public boolean isSleeping() { 6826 return mSleeping || mShuttingDown; 6827 } 6828 6829 public void goingToSleep() { 6830 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6831 != PackageManager.PERMISSION_GRANTED) { 6832 throw new SecurityException("Requires permission " 6833 + android.Manifest.permission.DEVICE_POWER); 6834 } 6835 6836 synchronized(this) { 6837 mWentToSleep = true; 6838 updateEventDispatchingLocked(); 6839 6840 if (!mSleeping) { 6841 mSleeping = true; 6842 mMainStack.stopIfSleepingLocked(); 6843 6844 // Initialize the wake times of all processes. 6845 checkExcessivePowerUsageLocked(false); 6846 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6847 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6848 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6849 } 6850 } 6851 } 6852 6853 public boolean shutdown(int timeout) { 6854 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6855 != PackageManager.PERMISSION_GRANTED) { 6856 throw new SecurityException("Requires permission " 6857 + android.Manifest.permission.SHUTDOWN); 6858 } 6859 6860 boolean timedout = false; 6861 6862 synchronized(this) { 6863 mShuttingDown = true; 6864 updateEventDispatchingLocked(); 6865 6866 if (mMainStack.mResumedActivity != null) { 6867 mMainStack.stopIfSleepingLocked(); 6868 final long endTime = System.currentTimeMillis() + timeout; 6869 while (mMainStack.mResumedActivity != null 6870 || mMainStack.mPausingActivity != null) { 6871 long delay = endTime - System.currentTimeMillis(); 6872 if (delay <= 0) { 6873 Slog.w(TAG, "Activity manager shutdown timed out"); 6874 timedout = true; 6875 break; 6876 } 6877 try { 6878 this.wait(); 6879 } catch (InterruptedException e) { 6880 } 6881 } 6882 } 6883 } 6884 6885 mUsageStatsService.shutdown(); 6886 mBatteryStatsService.shutdown(); 6887 6888 return timedout; 6889 } 6890 6891 public final void activitySlept(IBinder token) { 6892 if (localLOGV) Slog.v( 6893 TAG, "Activity slept: token=" + token); 6894 6895 ActivityRecord r = null; 6896 6897 final long origId = Binder.clearCallingIdentity(); 6898 6899 synchronized (this) { 6900 r = mMainStack.isInStackLocked(token); 6901 if (r != null) { 6902 mMainStack.activitySleptLocked(r); 6903 } 6904 } 6905 6906 Binder.restoreCallingIdentity(origId); 6907 } 6908 6909 private void comeOutOfSleepIfNeededLocked() { 6910 if (!mWentToSleep && !mLockScreenShown) { 6911 if (mSleeping) { 6912 mSleeping = false; 6913 mMainStack.awakeFromSleepingLocked(); 6914 mMainStack.resumeTopActivityLocked(null); 6915 } 6916 } 6917 } 6918 6919 public void wakingUp() { 6920 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6921 != PackageManager.PERMISSION_GRANTED) { 6922 throw new SecurityException("Requires permission " 6923 + android.Manifest.permission.DEVICE_POWER); 6924 } 6925 6926 synchronized(this) { 6927 mWentToSleep = false; 6928 updateEventDispatchingLocked(); 6929 comeOutOfSleepIfNeededLocked(); 6930 } 6931 } 6932 6933 private void updateEventDispatchingLocked() { 6934 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6935 } 6936 6937 public void setLockScreenShown(boolean shown) { 6938 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6939 != PackageManager.PERMISSION_GRANTED) { 6940 throw new SecurityException("Requires permission " 6941 + android.Manifest.permission.DEVICE_POWER); 6942 } 6943 6944 synchronized(this) { 6945 mLockScreenShown = shown; 6946 comeOutOfSleepIfNeededLocked(); 6947 } 6948 } 6949 6950 public void stopAppSwitches() { 6951 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6952 != PackageManager.PERMISSION_GRANTED) { 6953 throw new SecurityException("Requires permission " 6954 + android.Manifest.permission.STOP_APP_SWITCHES); 6955 } 6956 6957 synchronized(this) { 6958 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6959 + APP_SWITCH_DELAY_TIME; 6960 mDidAppSwitch = false; 6961 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6962 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6963 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6964 } 6965 } 6966 6967 public void resumeAppSwitches() { 6968 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6969 != PackageManager.PERMISSION_GRANTED) { 6970 throw new SecurityException("Requires permission " 6971 + android.Manifest.permission.STOP_APP_SWITCHES); 6972 } 6973 6974 synchronized(this) { 6975 // Note that we don't execute any pending app switches... we will 6976 // let those wait until either the timeout, or the next start 6977 // activity request. 6978 mAppSwitchesAllowedTime = 0; 6979 } 6980 } 6981 6982 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 6983 String name) { 6984 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 6985 return true; 6986 } 6987 6988 final int perm = checkComponentPermission( 6989 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 6990 callingUid, -1, true); 6991 if (perm == PackageManager.PERMISSION_GRANTED) { 6992 return true; 6993 } 6994 6995 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 6996 return false; 6997 } 6998 6999 public void setDebugApp(String packageName, boolean waitForDebugger, 7000 boolean persistent) { 7001 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7002 "setDebugApp()"); 7003 7004 // Note that this is not really thread safe if there are multiple 7005 // callers into it at the same time, but that's not a situation we 7006 // care about. 7007 if (persistent) { 7008 final ContentResolver resolver = mContext.getContentResolver(); 7009 Settings.System.putString( 7010 resolver, Settings.System.DEBUG_APP, 7011 packageName); 7012 Settings.System.putInt( 7013 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7014 waitForDebugger ? 1 : 0); 7015 } 7016 7017 synchronized (this) { 7018 if (!persistent) { 7019 mOrigDebugApp = mDebugApp; 7020 mOrigWaitForDebugger = mWaitForDebugger; 7021 } 7022 mDebugApp = packageName; 7023 mWaitForDebugger = waitForDebugger; 7024 mDebugTransient = !persistent; 7025 if (packageName != null) { 7026 final long origId = Binder.clearCallingIdentity(); 7027 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7028 Binder.restoreCallingIdentity(origId); 7029 } 7030 } 7031 } 7032 7033 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7034 synchronized (this) { 7035 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7036 if (!isDebuggable) { 7037 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7038 throw new SecurityException("Process not debuggable: " + app.packageName); 7039 } 7040 } 7041 7042 mOpenGlTraceApp = processName; 7043 } 7044 } 7045 7046 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7047 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7048 synchronized (this) { 7049 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7050 if (!isDebuggable) { 7051 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7052 throw new SecurityException("Process not debuggable: " + app.packageName); 7053 } 7054 } 7055 mProfileApp = processName; 7056 mProfileFile = profileFile; 7057 if (mProfileFd != null) { 7058 try { 7059 mProfileFd.close(); 7060 } catch (IOException e) { 7061 } 7062 mProfileFd = null; 7063 } 7064 mProfileFd = profileFd; 7065 mProfileType = 0; 7066 mAutoStopProfiler = autoStopProfiler; 7067 } 7068 } 7069 7070 public void setAlwaysFinish(boolean enabled) { 7071 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7072 "setAlwaysFinish()"); 7073 7074 Settings.System.putInt( 7075 mContext.getContentResolver(), 7076 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7077 7078 synchronized (this) { 7079 mAlwaysFinishActivities = enabled; 7080 } 7081 } 7082 7083 public void setActivityController(IActivityController controller) { 7084 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7085 "setActivityController()"); 7086 synchronized (this) { 7087 mController = controller; 7088 } 7089 } 7090 7091 public boolean isUserAMonkey() { 7092 // For now the fact that there is a controller implies 7093 // we have a monkey. 7094 synchronized (this) { 7095 return mController != null; 7096 } 7097 } 7098 7099 public void registerProcessObserver(IProcessObserver observer) { 7100 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7101 "registerProcessObserver()"); 7102 synchronized (this) { 7103 mProcessObservers.register(observer); 7104 } 7105 } 7106 7107 public void unregisterProcessObserver(IProcessObserver observer) { 7108 synchronized (this) { 7109 mProcessObservers.unregister(observer); 7110 } 7111 } 7112 7113 public void setImmersive(IBinder token, boolean immersive) { 7114 synchronized(this) { 7115 ActivityRecord r = mMainStack.isInStackLocked(token); 7116 if (r == null) { 7117 throw new IllegalArgumentException(); 7118 } 7119 r.immersive = immersive; 7120 } 7121 } 7122 7123 public boolean isImmersive(IBinder token) { 7124 synchronized (this) { 7125 ActivityRecord r = mMainStack.isInStackLocked(token); 7126 if (r == null) { 7127 throw new IllegalArgumentException(); 7128 } 7129 return r.immersive; 7130 } 7131 } 7132 7133 public boolean isTopActivityImmersive() { 7134 enforceNotIsolatedCaller("startActivity"); 7135 synchronized (this) { 7136 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7137 return (r != null) ? r.immersive : false; 7138 } 7139 } 7140 7141 public final void enterSafeMode() { 7142 synchronized(this) { 7143 // It only makes sense to do this before the system is ready 7144 // and started launching other packages. 7145 if (!mSystemReady) { 7146 try { 7147 AppGlobals.getPackageManager().enterSafeMode(); 7148 } catch (RemoteException e) { 7149 } 7150 } 7151 } 7152 } 7153 7154 public final void showSafeModeOverlay() { 7155 View v = LayoutInflater.from(mContext).inflate( 7156 com.android.internal.R.layout.safe_mode, null); 7157 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7158 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7159 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7160 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7161 lp.gravity = Gravity.BOTTOM | Gravity.START; 7162 lp.format = v.getBackground().getOpacity(); 7163 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7164 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7165 ((WindowManager)mContext.getSystemService( 7166 Context.WINDOW_SERVICE)).addView(v, lp); 7167 } 7168 7169 public void noteWakeupAlarm(IIntentSender sender) { 7170 if (!(sender instanceof PendingIntentRecord)) { 7171 return; 7172 } 7173 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7174 synchronized (stats) { 7175 if (mBatteryStatsService.isOnBattery()) { 7176 mBatteryStatsService.enforceCallingPermission(); 7177 PendingIntentRecord rec = (PendingIntentRecord)sender; 7178 int MY_UID = Binder.getCallingUid(); 7179 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7180 BatteryStatsImpl.Uid.Pkg pkg = 7181 stats.getPackageStatsLocked(uid, rec.key.packageName); 7182 pkg.incWakeupsLocked(); 7183 } 7184 } 7185 } 7186 7187 public boolean killPids(int[] pids, String pReason, boolean secure) { 7188 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7189 throw new SecurityException("killPids only available to the system"); 7190 } 7191 String reason = (pReason == null) ? "Unknown" : pReason; 7192 // XXX Note: don't acquire main activity lock here, because the window 7193 // manager calls in with its locks held. 7194 7195 boolean killed = false; 7196 synchronized (mPidsSelfLocked) { 7197 int[] types = new int[pids.length]; 7198 int worstType = 0; 7199 for (int i=0; i<pids.length; i++) { 7200 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7201 if (proc != null) { 7202 int type = proc.setAdj; 7203 types[i] = type; 7204 if (type > worstType) { 7205 worstType = type; 7206 } 7207 } 7208 } 7209 7210 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7211 // then constrain it so we will kill all hidden procs. 7212 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7213 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7214 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7215 } 7216 7217 // If this is not a secure call, don't let it kill processes that 7218 // are important. 7219 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7220 worstType = ProcessList.SERVICE_ADJ; 7221 } 7222 7223 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7224 for (int i=0; i<pids.length; i++) { 7225 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7226 if (proc == null) { 7227 continue; 7228 } 7229 int adj = proc.setAdj; 7230 if (adj >= worstType && !proc.killedBackground) { 7231 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7232 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7233 proc.processName, adj, reason); 7234 killed = true; 7235 proc.killedBackground = true; 7236 Process.killProcessQuiet(pids[i]); 7237 } 7238 } 7239 } 7240 return killed; 7241 } 7242 7243 @Override 7244 public boolean killProcessesBelowForeground(String reason) { 7245 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7246 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7247 } 7248 7249 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7250 } 7251 7252 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7253 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7254 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7255 } 7256 7257 boolean killed = false; 7258 synchronized (mPidsSelfLocked) { 7259 final int size = mPidsSelfLocked.size(); 7260 for (int i = 0; i < size; i++) { 7261 final int pid = mPidsSelfLocked.keyAt(i); 7262 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7263 if (proc == null) continue; 7264 7265 final int adj = proc.setAdj; 7266 if (adj > belowAdj && !proc.killedBackground) { 7267 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7268 EventLog.writeEvent( 7269 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7270 killed = true; 7271 proc.killedBackground = true; 7272 Process.killProcessQuiet(pid); 7273 } 7274 } 7275 } 7276 return killed; 7277 } 7278 7279 public final void startRunning(String pkg, String cls, String action, 7280 String data) { 7281 synchronized(this) { 7282 if (mStartRunning) { 7283 return; 7284 } 7285 mStartRunning = true; 7286 mTopComponent = pkg != null && cls != null 7287 ? new ComponentName(pkg, cls) : null; 7288 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7289 mTopData = data; 7290 if (!mSystemReady) { 7291 return; 7292 } 7293 } 7294 7295 systemReady(null); 7296 } 7297 7298 private void retrieveSettings() { 7299 final ContentResolver resolver = mContext.getContentResolver(); 7300 String debugApp = Settings.System.getString( 7301 resolver, Settings.System.DEBUG_APP); 7302 boolean waitForDebugger = Settings.System.getInt( 7303 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7304 boolean alwaysFinishActivities = Settings.System.getInt( 7305 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7306 7307 Configuration configuration = new Configuration(); 7308 Settings.System.getConfiguration(resolver, configuration); 7309 7310 synchronized (this) { 7311 mDebugApp = mOrigDebugApp = debugApp; 7312 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7313 mAlwaysFinishActivities = alwaysFinishActivities; 7314 // This happens before any activities are started, so we can 7315 // change mConfiguration in-place. 7316 updateConfigurationLocked(configuration, null, false, true); 7317 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7318 } 7319 } 7320 7321 public boolean testIsSystemReady() { 7322 // no need to synchronize(this) just to read & return the value 7323 return mSystemReady; 7324 } 7325 7326 private static File getCalledPreBootReceiversFile() { 7327 File dataDir = Environment.getDataDirectory(); 7328 File systemDir = new File(dataDir, "system"); 7329 File fname = new File(systemDir, "called_pre_boots.dat"); 7330 return fname; 7331 } 7332 7333 static final int LAST_DONE_VERSION = 10000; 7334 7335 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7336 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7337 File file = getCalledPreBootReceiversFile(); 7338 FileInputStream fis = null; 7339 try { 7340 fis = new FileInputStream(file); 7341 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7342 int fvers = dis.readInt(); 7343 if (fvers == LAST_DONE_VERSION) { 7344 String vers = dis.readUTF(); 7345 String codename = dis.readUTF(); 7346 String build = dis.readUTF(); 7347 if (android.os.Build.VERSION.RELEASE.equals(vers) 7348 && android.os.Build.VERSION.CODENAME.equals(codename) 7349 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7350 int num = dis.readInt(); 7351 while (num > 0) { 7352 num--; 7353 String pkg = dis.readUTF(); 7354 String cls = dis.readUTF(); 7355 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7356 } 7357 } 7358 } 7359 } catch (FileNotFoundException e) { 7360 } catch (IOException e) { 7361 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7362 } finally { 7363 if (fis != null) { 7364 try { 7365 fis.close(); 7366 } catch (IOException e) { 7367 } 7368 } 7369 } 7370 return lastDoneReceivers; 7371 } 7372 7373 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7374 File file = getCalledPreBootReceiversFile(); 7375 FileOutputStream fos = null; 7376 DataOutputStream dos = null; 7377 try { 7378 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7379 fos = new FileOutputStream(file); 7380 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7381 dos.writeInt(LAST_DONE_VERSION); 7382 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7383 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7384 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7385 dos.writeInt(list.size()); 7386 for (int i=0; i<list.size(); i++) { 7387 dos.writeUTF(list.get(i).getPackageName()); 7388 dos.writeUTF(list.get(i).getClassName()); 7389 } 7390 } catch (IOException e) { 7391 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7392 file.delete(); 7393 } finally { 7394 FileUtils.sync(fos); 7395 if (dos != null) { 7396 try { 7397 dos.close(); 7398 } catch (IOException e) { 7399 // TODO Auto-generated catch block 7400 e.printStackTrace(); 7401 } 7402 } 7403 } 7404 } 7405 7406 public void systemReady(final Runnable goingCallback) { 7407 synchronized(this) { 7408 if (mSystemReady) { 7409 if (goingCallback != null) goingCallback.run(); 7410 return; 7411 } 7412 7413 // Check to see if there are any update receivers to run. 7414 if (!mDidUpdate) { 7415 if (mWaitingUpdate) { 7416 return; 7417 } 7418 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7419 List<ResolveInfo> ris = null; 7420 try { 7421 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7422 intent, null, 0, 0); 7423 } catch (RemoteException e) { 7424 } 7425 if (ris != null) { 7426 for (int i=ris.size()-1; i>=0; i--) { 7427 if ((ris.get(i).activityInfo.applicationInfo.flags 7428 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7429 ris.remove(i); 7430 } 7431 } 7432 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7433 7434 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7435 7436 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7437 for (int i=0; i<ris.size(); i++) { 7438 ActivityInfo ai = ris.get(i).activityInfo; 7439 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7440 if (lastDoneReceivers.contains(comp)) { 7441 ris.remove(i); 7442 i--; 7443 } 7444 } 7445 7446 for (int i=0; i<ris.size(); i++) { 7447 ActivityInfo ai = ris.get(i).activityInfo; 7448 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7449 doneReceivers.add(comp); 7450 intent.setComponent(comp); 7451 IIntentReceiver finisher = null; 7452 if (i == ris.size()-1) { 7453 finisher = new IIntentReceiver.Stub() { 7454 public void performReceive(Intent intent, int resultCode, 7455 String data, Bundle extras, boolean ordered, 7456 boolean sticky) { 7457 // The raw IIntentReceiver interface is called 7458 // with the AM lock held, so redispatch to 7459 // execute our code without the lock. 7460 mHandler.post(new Runnable() { 7461 public void run() { 7462 synchronized (ActivityManagerService.this) { 7463 mDidUpdate = true; 7464 } 7465 writeLastDonePreBootReceivers(doneReceivers); 7466 showBootMessage(mContext.getText( 7467 R.string.android_upgrading_complete), 7468 false); 7469 systemReady(goingCallback); 7470 } 7471 }); 7472 } 7473 }; 7474 } 7475 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7476 /* TODO: Send this to all users */ 7477 broadcastIntentLocked(null, null, intent, null, finisher, 7478 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7479 0 /* UserId zero */); 7480 if (finisher != null) { 7481 mWaitingUpdate = true; 7482 } 7483 } 7484 } 7485 if (mWaitingUpdate) { 7486 return; 7487 } 7488 mDidUpdate = true; 7489 } 7490 7491 mSystemReady = true; 7492 if (!mStartRunning) { 7493 return; 7494 } 7495 } 7496 7497 ArrayList<ProcessRecord> procsToKill = null; 7498 synchronized(mPidsSelfLocked) { 7499 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7500 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7501 if (!isAllowedWhileBooting(proc.info)){ 7502 if (procsToKill == null) { 7503 procsToKill = new ArrayList<ProcessRecord>(); 7504 } 7505 procsToKill.add(proc); 7506 } 7507 } 7508 } 7509 7510 synchronized(this) { 7511 if (procsToKill != null) { 7512 for (int i=procsToKill.size()-1; i>=0; i--) { 7513 ProcessRecord proc = procsToKill.get(i); 7514 Slog.i(TAG, "Removing system update proc: " + proc); 7515 removeProcessLocked(proc, true, false, "system update done"); 7516 } 7517 } 7518 7519 // Now that we have cleaned up any update processes, we 7520 // are ready to start launching real processes and know that 7521 // we won't trample on them any more. 7522 mProcessesReady = true; 7523 } 7524 7525 Slog.i(TAG, "System now ready"); 7526 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7527 SystemClock.uptimeMillis()); 7528 7529 synchronized(this) { 7530 // Make sure we have no pre-ready processes sitting around. 7531 7532 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7533 ResolveInfo ri = mContext.getPackageManager() 7534 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7535 STOCK_PM_FLAGS); 7536 CharSequence errorMsg = null; 7537 if (ri != null) { 7538 ActivityInfo ai = ri.activityInfo; 7539 ApplicationInfo app = ai.applicationInfo; 7540 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7541 mTopAction = Intent.ACTION_FACTORY_TEST; 7542 mTopData = null; 7543 mTopComponent = new ComponentName(app.packageName, 7544 ai.name); 7545 } else { 7546 errorMsg = mContext.getResources().getText( 7547 com.android.internal.R.string.factorytest_not_system); 7548 } 7549 } else { 7550 errorMsg = mContext.getResources().getText( 7551 com.android.internal.R.string.factorytest_no_action); 7552 } 7553 if (errorMsg != null) { 7554 mTopAction = null; 7555 mTopData = null; 7556 mTopComponent = null; 7557 Message msg = Message.obtain(); 7558 msg.what = SHOW_FACTORY_ERROR_MSG; 7559 msg.getData().putCharSequence("msg", errorMsg); 7560 mHandler.sendMessage(msg); 7561 } 7562 } 7563 } 7564 7565 retrieveSettings(); 7566 7567 if (goingCallback != null) goingCallback.run(); 7568 7569 synchronized (this) { 7570 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7571 try { 7572 List apps = AppGlobals.getPackageManager(). 7573 getPersistentApplications(STOCK_PM_FLAGS); 7574 if (apps != null) { 7575 int N = apps.size(); 7576 int i; 7577 for (i=0; i<N; i++) { 7578 ApplicationInfo info 7579 = (ApplicationInfo)apps.get(i); 7580 if (info != null && 7581 !info.packageName.equals("android")) { 7582 addAppLocked(info, false); 7583 } 7584 } 7585 } 7586 } catch (RemoteException ex) { 7587 // pm is in same process, this will never happen. 7588 } 7589 } 7590 7591 // Start up initial activity. 7592 mBooting = true; 7593 7594 try { 7595 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7596 Message msg = Message.obtain(); 7597 msg.what = SHOW_UID_ERROR_MSG; 7598 mHandler.sendMessage(msg); 7599 } 7600 } catch (RemoteException e) { 7601 } 7602 7603 mMainStack.resumeTopActivityLocked(null); 7604 } 7605 } 7606 7607 private boolean makeAppCrashingLocked(ProcessRecord app, 7608 String shortMsg, String longMsg, String stackTrace) { 7609 app.crashing = true; 7610 app.crashingReport = generateProcessError(app, 7611 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7612 startAppProblemLocked(app); 7613 app.stopFreezingAllLocked(); 7614 return handleAppCrashLocked(app); 7615 } 7616 7617 private void makeAppNotRespondingLocked(ProcessRecord app, 7618 String activity, String shortMsg, String longMsg) { 7619 app.notResponding = true; 7620 app.notRespondingReport = generateProcessError(app, 7621 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7622 activity, shortMsg, longMsg, null); 7623 startAppProblemLocked(app); 7624 app.stopFreezingAllLocked(); 7625 } 7626 7627 /** 7628 * Generate a process error record, suitable for attachment to a ProcessRecord. 7629 * 7630 * @param app The ProcessRecord in which the error occurred. 7631 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7632 * ActivityManager.AppErrorStateInfo 7633 * @param activity The activity associated with the crash, if known. 7634 * @param shortMsg Short message describing the crash. 7635 * @param longMsg Long message describing the crash. 7636 * @param stackTrace Full crash stack trace, may be null. 7637 * 7638 * @return Returns a fully-formed AppErrorStateInfo record. 7639 */ 7640 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7641 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7642 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7643 7644 report.condition = condition; 7645 report.processName = app.processName; 7646 report.pid = app.pid; 7647 report.uid = app.info.uid; 7648 report.tag = activity; 7649 report.shortMsg = shortMsg; 7650 report.longMsg = longMsg; 7651 report.stackTrace = stackTrace; 7652 7653 return report; 7654 } 7655 7656 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7657 synchronized (this) { 7658 app.crashing = false; 7659 app.crashingReport = null; 7660 app.notResponding = false; 7661 app.notRespondingReport = null; 7662 if (app.anrDialog == fromDialog) { 7663 app.anrDialog = null; 7664 } 7665 if (app.waitDialog == fromDialog) { 7666 app.waitDialog = null; 7667 } 7668 if (app.pid > 0 && app.pid != MY_PID) { 7669 handleAppCrashLocked(app); 7670 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7671 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7672 app.processName, app.setAdj, "user's request after error"); 7673 Process.killProcessQuiet(app.pid); 7674 } 7675 } 7676 } 7677 7678 private boolean handleAppCrashLocked(ProcessRecord app) { 7679 if (mHeadless) { 7680 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7681 return false; 7682 } 7683 long now = SystemClock.uptimeMillis(); 7684 7685 Long crashTime; 7686 if (!app.isolated) { 7687 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7688 } else { 7689 crashTime = null; 7690 } 7691 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7692 // This process loses! 7693 Slog.w(TAG, "Process " + app.info.processName 7694 + " has crashed too many times: killing!"); 7695 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7696 app.info.processName, app.uid); 7697 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7698 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7699 if (r.app == app) { 7700 Slog.w(TAG, " Force finishing activity " 7701 + r.intent.getComponent().flattenToShortString()); 7702 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7703 } 7704 } 7705 if (!app.persistent) { 7706 // We don't want to start this process again until the user 7707 // explicitly does so... but for persistent process, we really 7708 // need to keep it running. If a persistent process is actually 7709 // repeatedly crashing, then badness for everyone. 7710 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7711 app.info.processName); 7712 if (!app.isolated) { 7713 // XXX We don't have a way to mark isolated processes 7714 // as bad, since they don't have a peristent identity. 7715 mBadProcesses.put(app.info.processName, app.uid, now); 7716 mProcessCrashTimes.remove(app.info.processName, app.uid); 7717 } 7718 app.bad = true; 7719 app.removed = true; 7720 // Don't let services in this process be restarted and potentially 7721 // annoy the user repeatedly. Unless it is persistent, since those 7722 // processes run critical code. 7723 removeProcessLocked(app, false, false, "crash"); 7724 mMainStack.resumeTopActivityLocked(null); 7725 return false; 7726 } 7727 mMainStack.resumeTopActivityLocked(null); 7728 } else { 7729 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7730 if (r != null && r.app == app) { 7731 // If the top running activity is from this crashing 7732 // process, then terminate it to avoid getting in a loop. 7733 Slog.w(TAG, " Force finishing activity " 7734 + r.intent.getComponent().flattenToShortString()); 7735 int index = mMainStack.indexOfActivityLocked(r); 7736 r.stack.finishActivityLocked(r, index, 7737 Activity.RESULT_CANCELED, null, "crashed"); 7738 // Also terminate any activities below it that aren't yet 7739 // stopped, to avoid a situation where one will get 7740 // re-start our crashing activity once it gets resumed again. 7741 index--; 7742 if (index >= 0) { 7743 r = (ActivityRecord)mMainStack.mHistory.get(index); 7744 if (r.state == ActivityState.RESUMED 7745 || r.state == ActivityState.PAUSING 7746 || r.state == ActivityState.PAUSED) { 7747 if (!r.isHomeActivity || mHomeProcess != r.app) { 7748 Slog.w(TAG, " Force finishing activity " 7749 + r.intent.getComponent().flattenToShortString()); 7750 r.stack.finishActivityLocked(r, index, 7751 Activity.RESULT_CANCELED, null, "crashed"); 7752 } 7753 } 7754 } 7755 } 7756 } 7757 7758 // Bump up the crash count of any services currently running in the proc. 7759 if (app.services.size() != 0) { 7760 // Any services running in the application need to be placed 7761 // back in the pending list. 7762 Iterator<ServiceRecord> it = app.services.iterator(); 7763 while (it.hasNext()) { 7764 ServiceRecord sr = it.next(); 7765 sr.crashCount++; 7766 } 7767 } 7768 7769 // If the crashing process is what we consider to be the "home process" and it has been 7770 // replaced by a third-party app, clear the package preferred activities from packages 7771 // with a home activity running in the process to prevent a repeatedly crashing app 7772 // from blocking the user to manually clear the list. 7773 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7774 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7775 Iterator it = mHomeProcess.activities.iterator(); 7776 while (it.hasNext()) { 7777 ActivityRecord r = (ActivityRecord)it.next(); 7778 if (r.isHomeActivity) { 7779 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7780 try { 7781 ActivityThread.getPackageManager() 7782 .clearPackagePreferredActivities(r.packageName); 7783 } catch (RemoteException c) { 7784 // pm is in same process, this will never happen. 7785 } 7786 } 7787 } 7788 } 7789 7790 if (!app.isolated) { 7791 // XXX Can't keep track of crash times for isolated processes, 7792 // because they don't have a perisistent identity. 7793 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7794 } 7795 7796 return true; 7797 } 7798 7799 void startAppProblemLocked(ProcessRecord app) { 7800 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7801 mContext, app.info.packageName, app.info.flags); 7802 skipCurrentReceiverLocked(app); 7803 } 7804 7805 void skipCurrentReceiverLocked(ProcessRecord app) { 7806 for (BroadcastQueue queue : mBroadcastQueues) { 7807 queue.skipCurrentReceiverLocked(app); 7808 } 7809 } 7810 7811 /** 7812 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7813 * The application process will exit immediately after this call returns. 7814 * @param app object of the crashing app, null for the system server 7815 * @param crashInfo describing the exception 7816 */ 7817 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7818 ProcessRecord r = findAppProcess(app, "Crash"); 7819 final String processName = app == null ? "system_server" 7820 : (r == null ? "unknown" : r.processName); 7821 7822 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7823 processName, 7824 r == null ? -1 : r.info.flags, 7825 crashInfo.exceptionClassName, 7826 crashInfo.exceptionMessage, 7827 crashInfo.throwFileName, 7828 crashInfo.throwLineNumber); 7829 7830 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7831 7832 crashApplication(r, crashInfo); 7833 } 7834 7835 public void handleApplicationStrictModeViolation( 7836 IBinder app, 7837 int violationMask, 7838 StrictMode.ViolationInfo info) { 7839 ProcessRecord r = findAppProcess(app, "StrictMode"); 7840 if (r == null) { 7841 return; 7842 } 7843 7844 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7845 Integer stackFingerprint = info.hashCode(); 7846 boolean logIt = true; 7847 synchronized (mAlreadyLoggedViolatedStacks) { 7848 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7849 logIt = false; 7850 // TODO: sub-sample into EventLog for these, with 7851 // the info.durationMillis? Then we'd get 7852 // the relative pain numbers, without logging all 7853 // the stack traces repeatedly. We'd want to do 7854 // likewise in the client code, which also does 7855 // dup suppression, before the Binder call. 7856 } else { 7857 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7858 mAlreadyLoggedViolatedStacks.clear(); 7859 } 7860 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7861 } 7862 } 7863 if (logIt) { 7864 logStrictModeViolationToDropBox(r, info); 7865 } 7866 } 7867 7868 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7869 AppErrorResult result = new AppErrorResult(); 7870 synchronized (this) { 7871 final long origId = Binder.clearCallingIdentity(); 7872 7873 Message msg = Message.obtain(); 7874 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7875 HashMap<String, Object> data = new HashMap<String, Object>(); 7876 data.put("result", result); 7877 data.put("app", r); 7878 data.put("violationMask", violationMask); 7879 data.put("info", info); 7880 msg.obj = data; 7881 mHandler.sendMessage(msg); 7882 7883 Binder.restoreCallingIdentity(origId); 7884 } 7885 int res = result.get(); 7886 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7887 } 7888 } 7889 7890 // Depending on the policy in effect, there could be a bunch of 7891 // these in quick succession so we try to batch these together to 7892 // minimize disk writes, number of dropbox entries, and maximize 7893 // compression, by having more fewer, larger records. 7894 private void logStrictModeViolationToDropBox( 7895 ProcessRecord process, 7896 StrictMode.ViolationInfo info) { 7897 if (info == null) { 7898 return; 7899 } 7900 final boolean isSystemApp = process == null || 7901 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7902 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7903 final String processName = process == null ? "unknown" : process.processName; 7904 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7905 final DropBoxManager dbox = (DropBoxManager) 7906 mContext.getSystemService(Context.DROPBOX_SERVICE); 7907 7908 // Exit early if the dropbox isn't configured to accept this report type. 7909 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7910 7911 boolean bufferWasEmpty; 7912 boolean needsFlush; 7913 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7914 synchronized (sb) { 7915 bufferWasEmpty = sb.length() == 0; 7916 appendDropBoxProcessHeaders(process, processName, sb); 7917 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7918 sb.append("System-App: ").append(isSystemApp).append("\n"); 7919 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7920 if (info.violationNumThisLoop != 0) { 7921 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7922 } 7923 if (info.numAnimationsRunning != 0) { 7924 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7925 } 7926 if (info.broadcastIntentAction != null) { 7927 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7928 } 7929 if (info.durationMillis != -1) { 7930 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7931 } 7932 if (info.numInstances != -1) { 7933 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7934 } 7935 if (info.tags != null) { 7936 for (String tag : info.tags) { 7937 sb.append("Span-Tag: ").append(tag).append("\n"); 7938 } 7939 } 7940 sb.append("\n"); 7941 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7942 sb.append(info.crashInfo.stackTrace); 7943 } 7944 sb.append("\n"); 7945 7946 // Only buffer up to ~64k. Various logging bits truncate 7947 // things at 128k. 7948 needsFlush = (sb.length() > 64 * 1024); 7949 } 7950 7951 // Flush immediately if the buffer's grown too large, or this 7952 // is a non-system app. Non-system apps are isolated with a 7953 // different tag & policy and not batched. 7954 // 7955 // Batching is useful during internal testing with 7956 // StrictMode settings turned up high. Without batching, 7957 // thousands of separate files could be created on boot. 7958 if (!isSystemApp || needsFlush) { 7959 new Thread("Error dump: " + dropboxTag) { 7960 @Override 7961 public void run() { 7962 String report; 7963 synchronized (sb) { 7964 report = sb.toString(); 7965 sb.delete(0, sb.length()); 7966 sb.trimToSize(); 7967 } 7968 if (report.length() != 0) { 7969 dbox.addText(dropboxTag, report); 7970 } 7971 } 7972 }.start(); 7973 return; 7974 } 7975 7976 // System app batching: 7977 if (!bufferWasEmpty) { 7978 // An existing dropbox-writing thread is outstanding, so 7979 // we don't need to start it up. The existing thread will 7980 // catch the buffer appends we just did. 7981 return; 7982 } 7983 7984 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 7985 // (After this point, we shouldn't access AMS internal data structures.) 7986 new Thread("Error dump: " + dropboxTag) { 7987 @Override 7988 public void run() { 7989 // 5 second sleep to let stacks arrive and be batched together 7990 try { 7991 Thread.sleep(5000); // 5 seconds 7992 } catch (InterruptedException e) {} 7993 7994 String errorReport; 7995 synchronized (mStrictModeBuffer) { 7996 errorReport = mStrictModeBuffer.toString(); 7997 if (errorReport.length() == 0) { 7998 return; 7999 } 8000 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8001 mStrictModeBuffer.trimToSize(); 8002 } 8003 dbox.addText(dropboxTag, errorReport); 8004 } 8005 }.start(); 8006 } 8007 8008 /** 8009 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8010 * @param app object of the crashing app, null for the system server 8011 * @param tag reported by the caller 8012 * @param crashInfo describing the context of the error 8013 * @return true if the process should exit immediately (WTF is fatal) 8014 */ 8015 public boolean handleApplicationWtf(IBinder app, String tag, 8016 ApplicationErrorReport.CrashInfo crashInfo) { 8017 ProcessRecord r = findAppProcess(app, "WTF"); 8018 final String processName = app == null ? "system_server" 8019 : (r == null ? "unknown" : r.processName); 8020 8021 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8022 processName, 8023 r == null ? -1 : r.info.flags, 8024 tag, crashInfo.exceptionMessage); 8025 8026 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8027 8028 if (r != null && r.pid != Process.myPid() && 8029 Settings.Secure.getInt(mContext.getContentResolver(), 8030 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8031 crashApplication(r, crashInfo); 8032 return true; 8033 } else { 8034 return false; 8035 } 8036 } 8037 8038 /** 8039 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8040 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8041 */ 8042 private ProcessRecord findAppProcess(IBinder app, String reason) { 8043 if (app == null) { 8044 return null; 8045 } 8046 8047 synchronized (this) { 8048 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8049 final int NA = apps.size(); 8050 for (int ia=0; ia<NA; ia++) { 8051 ProcessRecord p = apps.valueAt(ia); 8052 if (p.thread != null && p.thread.asBinder() == app) { 8053 return p; 8054 } 8055 } 8056 } 8057 8058 Slog.w(TAG, "Can't find mystery application for " + reason 8059 + " from pid=" + Binder.getCallingPid() 8060 + " uid=" + Binder.getCallingUid() + ": " + app); 8061 return null; 8062 } 8063 } 8064 8065 /** 8066 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8067 * to append various headers to the dropbox log text. 8068 */ 8069 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8070 StringBuilder sb) { 8071 // Watchdog thread ends up invoking this function (with 8072 // a null ProcessRecord) to add the stack file to dropbox. 8073 // Do not acquire a lock on this (am) in such cases, as it 8074 // could cause a potential deadlock, if and when watchdog 8075 // is invoked due to unavailability of lock on am and it 8076 // would prevent watchdog from killing system_server. 8077 if (process == null) { 8078 sb.append("Process: ").append(processName).append("\n"); 8079 return; 8080 } 8081 // Note: ProcessRecord 'process' is guarded by the service 8082 // instance. (notably process.pkgList, which could otherwise change 8083 // concurrently during execution of this method) 8084 synchronized (this) { 8085 sb.append("Process: ").append(processName).append("\n"); 8086 int flags = process.info.flags; 8087 IPackageManager pm = AppGlobals.getPackageManager(); 8088 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8089 for (String pkg : process.pkgList) { 8090 sb.append("Package: ").append(pkg); 8091 try { 8092 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8093 if (pi != null) { 8094 sb.append(" v").append(pi.versionCode); 8095 if (pi.versionName != null) { 8096 sb.append(" (").append(pi.versionName).append(")"); 8097 } 8098 } 8099 } catch (RemoteException e) { 8100 Slog.e(TAG, "Error getting package info: " + pkg, e); 8101 } 8102 sb.append("\n"); 8103 } 8104 } 8105 } 8106 8107 private static String processClass(ProcessRecord process) { 8108 if (process == null || process.pid == MY_PID) { 8109 return "system_server"; 8110 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8111 return "system_app"; 8112 } else { 8113 return "data_app"; 8114 } 8115 } 8116 8117 /** 8118 * Write a description of an error (crash, WTF, ANR) to the drop box. 8119 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8120 * @param process which caused the error, null means the system server 8121 * @param activity which triggered the error, null if unknown 8122 * @param parent activity related to the error, null if unknown 8123 * @param subject line related to the error, null if absent 8124 * @param report in long form describing the error, null if absent 8125 * @param logFile to include in the report, null if none 8126 * @param crashInfo giving an application stack trace, null if absent 8127 */ 8128 public void addErrorToDropBox(String eventType, 8129 ProcessRecord process, String processName, ActivityRecord activity, 8130 ActivityRecord parent, String subject, 8131 final String report, final File logFile, 8132 final ApplicationErrorReport.CrashInfo crashInfo) { 8133 // NOTE -- this must never acquire the ActivityManagerService lock, 8134 // otherwise the watchdog may be prevented from resetting the system. 8135 8136 final String dropboxTag = processClass(process) + "_" + eventType; 8137 final DropBoxManager dbox = (DropBoxManager) 8138 mContext.getSystemService(Context.DROPBOX_SERVICE); 8139 8140 // Exit early if the dropbox isn't configured to accept this report type. 8141 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8142 8143 final StringBuilder sb = new StringBuilder(1024); 8144 appendDropBoxProcessHeaders(process, processName, sb); 8145 if (activity != null) { 8146 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8147 } 8148 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8149 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8150 } 8151 if (parent != null && parent != activity) { 8152 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8153 } 8154 if (subject != null) { 8155 sb.append("Subject: ").append(subject).append("\n"); 8156 } 8157 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8158 if (Debug.isDebuggerConnected()) { 8159 sb.append("Debugger: Connected\n"); 8160 } 8161 sb.append("\n"); 8162 8163 // Do the rest in a worker thread to avoid blocking the caller on I/O 8164 // (After this point, we shouldn't access AMS internal data structures.) 8165 Thread worker = new Thread("Error dump: " + dropboxTag) { 8166 @Override 8167 public void run() { 8168 if (report != null) { 8169 sb.append(report); 8170 } 8171 if (logFile != null) { 8172 try { 8173 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8174 } catch (IOException e) { 8175 Slog.e(TAG, "Error reading " + logFile, e); 8176 } 8177 } 8178 if (crashInfo != null && crashInfo.stackTrace != null) { 8179 sb.append(crashInfo.stackTrace); 8180 } 8181 8182 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8183 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8184 if (lines > 0) { 8185 sb.append("\n"); 8186 8187 // Merge several logcat streams, and take the last N lines 8188 InputStreamReader input = null; 8189 try { 8190 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8191 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8192 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8193 8194 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8195 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8196 input = new InputStreamReader(logcat.getInputStream()); 8197 8198 int num; 8199 char[] buf = new char[8192]; 8200 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8201 } catch (IOException e) { 8202 Slog.e(TAG, "Error running logcat", e); 8203 } finally { 8204 if (input != null) try { input.close(); } catch (IOException e) {} 8205 } 8206 } 8207 8208 dbox.addText(dropboxTag, sb.toString()); 8209 } 8210 }; 8211 8212 if (process == null) { 8213 // If process is null, we are being called from some internal code 8214 // and may be about to die -- run this synchronously. 8215 worker.run(); 8216 } else { 8217 worker.start(); 8218 } 8219 } 8220 8221 /** 8222 * Bring up the "unexpected error" dialog box for a crashing app. 8223 * Deal with edge cases (intercepts from instrumented applications, 8224 * ActivityController, error intent receivers, that sort of thing). 8225 * @param r the application crashing 8226 * @param crashInfo describing the failure 8227 */ 8228 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8229 long timeMillis = System.currentTimeMillis(); 8230 String shortMsg = crashInfo.exceptionClassName; 8231 String longMsg = crashInfo.exceptionMessage; 8232 String stackTrace = crashInfo.stackTrace; 8233 if (shortMsg != null && longMsg != null) { 8234 longMsg = shortMsg + ": " + longMsg; 8235 } else if (shortMsg != null) { 8236 longMsg = shortMsg; 8237 } 8238 8239 AppErrorResult result = new AppErrorResult(); 8240 synchronized (this) { 8241 if (mController != null) { 8242 try { 8243 String name = r != null ? r.processName : null; 8244 int pid = r != null ? r.pid : Binder.getCallingPid(); 8245 if (!mController.appCrashed(name, pid, 8246 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8247 Slog.w(TAG, "Force-killing crashed app " + name 8248 + " at watcher's request"); 8249 Process.killProcess(pid); 8250 return; 8251 } 8252 } catch (RemoteException e) { 8253 mController = null; 8254 } 8255 } 8256 8257 final long origId = Binder.clearCallingIdentity(); 8258 8259 // If this process is running instrumentation, finish it. 8260 if (r != null && r.instrumentationClass != null) { 8261 Slog.w(TAG, "Error in app " + r.processName 8262 + " running instrumentation " + r.instrumentationClass + ":"); 8263 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8264 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8265 Bundle info = new Bundle(); 8266 info.putString("shortMsg", shortMsg); 8267 info.putString("longMsg", longMsg); 8268 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8269 Binder.restoreCallingIdentity(origId); 8270 return; 8271 } 8272 8273 // If we can't identify the process or it's already exceeded its crash quota, 8274 // quit right away without showing a crash dialog. 8275 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8276 Binder.restoreCallingIdentity(origId); 8277 return; 8278 } 8279 8280 Message msg = Message.obtain(); 8281 msg.what = SHOW_ERROR_MSG; 8282 HashMap data = new HashMap(); 8283 data.put("result", result); 8284 data.put("app", r); 8285 msg.obj = data; 8286 mHandler.sendMessage(msg); 8287 8288 Binder.restoreCallingIdentity(origId); 8289 } 8290 8291 int res = result.get(); 8292 8293 Intent appErrorIntent = null; 8294 synchronized (this) { 8295 if (r != null && !r.isolated) { 8296 // XXX Can't keep track of crash time for isolated processes, 8297 // since they don't have a persistent identity. 8298 mProcessCrashTimes.put(r.info.processName, r.uid, 8299 SystemClock.uptimeMillis()); 8300 } 8301 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8302 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8303 } 8304 } 8305 8306 if (appErrorIntent != null) { 8307 try { 8308 mContext.startActivity(appErrorIntent); 8309 } catch (ActivityNotFoundException e) { 8310 Slog.w(TAG, "bug report receiver dissappeared", e); 8311 } 8312 } 8313 } 8314 8315 Intent createAppErrorIntentLocked(ProcessRecord r, 8316 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8317 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8318 if (report == null) { 8319 return null; 8320 } 8321 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8322 result.setComponent(r.errorReportReceiver); 8323 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8324 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8325 return result; 8326 } 8327 8328 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8329 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8330 if (r.errorReportReceiver == null) { 8331 return null; 8332 } 8333 8334 if (!r.crashing && !r.notResponding) { 8335 return null; 8336 } 8337 8338 ApplicationErrorReport report = new ApplicationErrorReport(); 8339 report.packageName = r.info.packageName; 8340 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8341 report.processName = r.processName; 8342 report.time = timeMillis; 8343 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8344 8345 if (r.crashing) { 8346 report.type = ApplicationErrorReport.TYPE_CRASH; 8347 report.crashInfo = crashInfo; 8348 } else if (r.notResponding) { 8349 report.type = ApplicationErrorReport.TYPE_ANR; 8350 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8351 8352 report.anrInfo.activity = r.notRespondingReport.tag; 8353 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8354 report.anrInfo.info = r.notRespondingReport.longMsg; 8355 } 8356 8357 return report; 8358 } 8359 8360 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8361 enforceNotIsolatedCaller("getProcessesInErrorState"); 8362 // assume our apps are happy - lazy create the list 8363 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8364 8365 synchronized (this) { 8366 8367 // iterate across all processes 8368 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8369 ProcessRecord app = mLruProcesses.get(i); 8370 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8371 // This one's in trouble, so we'll generate a report for it 8372 // crashes are higher priority (in case there's a crash *and* an anr) 8373 ActivityManager.ProcessErrorStateInfo report = null; 8374 if (app.crashing) { 8375 report = app.crashingReport; 8376 } else if (app.notResponding) { 8377 report = app.notRespondingReport; 8378 } 8379 8380 if (report != null) { 8381 if (errList == null) { 8382 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8383 } 8384 errList.add(report); 8385 } else { 8386 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8387 " crashing = " + app.crashing + 8388 " notResponding = " + app.notResponding); 8389 } 8390 } 8391 } 8392 } 8393 8394 return errList; 8395 } 8396 8397 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8398 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8399 if (currApp != null) { 8400 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8401 } 8402 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8403 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8404 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8405 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8406 if (currApp != null) { 8407 currApp.lru = 0; 8408 } 8409 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8410 } else if (adj >= ProcessList.SERVICE_ADJ) { 8411 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8412 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8413 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8414 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8415 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8416 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8417 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8418 } else { 8419 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8420 } 8421 } 8422 8423 private void fillInProcMemInfo(ProcessRecord app, 8424 ActivityManager.RunningAppProcessInfo outInfo) { 8425 outInfo.pid = app.pid; 8426 outInfo.uid = app.info.uid; 8427 if (mHeavyWeightProcess == app) { 8428 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8429 } 8430 if (app.persistent) { 8431 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8432 } 8433 outInfo.lastTrimLevel = app.trimMemoryLevel; 8434 int adj = app.curAdj; 8435 outInfo.importance = oomAdjToImportance(adj, outInfo); 8436 outInfo.importanceReasonCode = app.adjTypeCode; 8437 } 8438 8439 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8440 enforceNotIsolatedCaller("getRunningAppProcesses"); 8441 // Lazy instantiation of list 8442 List<ActivityManager.RunningAppProcessInfo> runList = null; 8443 synchronized (this) { 8444 // Iterate across all processes 8445 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8446 ProcessRecord app = mLruProcesses.get(i); 8447 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8448 // Generate process state info for running application 8449 ActivityManager.RunningAppProcessInfo currApp = 8450 new ActivityManager.RunningAppProcessInfo(app.processName, 8451 app.pid, app.getPackageList()); 8452 fillInProcMemInfo(app, currApp); 8453 if (app.adjSource instanceof ProcessRecord) { 8454 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8455 currApp.importanceReasonImportance = oomAdjToImportance( 8456 app.adjSourceOom, null); 8457 } else if (app.adjSource instanceof ActivityRecord) { 8458 ActivityRecord r = (ActivityRecord)app.adjSource; 8459 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8460 } 8461 if (app.adjTarget instanceof ComponentName) { 8462 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8463 } 8464 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8465 // + " lru=" + currApp.lru); 8466 if (runList == null) { 8467 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8468 } 8469 runList.add(currApp); 8470 } 8471 } 8472 } 8473 return runList; 8474 } 8475 8476 public List<ApplicationInfo> getRunningExternalApplications() { 8477 enforceNotIsolatedCaller("getRunningExternalApplications"); 8478 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8479 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8480 if (runningApps != null && runningApps.size() > 0) { 8481 Set<String> extList = new HashSet<String>(); 8482 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8483 if (app.pkgList != null) { 8484 for (String pkg : app.pkgList) { 8485 extList.add(pkg); 8486 } 8487 } 8488 } 8489 IPackageManager pm = AppGlobals.getPackageManager(); 8490 for (String pkg : extList) { 8491 try { 8492 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8493 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8494 retList.add(info); 8495 } 8496 } catch (RemoteException e) { 8497 } 8498 } 8499 } 8500 return retList; 8501 } 8502 8503 @Override 8504 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8505 enforceNotIsolatedCaller("getMyMemoryState"); 8506 synchronized (this) { 8507 ProcessRecord proc; 8508 synchronized (mPidsSelfLocked) { 8509 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8510 } 8511 fillInProcMemInfo(proc, outInfo); 8512 } 8513 } 8514 8515 @Override 8516 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8517 if (checkCallingPermission(android.Manifest.permission.DUMP) 8518 != PackageManager.PERMISSION_GRANTED) { 8519 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8520 + Binder.getCallingPid() 8521 + ", uid=" + Binder.getCallingUid() 8522 + " without permission " 8523 + android.Manifest.permission.DUMP); 8524 return; 8525 } 8526 8527 boolean dumpAll = false; 8528 boolean dumpClient = false; 8529 String dumpPackage = null; 8530 8531 int opti = 0; 8532 while (opti < args.length) { 8533 String opt = args[opti]; 8534 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8535 break; 8536 } 8537 opti++; 8538 if ("-a".equals(opt)) { 8539 dumpAll = true; 8540 } else if ("-c".equals(opt)) { 8541 dumpClient = true; 8542 } else if ("-h".equals(opt)) { 8543 pw.println("Activity manager dump options:"); 8544 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8545 pw.println(" cmd may be one of:"); 8546 pw.println(" a[ctivities]: activity stack state"); 8547 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8548 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8549 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8550 pw.println(" o[om]: out of memory management"); 8551 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8552 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8553 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8554 pw.println(" service [COMP_SPEC]: service client-side state"); 8555 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8556 pw.println(" all: dump all activities"); 8557 pw.println(" top: dump the top activity"); 8558 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8559 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8560 pw.println(" a partial substring in a component name, a"); 8561 pw.println(" hex object identifier."); 8562 pw.println(" -a: include all available server state."); 8563 pw.println(" -c: include client state."); 8564 return; 8565 } else { 8566 pw.println("Unknown argument: " + opt + "; use -h for help"); 8567 } 8568 } 8569 8570 long origId = Binder.clearCallingIdentity(); 8571 boolean more = false; 8572 // Is the caller requesting to dump a particular piece of data? 8573 if (opti < args.length) { 8574 String cmd = args[opti]; 8575 opti++; 8576 if ("activities".equals(cmd) || "a".equals(cmd)) { 8577 synchronized (this) { 8578 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8579 } 8580 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8581 String[] newArgs; 8582 String name; 8583 if (opti >= args.length) { 8584 name = null; 8585 newArgs = EMPTY_STRING_ARRAY; 8586 } else { 8587 name = args[opti]; 8588 opti++; 8589 newArgs = new String[args.length - opti]; 8590 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8591 args.length - opti); 8592 } 8593 synchronized (this) { 8594 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8595 } 8596 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8597 String[] newArgs; 8598 String name; 8599 if (opti >= args.length) { 8600 name = null; 8601 newArgs = EMPTY_STRING_ARRAY; 8602 } else { 8603 name = args[opti]; 8604 opti++; 8605 newArgs = new String[args.length - opti]; 8606 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8607 args.length - opti); 8608 } 8609 synchronized (this) { 8610 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8611 } 8612 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8613 String[] newArgs; 8614 String name; 8615 if (opti >= args.length) { 8616 name = null; 8617 newArgs = EMPTY_STRING_ARRAY; 8618 } else { 8619 name = args[opti]; 8620 opti++; 8621 newArgs = new String[args.length - opti]; 8622 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8623 args.length - opti); 8624 } 8625 synchronized (this) { 8626 dumpProcessesLocked(fd, pw, args, opti, true, name); 8627 } 8628 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8629 synchronized (this) { 8630 dumpOomLocked(fd, pw, args, opti, true); 8631 } 8632 } else if ("provider".equals(cmd)) { 8633 String[] newArgs; 8634 String name; 8635 if (opti >= args.length) { 8636 name = null; 8637 newArgs = EMPTY_STRING_ARRAY; 8638 } else { 8639 name = args[opti]; 8640 opti++; 8641 newArgs = new String[args.length - opti]; 8642 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8643 } 8644 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8645 pw.println("No providers match: " + name); 8646 pw.println("Use -h for help."); 8647 } 8648 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8649 synchronized (this) { 8650 dumpProvidersLocked(fd, pw, args, opti, true, null); 8651 } 8652 } else if ("service".equals(cmd)) { 8653 String[] newArgs; 8654 String name; 8655 if (opti >= args.length) { 8656 name = null; 8657 newArgs = EMPTY_STRING_ARRAY; 8658 } else { 8659 name = args[opti]; 8660 opti++; 8661 newArgs = new String[args.length - opti]; 8662 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8663 args.length - opti); 8664 } 8665 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8666 pw.println("No services match: " + name); 8667 pw.println("Use -h for help."); 8668 } 8669 } else if ("package".equals(cmd)) { 8670 String[] newArgs; 8671 if (opti >= args.length) { 8672 pw.println("package: no package name specified"); 8673 pw.println("Use -h for help."); 8674 } else { 8675 dumpPackage = args[opti]; 8676 opti++; 8677 newArgs = new String[args.length - opti]; 8678 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8679 args.length - opti); 8680 args = newArgs; 8681 opti = 0; 8682 more = true; 8683 } 8684 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8685 synchronized (this) { 8686 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8687 } 8688 } else { 8689 // Dumping a single activity? 8690 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8691 pw.println("Bad activity command, or no activities match: " + cmd); 8692 pw.println("Use -h for help."); 8693 } 8694 } 8695 if (!more) { 8696 Binder.restoreCallingIdentity(origId); 8697 return; 8698 } 8699 } 8700 8701 // No piece of data specified, dump everything. 8702 synchronized (this) { 8703 boolean needSep; 8704 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8705 if (needSep) { 8706 pw.println(" "); 8707 } 8708 if (dumpAll) { 8709 pw.println("-------------------------------------------------------------------------------"); 8710 } 8711 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8712 if (needSep) { 8713 pw.println(" "); 8714 } 8715 if (dumpAll) { 8716 pw.println("-------------------------------------------------------------------------------"); 8717 } 8718 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8719 if (needSep) { 8720 pw.println(" "); 8721 } 8722 if (dumpAll) { 8723 pw.println("-------------------------------------------------------------------------------"); 8724 } 8725 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8726 if (needSep) { 8727 pw.println(" "); 8728 } 8729 if (dumpAll) { 8730 pw.println("-------------------------------------------------------------------------------"); 8731 } 8732 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8733 if (needSep) { 8734 pw.println(" "); 8735 } 8736 if (dumpAll) { 8737 pw.println("-------------------------------------------------------------------------------"); 8738 } 8739 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8740 } 8741 Binder.restoreCallingIdentity(origId); 8742 } 8743 8744 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8745 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8746 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8747 pw.println(" Main stack:"); 8748 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8749 dumpPackage); 8750 pw.println(" "); 8751 pw.println(" Running activities (most recent first):"); 8752 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8753 dumpPackage); 8754 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8755 pw.println(" "); 8756 pw.println(" Activities waiting for another to become visible:"); 8757 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8758 !dumpAll, false, dumpPackage); 8759 } 8760 if (mMainStack.mStoppingActivities.size() > 0) { 8761 pw.println(" "); 8762 pw.println(" Activities waiting to stop:"); 8763 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8764 !dumpAll, false, dumpPackage); 8765 } 8766 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8767 pw.println(" "); 8768 pw.println(" Activities waiting to sleep:"); 8769 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8770 !dumpAll, false, dumpPackage); 8771 } 8772 if (mMainStack.mFinishingActivities.size() > 0) { 8773 pw.println(" "); 8774 pw.println(" Activities waiting to finish:"); 8775 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8776 !dumpAll, false, dumpPackage); 8777 } 8778 8779 pw.println(" "); 8780 if (mMainStack.mPausingActivity != null) { 8781 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8782 } 8783 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8784 pw.println(" mFocusedActivity: " + mFocusedActivity); 8785 if (dumpAll) { 8786 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8787 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8788 pw.println(" mDismissKeyguardOnNextActivity: " 8789 + mMainStack.mDismissKeyguardOnNextActivity); 8790 } 8791 8792 if (mRecentTasks.size() > 0) { 8793 pw.println(); 8794 pw.println(" Recent tasks:"); 8795 8796 final int N = mRecentTasks.size(); 8797 for (int i=0; i<N; i++) { 8798 TaskRecord tr = mRecentTasks.get(i); 8799 if (dumpPackage != null) { 8800 if (tr.realActivity == null || 8801 !dumpPackage.equals(tr.realActivity)) { 8802 continue; 8803 } 8804 } 8805 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8806 pw.println(tr); 8807 if (dumpAll) { 8808 mRecentTasks.get(i).dump(pw, " "); 8809 } 8810 } 8811 } 8812 8813 if (dumpAll) { 8814 pw.println(" "); 8815 pw.println(" mCurTask: " + mCurTask); 8816 } 8817 8818 return true; 8819 } 8820 8821 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8822 int opti, boolean dumpAll, String dumpPackage) { 8823 boolean needSep = false; 8824 int numPers = 0; 8825 8826 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8827 8828 if (dumpAll) { 8829 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8830 final int NA = procs.size(); 8831 for (int ia=0; ia<NA; ia++) { 8832 ProcessRecord r = procs.valueAt(ia); 8833 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8834 continue; 8835 } 8836 if (!needSep) { 8837 pw.println(" All known processes:"); 8838 needSep = true; 8839 } 8840 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8841 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8842 pw.print(" "); pw.println(r); 8843 r.dump(pw, " "); 8844 if (r.persistent) { 8845 numPers++; 8846 } 8847 } 8848 } 8849 } 8850 8851 if (mIsolatedProcesses.size() > 0) { 8852 if (needSep) pw.println(" "); 8853 needSep = true; 8854 pw.println(" Isolated process list (sorted by uid):"); 8855 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8856 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8857 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8858 continue; 8859 } 8860 pw.println(String.format("%sIsolated #%2d: %s", 8861 " ", i, r.toString())); 8862 } 8863 } 8864 8865 if (mLruProcesses.size() > 0) { 8866 if (needSep) pw.println(" "); 8867 needSep = true; 8868 pw.println(" Process LRU list (sorted by oom_adj):"); 8869 dumpProcessOomList(pw, this, mLruProcesses, " ", 8870 "Proc", "PERS", false, dumpPackage); 8871 needSep = true; 8872 } 8873 8874 if (dumpAll) { 8875 synchronized (mPidsSelfLocked) { 8876 boolean printed = false; 8877 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8878 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8879 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8880 continue; 8881 } 8882 if (!printed) { 8883 if (needSep) pw.println(" "); 8884 needSep = true; 8885 pw.println(" PID mappings:"); 8886 printed = true; 8887 } 8888 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8889 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8890 } 8891 } 8892 } 8893 8894 if (mForegroundProcesses.size() > 0) { 8895 synchronized (mPidsSelfLocked) { 8896 boolean printed = false; 8897 for (int i=0; i<mForegroundProcesses.size(); i++) { 8898 ProcessRecord r = mPidsSelfLocked.get( 8899 mForegroundProcesses.valueAt(i).pid); 8900 if (dumpPackage != null && (r == null 8901 || !dumpPackage.equals(r.info.packageName))) { 8902 continue; 8903 } 8904 if (!printed) { 8905 if (needSep) pw.println(" "); 8906 needSep = true; 8907 pw.println(" Foreground Processes:"); 8908 printed = true; 8909 } 8910 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8911 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8912 } 8913 } 8914 } 8915 8916 if (mPersistentStartingProcesses.size() > 0) { 8917 if (needSep) pw.println(" "); 8918 needSep = true; 8919 pw.println(" Persisent processes that are starting:"); 8920 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8921 "Starting Norm", "Restarting PERS", dumpPackage); 8922 } 8923 8924 if (mRemovedProcesses.size() > 0) { 8925 if (needSep) pw.println(" "); 8926 needSep = true; 8927 pw.println(" Processes that are being removed:"); 8928 dumpProcessList(pw, this, mRemovedProcesses, " ", 8929 "Removed Norm", "Removed PERS", dumpPackage); 8930 } 8931 8932 if (mProcessesOnHold.size() > 0) { 8933 if (needSep) pw.println(" "); 8934 needSep = true; 8935 pw.println(" Processes that are on old until the system is ready:"); 8936 dumpProcessList(pw, this, mProcessesOnHold, " ", 8937 "OnHold Norm", "OnHold PERS", dumpPackage); 8938 } 8939 8940 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8941 8942 if (mProcessCrashTimes.getMap().size() > 0) { 8943 boolean printed = false; 8944 long now = SystemClock.uptimeMillis(); 8945 for (Map.Entry<String, SparseArray<Long>> procs 8946 : mProcessCrashTimes.getMap().entrySet()) { 8947 String pname = procs.getKey(); 8948 SparseArray<Long> uids = procs.getValue(); 8949 final int N = uids.size(); 8950 for (int i=0; i<N; i++) { 8951 int puid = uids.keyAt(i); 8952 ProcessRecord r = mProcessNames.get(pname, puid); 8953 if (dumpPackage != null && (r == null 8954 || !dumpPackage.equals(r.info.packageName))) { 8955 continue; 8956 } 8957 if (!printed) { 8958 if (needSep) pw.println(" "); 8959 needSep = true; 8960 pw.println(" Time since processes crashed:"); 8961 printed = true; 8962 } 8963 pw.print(" Process "); pw.print(pname); 8964 pw.print(" uid "); pw.print(puid); 8965 pw.print(": last crashed "); 8966 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8967 pw.println(" ago"); 8968 } 8969 } 8970 } 8971 8972 if (mBadProcesses.getMap().size() > 0) { 8973 boolean printed = false; 8974 for (Map.Entry<String, SparseArray<Long>> procs 8975 : mBadProcesses.getMap().entrySet()) { 8976 String pname = procs.getKey(); 8977 SparseArray<Long> uids = procs.getValue(); 8978 final int N = uids.size(); 8979 for (int i=0; i<N; i++) { 8980 int puid = uids.keyAt(i); 8981 ProcessRecord r = mProcessNames.get(pname, puid); 8982 if (dumpPackage != null && (r == null 8983 || !dumpPackage.equals(r.info.packageName))) { 8984 continue; 8985 } 8986 if (!printed) { 8987 if (needSep) pw.println(" "); 8988 needSep = true; 8989 pw.println(" Bad processes:"); 8990 } 8991 pw.print(" Bad process "); pw.print(pname); 8992 pw.print(" uid "); pw.print(puid); 8993 pw.print(": crashed at time "); 8994 pw.println(uids.valueAt(i)); 8995 } 8996 } 8997 } 8998 8999 pw.println(); 9000 pw.println(" mHomeProcess: " + mHomeProcess); 9001 pw.println(" mPreviousProcess: " + mPreviousProcess); 9002 if (dumpAll) { 9003 StringBuilder sb = new StringBuilder(128); 9004 sb.append(" mPreviousProcessVisibleTime: "); 9005 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9006 pw.println(sb); 9007 } 9008 if (mHeavyWeightProcess != null) { 9009 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9010 } 9011 pw.println(" mConfiguration: " + mConfiguration); 9012 if (dumpAll) { 9013 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9014 if (mCompatModePackages.getPackages().size() > 0) { 9015 boolean printed = false; 9016 for (Map.Entry<String, Integer> entry 9017 : mCompatModePackages.getPackages().entrySet()) { 9018 String pkg = entry.getKey(); 9019 int mode = entry.getValue(); 9020 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9021 continue; 9022 } 9023 if (!printed) { 9024 pw.println(" mScreenCompatPackages:"); 9025 printed = true; 9026 } 9027 pw.print(" "); pw.print(pkg); pw.print(": "); 9028 pw.print(mode); pw.println(); 9029 } 9030 } 9031 } 9032 if (mSleeping || mWentToSleep || mLockScreenShown) { 9033 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9034 + " mLockScreenShown " + mLockScreenShown); 9035 } 9036 if (mShuttingDown) { 9037 pw.println(" mShuttingDown=" + mShuttingDown); 9038 } 9039 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9040 || mOrigWaitForDebugger) { 9041 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9042 + " mDebugTransient=" + mDebugTransient 9043 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9044 } 9045 if (mOpenGlTraceApp != null) { 9046 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9047 } 9048 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9049 || mProfileFd != null) { 9050 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9051 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9052 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9053 + mAutoStopProfiler); 9054 } 9055 if (mAlwaysFinishActivities || mController != null) { 9056 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9057 + " mController=" + mController); 9058 } 9059 if (dumpAll) { 9060 pw.println(" Total persistent processes: " + numPers); 9061 pw.println(" mStartRunning=" + mStartRunning 9062 + " mProcessesReady=" + mProcessesReady 9063 + " mSystemReady=" + mSystemReady); 9064 pw.println(" mBooting=" + mBooting 9065 + " mBooted=" + mBooted 9066 + " mFactoryTest=" + mFactoryTest); 9067 pw.print(" mLastPowerCheckRealtime="); 9068 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9069 pw.println(""); 9070 pw.print(" mLastPowerCheckUptime="); 9071 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9072 pw.println(""); 9073 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9074 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9075 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9076 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9077 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9078 } 9079 9080 return true; 9081 } 9082 9083 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9084 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9085 if (mProcessesToGc.size() > 0) { 9086 boolean printed = false; 9087 long now = SystemClock.uptimeMillis(); 9088 for (int i=0; i<mProcessesToGc.size(); i++) { 9089 ProcessRecord proc = mProcessesToGc.get(i); 9090 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9091 continue; 9092 } 9093 if (!printed) { 9094 if (needSep) pw.println(" "); 9095 needSep = true; 9096 pw.println(" Processes that are waiting to GC:"); 9097 printed = true; 9098 } 9099 pw.print(" Process "); pw.println(proc); 9100 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9101 pw.print(", last gced="); 9102 pw.print(now-proc.lastRequestedGc); 9103 pw.print(" ms ago, last lowMem="); 9104 pw.print(now-proc.lastLowMemory); 9105 pw.println(" ms ago"); 9106 9107 } 9108 } 9109 return needSep; 9110 } 9111 9112 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9113 int opti, boolean dumpAll) { 9114 boolean needSep = false; 9115 9116 if (mLruProcesses.size() > 0) { 9117 if (needSep) pw.println(" "); 9118 needSep = true; 9119 pw.println(" OOM levels:"); 9120 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9121 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9122 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9123 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9124 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9125 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9126 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9127 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9128 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9129 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9130 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9131 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9132 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9133 9134 if (needSep) pw.println(" "); 9135 needSep = true; 9136 pw.println(" Process OOM control:"); 9137 dumpProcessOomList(pw, this, mLruProcesses, " ", 9138 "Proc", "PERS", true, null); 9139 needSep = true; 9140 } 9141 9142 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9143 9144 pw.println(); 9145 pw.println(" mHomeProcess: " + mHomeProcess); 9146 pw.println(" mPreviousProcess: " + mPreviousProcess); 9147 if (mHeavyWeightProcess != null) { 9148 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9149 } 9150 9151 return true; 9152 } 9153 9154 /** 9155 * There are three ways to call this: 9156 * - no provider specified: dump all the providers 9157 * - a flattened component name that matched an existing provider was specified as the 9158 * first arg: dump that one provider 9159 * - the first arg isn't the flattened component name of an existing provider: 9160 * dump all providers whose component contains the first arg as a substring 9161 */ 9162 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9163 int opti, boolean dumpAll) { 9164 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9165 } 9166 9167 static class ItemMatcher { 9168 ArrayList<ComponentName> components; 9169 ArrayList<String> strings; 9170 ArrayList<Integer> objects; 9171 boolean all; 9172 9173 ItemMatcher() { 9174 all = true; 9175 } 9176 9177 void build(String name) { 9178 ComponentName componentName = ComponentName.unflattenFromString(name); 9179 if (componentName != null) { 9180 if (components == null) { 9181 components = new ArrayList<ComponentName>(); 9182 } 9183 components.add(componentName); 9184 all = false; 9185 } else { 9186 int objectId = 0; 9187 // Not a '/' separated full component name; maybe an object ID? 9188 try { 9189 objectId = Integer.parseInt(name, 16); 9190 if (objects == null) { 9191 objects = new ArrayList<Integer>(); 9192 } 9193 objects.add(objectId); 9194 all = false; 9195 } catch (RuntimeException e) { 9196 // Not an integer; just do string match. 9197 if (strings == null) { 9198 strings = new ArrayList<String>(); 9199 } 9200 strings.add(name); 9201 all = false; 9202 } 9203 } 9204 } 9205 9206 int build(String[] args, int opti) { 9207 for (; opti<args.length; opti++) { 9208 String name = args[opti]; 9209 if ("--".equals(name)) { 9210 return opti+1; 9211 } 9212 build(name); 9213 } 9214 return opti; 9215 } 9216 9217 boolean match(Object object, ComponentName comp) { 9218 if (all) { 9219 return true; 9220 } 9221 if (components != null) { 9222 for (int i=0; i<components.size(); i++) { 9223 if (components.get(i).equals(comp)) { 9224 return true; 9225 } 9226 } 9227 } 9228 if (objects != null) { 9229 for (int i=0; i<objects.size(); i++) { 9230 if (System.identityHashCode(object) == objects.get(i)) { 9231 return true; 9232 } 9233 } 9234 } 9235 if (strings != null) { 9236 String flat = comp.flattenToString(); 9237 for (int i=0; i<strings.size(); i++) { 9238 if (flat.contains(strings.get(i))) { 9239 return true; 9240 } 9241 } 9242 } 9243 return false; 9244 } 9245 } 9246 9247 /** 9248 * There are three things that cmd can be: 9249 * - a flattened component name that matches an existing activity 9250 * - the cmd arg isn't the flattened component name of an existing activity: 9251 * dump all activity whose component contains the cmd as a substring 9252 * - A hex number of the ActivityRecord object instance. 9253 */ 9254 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9255 int opti, boolean dumpAll) { 9256 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9257 9258 if ("all".equals(name)) { 9259 synchronized (this) { 9260 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9261 activities.add(r1); 9262 } 9263 } 9264 } else if ("top".equals(name)) { 9265 synchronized (this) { 9266 final int N = mMainStack.mHistory.size(); 9267 if (N > 0) { 9268 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9269 } 9270 } 9271 } else { 9272 ItemMatcher matcher = new ItemMatcher(); 9273 matcher.build(name); 9274 9275 synchronized (this) { 9276 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9277 if (matcher.match(r1, r1.intent.getComponent())) { 9278 activities.add(r1); 9279 } 9280 } 9281 } 9282 } 9283 9284 if (activities.size() <= 0) { 9285 return false; 9286 } 9287 9288 String[] newArgs = new String[args.length - opti]; 9289 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9290 9291 TaskRecord lastTask = null; 9292 boolean needSep = false; 9293 for (int i=activities.size()-1; i>=0; i--) { 9294 ActivityRecord r = (ActivityRecord)activities.get(i); 9295 if (needSep) { 9296 pw.println(); 9297 } 9298 needSep = true; 9299 synchronized (this) { 9300 if (lastTask != r.task) { 9301 lastTask = r.task; 9302 pw.print("TASK "); pw.print(lastTask.affinity); 9303 pw.print(" id="); pw.println(lastTask.taskId); 9304 if (dumpAll) { 9305 lastTask.dump(pw, " "); 9306 } 9307 } 9308 } 9309 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9310 } 9311 return true; 9312 } 9313 9314 /** 9315 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9316 * there is a thread associated with the activity. 9317 */ 9318 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9319 final ActivityRecord r, String[] args, boolean dumpAll) { 9320 String innerPrefix = prefix + " "; 9321 synchronized (this) { 9322 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9323 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9324 pw.print(" pid="); 9325 if (r.app != null) pw.println(r.app.pid); 9326 else pw.println("(not running)"); 9327 if (dumpAll) { 9328 r.dump(pw, innerPrefix); 9329 } 9330 } 9331 if (r.app != null && r.app.thread != null) { 9332 // flush anything that is already in the PrintWriter since the thread is going 9333 // to write to the file descriptor directly 9334 pw.flush(); 9335 try { 9336 TransferPipe tp = new TransferPipe(); 9337 try { 9338 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9339 r.appToken, innerPrefix, args); 9340 tp.go(fd); 9341 } finally { 9342 tp.kill(); 9343 } 9344 } catch (IOException e) { 9345 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9346 } catch (RemoteException e) { 9347 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9348 } 9349 } 9350 } 9351 9352 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9353 int opti, boolean dumpAll, String dumpPackage) { 9354 boolean needSep = false; 9355 9356 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9357 if (dumpAll) { 9358 if (mRegisteredReceivers.size() > 0) { 9359 boolean printed = false; 9360 Iterator it = mRegisteredReceivers.values().iterator(); 9361 while (it.hasNext()) { 9362 ReceiverList r = (ReceiverList)it.next(); 9363 if (dumpPackage != null && (r.app == null || 9364 !dumpPackage.equals(r.app.info.packageName))) { 9365 continue; 9366 } 9367 if (!printed) { 9368 pw.println(" Registered Receivers:"); 9369 needSep = true; 9370 printed = true; 9371 } 9372 pw.print(" * "); pw.println(r); 9373 r.dump(pw, " "); 9374 } 9375 } 9376 9377 if (mReceiverResolver.dump(pw, needSep ? 9378 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9379 " ", dumpPackage, false)) { 9380 needSep = true; 9381 } 9382 } 9383 9384 for (BroadcastQueue q : mBroadcastQueues) { 9385 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9386 } 9387 9388 needSep = true; 9389 9390 if (mStickyBroadcasts != null && dumpPackage == null) { 9391 if (needSep) { 9392 pw.println(); 9393 } 9394 needSep = true; 9395 pw.println(" Sticky broadcasts:"); 9396 StringBuilder sb = new StringBuilder(128); 9397 for (Map.Entry<String, ArrayList<Intent>> ent 9398 : mStickyBroadcasts.entrySet()) { 9399 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9400 if (dumpAll) { 9401 pw.println(":"); 9402 ArrayList<Intent> intents = ent.getValue(); 9403 final int N = intents.size(); 9404 for (int i=0; i<N; i++) { 9405 sb.setLength(0); 9406 sb.append(" Intent: "); 9407 intents.get(i).toShortString(sb, false, true, false, false); 9408 pw.println(sb.toString()); 9409 Bundle bundle = intents.get(i).getExtras(); 9410 if (bundle != null) { 9411 pw.print(" "); 9412 pw.println(bundle.toString()); 9413 } 9414 } 9415 } else { 9416 pw.println(""); 9417 } 9418 } 9419 needSep = true; 9420 } 9421 9422 if (dumpAll) { 9423 pw.println(); 9424 for (BroadcastQueue queue : mBroadcastQueues) { 9425 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9426 + queue.mBroadcastsScheduled); 9427 } 9428 pw.println(" mHandler:"); 9429 mHandler.dump(new PrintWriterPrinter(pw), " "); 9430 needSep = true; 9431 } 9432 9433 return needSep; 9434 } 9435 9436 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9437 int opti, boolean dumpAll, String dumpPackage) { 9438 boolean needSep = true; 9439 9440 ItemMatcher matcher = new ItemMatcher(); 9441 matcher.build(args, opti); 9442 9443 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9444 9445 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9446 9447 if (mLaunchingProviders.size() > 0) { 9448 boolean printed = false; 9449 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9450 ContentProviderRecord r = mLaunchingProviders.get(i); 9451 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9452 continue; 9453 } 9454 if (!printed) { 9455 if (needSep) pw.println(" "); 9456 needSep = true; 9457 pw.println(" Launching content providers:"); 9458 printed = true; 9459 } 9460 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9461 pw.println(r); 9462 } 9463 } 9464 9465 if (mGrantedUriPermissions.size() > 0) { 9466 if (needSep) pw.println(); 9467 needSep = true; 9468 pw.println("Granted Uri Permissions:"); 9469 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9470 int uid = mGrantedUriPermissions.keyAt(i); 9471 HashMap<Uri, UriPermission> perms 9472 = mGrantedUriPermissions.valueAt(i); 9473 pw.print(" * UID "); pw.print(uid); 9474 pw.println(" holds:"); 9475 for (UriPermission perm : perms.values()) { 9476 pw.print(" "); pw.println(perm); 9477 if (dumpAll) { 9478 perm.dump(pw, " "); 9479 } 9480 } 9481 } 9482 needSep = true; 9483 } 9484 9485 return needSep; 9486 } 9487 9488 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9489 int opti, boolean dumpAll, String dumpPackage) { 9490 boolean needSep = false; 9491 9492 if (mIntentSenderRecords.size() > 0) { 9493 boolean printed = false; 9494 Iterator<WeakReference<PendingIntentRecord>> it 9495 = mIntentSenderRecords.values().iterator(); 9496 while (it.hasNext()) { 9497 WeakReference<PendingIntentRecord> ref = it.next(); 9498 PendingIntentRecord rec = ref != null ? ref.get(): null; 9499 if (dumpPackage != null && (rec == null 9500 || !dumpPackage.equals(rec.key.packageName))) { 9501 continue; 9502 } 9503 if (!printed) { 9504 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9505 printed = true; 9506 } 9507 needSep = true; 9508 if (rec != null) { 9509 pw.print(" * "); pw.println(rec); 9510 if (dumpAll) { 9511 rec.dump(pw, " "); 9512 } 9513 } else { 9514 pw.print(" * "); pw.println(ref); 9515 } 9516 } 9517 } 9518 9519 return needSep; 9520 } 9521 9522 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9523 String prefix, String label, boolean complete, boolean brief, boolean client, 9524 String dumpPackage) { 9525 TaskRecord lastTask = null; 9526 boolean needNL = false; 9527 final String innerPrefix = prefix + " "; 9528 final String[] args = new String[0]; 9529 for (int i=list.size()-1; i>=0; i--) { 9530 final ActivityRecord r = (ActivityRecord)list.get(i); 9531 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9532 continue; 9533 } 9534 final boolean full = !brief && (complete || !r.isInHistory()); 9535 if (needNL) { 9536 pw.println(" "); 9537 needNL = false; 9538 } 9539 if (lastTask != r.task) { 9540 lastTask = r.task; 9541 pw.print(prefix); 9542 pw.print(full ? "* " : " "); 9543 pw.println(lastTask); 9544 if (full) { 9545 lastTask.dump(pw, prefix + " "); 9546 } else if (complete) { 9547 // Complete + brief == give a summary. Isn't that obvious?!? 9548 if (lastTask.intent != null) { 9549 pw.print(prefix); pw.print(" "); 9550 pw.println(lastTask.intent.toInsecureStringWithClip()); 9551 } 9552 } 9553 } 9554 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9555 pw.print(" #"); pw.print(i); pw.print(": "); 9556 pw.println(r); 9557 if (full) { 9558 r.dump(pw, innerPrefix); 9559 } else if (complete) { 9560 // Complete + brief == give a summary. Isn't that obvious?!? 9561 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9562 if (r.app != null) { 9563 pw.print(innerPrefix); pw.println(r.app); 9564 } 9565 } 9566 if (client && r.app != null && r.app.thread != null) { 9567 // flush anything that is already in the PrintWriter since the thread is going 9568 // to write to the file descriptor directly 9569 pw.flush(); 9570 try { 9571 TransferPipe tp = new TransferPipe(); 9572 try { 9573 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9574 r.appToken, innerPrefix, args); 9575 // Short timeout, since blocking here can 9576 // deadlock with the application. 9577 tp.go(fd, 2000); 9578 } finally { 9579 tp.kill(); 9580 } 9581 } catch (IOException e) { 9582 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9583 } catch (RemoteException e) { 9584 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9585 } 9586 needNL = true; 9587 } 9588 } 9589 } 9590 9591 private static String buildOomTag(String prefix, String space, int val, int base) { 9592 if (val == base) { 9593 if (space == null) return prefix; 9594 return prefix + " "; 9595 } 9596 return prefix + "+" + Integer.toString(val-base); 9597 } 9598 9599 private static final int dumpProcessList(PrintWriter pw, 9600 ActivityManagerService service, List list, 9601 String prefix, String normalLabel, String persistentLabel, 9602 String dumpPackage) { 9603 int numPers = 0; 9604 final int N = list.size()-1; 9605 for (int i=N; i>=0; i--) { 9606 ProcessRecord r = (ProcessRecord)list.get(i); 9607 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9608 continue; 9609 } 9610 pw.println(String.format("%s%s #%2d: %s", 9611 prefix, (r.persistent ? persistentLabel : normalLabel), 9612 i, r.toString())); 9613 if (r.persistent) { 9614 numPers++; 9615 } 9616 } 9617 return numPers; 9618 } 9619 9620 private static final boolean dumpProcessOomList(PrintWriter pw, 9621 ActivityManagerService service, List<ProcessRecord> origList, 9622 String prefix, String normalLabel, String persistentLabel, 9623 boolean inclDetails, String dumpPackage) { 9624 9625 ArrayList<Pair<ProcessRecord, Integer>> list 9626 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9627 for (int i=0; i<origList.size(); i++) { 9628 ProcessRecord r = origList.get(i); 9629 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9630 continue; 9631 } 9632 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9633 } 9634 9635 if (list.size() <= 0) { 9636 return false; 9637 } 9638 9639 Comparator<Pair<ProcessRecord, Integer>> comparator 9640 = new Comparator<Pair<ProcessRecord, Integer>>() { 9641 @Override 9642 public int compare(Pair<ProcessRecord, Integer> object1, 9643 Pair<ProcessRecord, Integer> object2) { 9644 if (object1.first.setAdj != object2.first.setAdj) { 9645 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9646 } 9647 if (object1.second.intValue() != object2.second.intValue()) { 9648 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9649 } 9650 return 0; 9651 } 9652 }; 9653 9654 Collections.sort(list, comparator); 9655 9656 final long curRealtime = SystemClock.elapsedRealtime(); 9657 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9658 final long curUptime = SystemClock.uptimeMillis(); 9659 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9660 9661 for (int i=list.size()-1; i>=0; i--) { 9662 ProcessRecord r = list.get(i).first; 9663 String oomAdj; 9664 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9665 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9666 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9667 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9668 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9669 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9670 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9671 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9672 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9673 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9674 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9675 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9676 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9677 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9678 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9679 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9680 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9681 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9682 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9683 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9684 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9685 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9686 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9687 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9688 } else { 9689 oomAdj = Integer.toString(r.setAdj); 9690 } 9691 String schedGroup; 9692 switch (r.setSchedGroup) { 9693 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9694 schedGroup = "B"; 9695 break; 9696 case Process.THREAD_GROUP_DEFAULT: 9697 schedGroup = "F"; 9698 break; 9699 default: 9700 schedGroup = Integer.toString(r.setSchedGroup); 9701 break; 9702 } 9703 String foreground; 9704 if (r.foregroundActivities) { 9705 foreground = "A"; 9706 } else if (r.foregroundServices) { 9707 foreground = "S"; 9708 } else { 9709 foreground = " "; 9710 } 9711 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9712 prefix, (r.persistent ? persistentLabel : normalLabel), 9713 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9714 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9715 if (r.adjSource != null || r.adjTarget != null) { 9716 pw.print(prefix); 9717 pw.print(" "); 9718 if (r.adjTarget instanceof ComponentName) { 9719 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9720 } else if (r.adjTarget != null) { 9721 pw.print(r.adjTarget.toString()); 9722 } else { 9723 pw.print("{null}"); 9724 } 9725 pw.print("<="); 9726 if (r.adjSource instanceof ProcessRecord) { 9727 pw.print("Proc{"); 9728 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9729 pw.println("}"); 9730 } else if (r.adjSource != null) { 9731 pw.println(r.adjSource.toString()); 9732 } else { 9733 pw.println("{null}"); 9734 } 9735 } 9736 if (inclDetails) { 9737 pw.print(prefix); 9738 pw.print(" "); 9739 pw.print("oom: max="); pw.print(r.maxAdj); 9740 pw.print(" hidden="); pw.print(r.hiddenAdj); 9741 pw.print(" curRaw="); pw.print(r.curRawAdj); 9742 pw.print(" setRaw="); pw.print(r.setRawAdj); 9743 pw.print(" cur="); pw.print(r.curAdj); 9744 pw.print(" set="); pw.println(r.setAdj); 9745 pw.print(prefix); 9746 pw.print(" "); 9747 pw.print("keeping="); pw.print(r.keeping); 9748 pw.print(" hidden="); pw.print(r.hidden); 9749 pw.print(" empty="); pw.print(r.empty); 9750 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9751 9752 if (!r.keeping) { 9753 if (r.lastWakeTime != 0) { 9754 long wtime; 9755 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9756 synchronized (stats) { 9757 wtime = stats.getProcessWakeTime(r.info.uid, 9758 r.pid, curRealtime); 9759 } 9760 long timeUsed = wtime - r.lastWakeTime; 9761 pw.print(prefix); 9762 pw.print(" "); 9763 pw.print("keep awake over "); 9764 TimeUtils.formatDuration(realtimeSince, pw); 9765 pw.print(" used "); 9766 TimeUtils.formatDuration(timeUsed, pw); 9767 pw.print(" ("); 9768 pw.print((timeUsed*100)/realtimeSince); 9769 pw.println("%)"); 9770 } 9771 if (r.lastCpuTime != 0) { 9772 long timeUsed = r.curCpuTime - r.lastCpuTime; 9773 pw.print(prefix); 9774 pw.print(" "); 9775 pw.print("run cpu over "); 9776 TimeUtils.formatDuration(uptimeSince, pw); 9777 pw.print(" used "); 9778 TimeUtils.formatDuration(timeUsed, pw); 9779 pw.print(" ("); 9780 pw.print((timeUsed*100)/uptimeSince); 9781 pw.println("%)"); 9782 } 9783 } 9784 } 9785 } 9786 return true; 9787 } 9788 9789 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9790 ArrayList<ProcessRecord> procs; 9791 synchronized (this) { 9792 if (args != null && args.length > start 9793 && args[start].charAt(0) != '-') { 9794 procs = new ArrayList<ProcessRecord>(); 9795 int pid = -1; 9796 try { 9797 pid = Integer.parseInt(args[start]); 9798 } catch (NumberFormatException e) { 9799 9800 } 9801 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9802 ProcessRecord proc = mLruProcesses.get(i); 9803 if (proc.pid == pid) { 9804 procs.add(proc); 9805 } else if (proc.processName.equals(args[start])) { 9806 procs.add(proc); 9807 } 9808 } 9809 if (procs.size() <= 0) { 9810 pw.println("No process found for: " + args[start]); 9811 return null; 9812 } 9813 } else { 9814 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9815 } 9816 } 9817 return procs; 9818 } 9819 9820 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9821 PrintWriter pw, String[] args) { 9822 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9823 if (procs == null) { 9824 return; 9825 } 9826 9827 long uptime = SystemClock.uptimeMillis(); 9828 long realtime = SystemClock.elapsedRealtime(); 9829 pw.println("Applications Graphics Acceleration Info:"); 9830 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9831 9832 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9833 ProcessRecord r = procs.get(i); 9834 if (r.thread != null) { 9835 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9836 pw.flush(); 9837 try { 9838 TransferPipe tp = new TransferPipe(); 9839 try { 9840 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9841 tp.go(fd); 9842 } finally { 9843 tp.kill(); 9844 } 9845 } catch (IOException e) { 9846 pw.println("Failure while dumping the app: " + r); 9847 pw.flush(); 9848 } catch (RemoteException e) { 9849 pw.println("Got a RemoteException while dumping the app " + r); 9850 pw.flush(); 9851 } 9852 } 9853 } 9854 } 9855 9856 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9857 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9858 if (procs == null) { 9859 return; 9860 } 9861 9862 pw.println("Applications Database Info:"); 9863 9864 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9865 ProcessRecord r = procs.get(i); 9866 if (r.thread != null) { 9867 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9868 pw.flush(); 9869 try { 9870 TransferPipe tp = new TransferPipe(); 9871 try { 9872 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9873 tp.go(fd); 9874 } finally { 9875 tp.kill(); 9876 } 9877 } catch (IOException e) { 9878 pw.println("Failure while dumping the app: " + r); 9879 pw.flush(); 9880 } catch (RemoteException e) { 9881 pw.println("Got a RemoteException while dumping the app " + r); 9882 pw.flush(); 9883 } 9884 } 9885 } 9886 } 9887 9888 final static class MemItem { 9889 final String label; 9890 final String shortLabel; 9891 final long pss; 9892 final int id; 9893 ArrayList<MemItem> subitems; 9894 9895 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9896 label = _label; 9897 shortLabel = _shortLabel; 9898 pss = _pss; 9899 id = _id; 9900 } 9901 } 9902 9903 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9904 boolean sort) { 9905 if (sort) { 9906 Collections.sort(items, new Comparator<MemItem>() { 9907 @Override 9908 public int compare(MemItem lhs, MemItem rhs) { 9909 if (lhs.pss < rhs.pss) { 9910 return 1; 9911 } else if (lhs.pss > rhs.pss) { 9912 return -1; 9913 } 9914 return 0; 9915 } 9916 }); 9917 } 9918 9919 for (int i=0; i<items.size(); i++) { 9920 MemItem mi = items.get(i); 9921 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9922 if (mi.subitems != null) { 9923 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9924 } 9925 } 9926 } 9927 9928 // These are in KB. 9929 static final long[] DUMP_MEM_BUCKETS = new long[] { 9930 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9931 120*1024, 160*1024, 200*1024, 9932 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9933 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9934 }; 9935 9936 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9937 boolean stackLike) { 9938 int start = label.lastIndexOf('.'); 9939 if (start >= 0) start++; 9940 else start = 0; 9941 int end = label.length(); 9942 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9943 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9944 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9945 out.append(bucket); 9946 out.append(stackLike ? "MB." : "MB "); 9947 out.append(label, start, end); 9948 return; 9949 } 9950 } 9951 out.append(memKB/1024); 9952 out.append(stackLike ? "MB." : "MB "); 9953 out.append(label, start, end); 9954 } 9955 9956 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9957 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9958 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9959 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9960 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9961 }; 9962 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9963 "System", "Persistent", "Foreground", 9964 "Visible", "Perceptible", "Heavy Weight", 9965 "Backup", "A Services", "Home", "Previous", 9966 "B Services", "Background" 9967 }; 9968 9969 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9970 PrintWriter pw, String prefix, String[] args, boolean brief, 9971 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9972 boolean dumpAll = false; 9973 boolean oomOnly = false; 9974 9975 int opti = 0; 9976 while (opti < args.length) { 9977 String opt = args[opti]; 9978 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9979 break; 9980 } 9981 opti++; 9982 if ("-a".equals(opt)) { 9983 dumpAll = true; 9984 } else if ("--oom".equals(opt)) { 9985 oomOnly = true; 9986 } else if ("-h".equals(opt)) { 9987 pw.println("meminfo dump options: [-a] [--oom] [process]"); 9988 pw.println(" -a: include all available information for each process."); 9989 pw.println(" --oom: only show processes organized by oom adj."); 9990 pw.println("If [process] is specified it can be the name or "); 9991 pw.println("pid of a specific process to dump."); 9992 return; 9993 } else { 9994 pw.println("Unknown argument: " + opt + "; use -h for help"); 9995 } 9996 } 9997 9998 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 9999 if (procs == null) { 10000 return; 10001 } 10002 10003 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10004 long uptime = SystemClock.uptimeMillis(); 10005 long realtime = SystemClock.elapsedRealtime(); 10006 10007 if (procs.size() == 1 || isCheckinRequest) { 10008 dumpAll = true; 10009 } 10010 10011 if (isCheckinRequest) { 10012 // short checkin version 10013 pw.println(uptime + "," + realtime); 10014 pw.flush(); 10015 } else { 10016 pw.println("Applications Memory Usage (kB):"); 10017 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10018 } 10019 10020 String[] innerArgs = new String[args.length-opti]; 10021 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10022 10023 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10024 long nativePss=0, dalvikPss=0, otherPss=0; 10025 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10026 10027 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10028 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10029 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10030 10031 long totalPss = 0; 10032 10033 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10034 ProcessRecord r = procs.get(i); 10035 if (r.thread != null) { 10036 if (!isCheckinRequest && dumpAll) { 10037 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10038 pw.flush(); 10039 } 10040 Debug.MemoryInfo mi = null; 10041 if (dumpAll) { 10042 try { 10043 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10044 } catch (RemoteException e) { 10045 if (!isCheckinRequest) { 10046 pw.println("Got RemoteException!"); 10047 pw.flush(); 10048 } 10049 } 10050 } else { 10051 mi = new Debug.MemoryInfo(); 10052 Debug.getMemoryInfo(r.pid, mi); 10053 } 10054 10055 if (!isCheckinRequest && mi != null) { 10056 long myTotalPss = mi.getTotalPss(); 10057 totalPss += myTotalPss; 10058 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10059 r.processName, myTotalPss, 0); 10060 procMems.add(pssItem); 10061 10062 nativePss += mi.nativePss; 10063 dalvikPss += mi.dalvikPss; 10064 otherPss += mi.otherPss; 10065 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10066 long mem = mi.getOtherPss(j); 10067 miscPss[j] += mem; 10068 otherPss -= mem; 10069 } 10070 10071 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10072 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10073 || oomIndex == (oomPss.length-1)) { 10074 oomPss[oomIndex] += myTotalPss; 10075 if (oomProcs[oomIndex] == null) { 10076 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10077 } 10078 oomProcs[oomIndex].add(pssItem); 10079 break; 10080 } 10081 } 10082 } 10083 } 10084 } 10085 10086 if (!isCheckinRequest && procs.size() > 1) { 10087 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10088 10089 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10090 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10091 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10092 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10093 String label = Debug.MemoryInfo.getOtherLabel(j); 10094 catMems.add(new MemItem(label, label, miscPss[j], j)); 10095 } 10096 10097 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10098 for (int j=0; j<oomPss.length; j++) { 10099 if (oomPss[j] != 0) { 10100 String label = DUMP_MEM_OOM_LABEL[j]; 10101 MemItem item = new MemItem(label, label, oomPss[j], 10102 DUMP_MEM_OOM_ADJ[j]); 10103 item.subitems = oomProcs[j]; 10104 oomMems.add(item); 10105 } 10106 } 10107 10108 if (outTag != null || outStack != null) { 10109 if (outTag != null) { 10110 appendMemBucket(outTag, totalPss, "total", false); 10111 } 10112 if (outStack != null) { 10113 appendMemBucket(outStack, totalPss, "total", true); 10114 } 10115 boolean firstLine = true; 10116 for (int i=0; i<oomMems.size(); i++) { 10117 MemItem miCat = oomMems.get(i); 10118 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10119 continue; 10120 } 10121 if (miCat.id < ProcessList.SERVICE_ADJ 10122 || miCat.id == ProcessList.HOME_APP_ADJ 10123 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10124 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10125 outTag.append(" / "); 10126 } 10127 if (outStack != null) { 10128 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10129 if (firstLine) { 10130 outStack.append(":"); 10131 firstLine = false; 10132 } 10133 outStack.append("\n\t at "); 10134 } else { 10135 outStack.append("$"); 10136 } 10137 } 10138 for (int j=0; j<miCat.subitems.size(); j++) { 10139 MemItem mi = miCat.subitems.get(j); 10140 if (j > 0) { 10141 if (outTag != null) { 10142 outTag.append(" "); 10143 } 10144 if (outStack != null) { 10145 outStack.append("$"); 10146 } 10147 } 10148 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10149 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10150 } 10151 if (outStack != null) { 10152 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10153 } 10154 } 10155 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10156 outStack.append("("); 10157 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10158 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10159 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10160 outStack.append(":"); 10161 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10162 } 10163 } 10164 outStack.append(")"); 10165 } 10166 } 10167 } 10168 } 10169 10170 if (!brief && !oomOnly) { 10171 pw.println(); 10172 pw.println("Total PSS by process:"); 10173 dumpMemItems(pw, " ", procMems, true); 10174 pw.println(); 10175 } 10176 pw.println("Total PSS by OOM adjustment:"); 10177 dumpMemItems(pw, " ", oomMems, false); 10178 if (!oomOnly) { 10179 PrintWriter out = categoryPw != null ? categoryPw : pw; 10180 out.println(); 10181 out.println("Total PSS by category:"); 10182 dumpMemItems(out, " ", catMems, true); 10183 } 10184 pw.println(); 10185 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10186 final int[] SINGLE_LONG_FORMAT = new int[] { 10187 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10188 }; 10189 long[] longOut = new long[1]; 10190 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10191 SINGLE_LONG_FORMAT, null, longOut, null); 10192 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10193 longOut[0] = 0; 10194 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10195 SINGLE_LONG_FORMAT, null, longOut, null); 10196 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10197 longOut[0] = 0; 10198 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10199 SINGLE_LONG_FORMAT, null, longOut, null); 10200 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10201 longOut[0] = 0; 10202 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10203 SINGLE_LONG_FORMAT, null, longOut, null); 10204 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10205 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10206 pw.print(shared); pw.println(" kB"); 10207 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10208 pw.print(voltile); pw.println(" kB volatile"); 10209 } 10210 } 10211 10212 /** 10213 * Searches array of arguments for the specified string 10214 * @param args array of argument strings 10215 * @param value value to search for 10216 * @return true if the value is contained in the array 10217 */ 10218 private static boolean scanArgs(String[] args, String value) { 10219 if (args != null) { 10220 for (String arg : args) { 10221 if (value.equals(arg)) { 10222 return true; 10223 } 10224 } 10225 } 10226 return false; 10227 } 10228 10229 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10230 ContentProviderRecord cpr, boolean always) { 10231 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10232 10233 if (!inLaunching || always) { 10234 synchronized (cpr) { 10235 cpr.launchingApp = null; 10236 cpr.notifyAll(); 10237 } 10238 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10239 String names[] = cpr.info.authority.split(";"); 10240 for (int j = 0; j < names.length; j++) { 10241 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10242 } 10243 } 10244 10245 for (int i=0; i<cpr.connections.size(); i++) { 10246 ContentProviderConnection conn = cpr.connections.get(i); 10247 if (conn.waiting) { 10248 // If this connection is waiting for the provider, then we don't 10249 // need to mess with its process unless we are always removing 10250 // or for some reason the provider is not currently launching. 10251 if (inLaunching && !always) { 10252 continue; 10253 } 10254 } 10255 ProcessRecord capp = conn.client; 10256 conn.dead = true; 10257 if (conn.stableCount > 0) { 10258 if (!capp.persistent && capp.thread != null 10259 && capp.pid != 0 10260 && capp.pid != MY_PID) { 10261 Slog.i(TAG, "Kill " + capp.processName 10262 + " (pid " + capp.pid + "): provider " + cpr.info.name 10263 + " in dying process " + (proc != null ? proc.processName : "??")); 10264 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10265 capp.processName, capp.setAdj, "dying provider " 10266 + cpr.name.toShortString()); 10267 Process.killProcessQuiet(capp.pid); 10268 } 10269 } else if (capp.thread != null && conn.provider.provider != null) { 10270 try { 10271 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10272 } catch (RemoteException e) { 10273 } 10274 // In the protocol here, we don't expect the client to correctly 10275 // clean up this connection, we'll just remove it. 10276 cpr.connections.remove(i); 10277 conn.client.conProviders.remove(conn); 10278 } 10279 } 10280 10281 if (inLaunching && always) { 10282 mLaunchingProviders.remove(cpr); 10283 } 10284 return inLaunching; 10285 } 10286 10287 /** 10288 * Main code for cleaning up a process when it has gone away. This is 10289 * called both as a result of the process dying, or directly when stopping 10290 * a process when running in single process mode. 10291 */ 10292 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10293 boolean restarting, boolean allowRestart, int index) { 10294 if (index >= 0) { 10295 mLruProcesses.remove(index); 10296 } 10297 10298 mProcessesToGc.remove(app); 10299 10300 // Dismiss any open dialogs. 10301 if (app.crashDialog != null) { 10302 app.crashDialog.dismiss(); 10303 app.crashDialog = null; 10304 } 10305 if (app.anrDialog != null) { 10306 app.anrDialog.dismiss(); 10307 app.anrDialog = null; 10308 } 10309 if (app.waitDialog != null) { 10310 app.waitDialog.dismiss(); 10311 app.waitDialog = null; 10312 } 10313 10314 app.crashing = false; 10315 app.notResponding = false; 10316 10317 app.resetPackageList(); 10318 app.unlinkDeathRecipient(); 10319 app.thread = null; 10320 app.forcingToForeground = null; 10321 app.foregroundServices = false; 10322 app.foregroundActivities = false; 10323 app.hasShownUi = false; 10324 app.hasAboveClient = false; 10325 10326 mServices.killServicesLocked(app, allowRestart); 10327 10328 boolean restart = false; 10329 10330 // Remove published content providers. 10331 if (!app.pubProviders.isEmpty()) { 10332 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10333 while (it.hasNext()) { 10334 ContentProviderRecord cpr = it.next(); 10335 10336 final boolean always = app.bad || !allowRestart; 10337 if (removeDyingProviderLocked(app, cpr, always) || always) { 10338 // We left the provider in the launching list, need to 10339 // restart it. 10340 restart = true; 10341 } 10342 10343 cpr.provider = null; 10344 cpr.proc = null; 10345 } 10346 app.pubProviders.clear(); 10347 } 10348 10349 // Take care of any launching providers waiting for this process. 10350 if (checkAppInLaunchingProvidersLocked(app, false)) { 10351 restart = true; 10352 } 10353 10354 // Unregister from connected content providers. 10355 if (!app.conProviders.isEmpty()) { 10356 for (int i=0; i<app.conProviders.size(); i++) { 10357 ContentProviderConnection conn = app.conProviders.get(i); 10358 conn.provider.connections.remove(conn); 10359 } 10360 app.conProviders.clear(); 10361 } 10362 10363 // At this point there may be remaining entries in mLaunchingProviders 10364 // where we were the only one waiting, so they are no longer of use. 10365 // Look for these and clean up if found. 10366 // XXX Commented out for now. Trying to figure out a way to reproduce 10367 // the actual situation to identify what is actually going on. 10368 if (false) { 10369 for (int i=0; i<mLaunchingProviders.size(); i++) { 10370 ContentProviderRecord cpr = (ContentProviderRecord) 10371 mLaunchingProviders.get(i); 10372 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10373 synchronized (cpr) { 10374 cpr.launchingApp = null; 10375 cpr.notifyAll(); 10376 } 10377 } 10378 } 10379 } 10380 10381 skipCurrentReceiverLocked(app); 10382 10383 // Unregister any receivers. 10384 if (app.receivers.size() > 0) { 10385 Iterator<ReceiverList> it = app.receivers.iterator(); 10386 while (it.hasNext()) { 10387 removeReceiverLocked(it.next()); 10388 } 10389 app.receivers.clear(); 10390 } 10391 10392 // If the app is undergoing backup, tell the backup manager about it 10393 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10394 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10395 try { 10396 IBackupManager bm = IBackupManager.Stub.asInterface( 10397 ServiceManager.getService(Context.BACKUP_SERVICE)); 10398 bm.agentDisconnected(app.info.packageName); 10399 } catch (RemoteException e) { 10400 // can't happen; backup manager is local 10401 } 10402 } 10403 10404 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10405 ProcessChangeItem item = mPendingProcessChanges.get(i); 10406 if (item.pid == app.pid) { 10407 mPendingProcessChanges.remove(i); 10408 mAvailProcessChanges.add(item); 10409 } 10410 } 10411 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10412 10413 // If the caller is restarting this app, then leave it in its 10414 // current lists and let the caller take care of it. 10415 if (restarting) { 10416 return; 10417 } 10418 10419 if (!app.persistent || app.isolated) { 10420 if (DEBUG_PROCESSES) Slog.v(TAG, 10421 "Removing non-persistent process during cleanup: " + app); 10422 mProcessNames.remove(app.processName, app.uid); 10423 mIsolatedProcesses.remove(app.uid); 10424 if (mHeavyWeightProcess == app) { 10425 mHeavyWeightProcess = null; 10426 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10427 } 10428 } else if (!app.removed) { 10429 // This app is persistent, so we need to keep its record around. 10430 // If it is not already on the pending app list, add it there 10431 // and start a new process for it. 10432 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10433 mPersistentStartingProcesses.add(app); 10434 restart = true; 10435 } 10436 } 10437 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10438 "Clean-up removing on hold: " + app); 10439 mProcessesOnHold.remove(app); 10440 10441 if (app == mHomeProcess) { 10442 mHomeProcess = null; 10443 } 10444 if (app == mPreviousProcess) { 10445 mPreviousProcess = null; 10446 } 10447 10448 if (restart && !app.isolated) { 10449 // We have components that still need to be running in the 10450 // process, so re-launch it. 10451 mProcessNames.put(app.processName, app.uid, app); 10452 startProcessLocked(app, "restart", app.processName); 10453 } else if (app.pid > 0 && app.pid != MY_PID) { 10454 // Goodbye! 10455 synchronized (mPidsSelfLocked) { 10456 mPidsSelfLocked.remove(app.pid); 10457 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10458 } 10459 app.setPid(0); 10460 } 10461 } 10462 10463 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10464 // Look through the content providers we are waiting to have launched, 10465 // and if any run in this process then either schedule a restart of 10466 // the process or kill the client waiting for it if this process has 10467 // gone bad. 10468 int NL = mLaunchingProviders.size(); 10469 boolean restart = false; 10470 for (int i=0; i<NL; i++) { 10471 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10472 if (cpr.launchingApp == app) { 10473 if (!alwaysBad && !app.bad) { 10474 restart = true; 10475 } else { 10476 removeDyingProviderLocked(app, cpr, true); 10477 NL = mLaunchingProviders.size(); 10478 } 10479 } 10480 } 10481 return restart; 10482 } 10483 10484 // ========================================================= 10485 // SERVICES 10486 // ========================================================= 10487 10488 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10489 int flags) { 10490 enforceNotIsolatedCaller("getServices"); 10491 synchronized (this) { 10492 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10493 } 10494 } 10495 10496 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10497 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10498 synchronized (this) { 10499 return mServices.getRunningServiceControlPanelLocked(name); 10500 } 10501 } 10502 10503 public ComponentName startService(IApplicationThread caller, Intent service, 10504 String resolvedType) { 10505 enforceNotIsolatedCaller("startService"); 10506 // Refuse possible leaked file descriptors 10507 if (service != null && service.hasFileDescriptors() == true) { 10508 throw new IllegalArgumentException("File descriptors passed in Intent"); 10509 } 10510 10511 if (DEBUG_SERVICE) 10512 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10513 synchronized(this) { 10514 final int callingPid = Binder.getCallingPid(); 10515 final int callingUid = Binder.getCallingUid(); 10516 final long origId = Binder.clearCallingIdentity(); 10517 ComponentName res = mServices.startServiceLocked(caller, service, 10518 resolvedType, callingPid, callingUid); 10519 Binder.restoreCallingIdentity(origId); 10520 return res; 10521 } 10522 } 10523 10524 ComponentName startServiceInPackage(int uid, 10525 Intent service, String resolvedType) { 10526 synchronized(this) { 10527 if (DEBUG_SERVICE) 10528 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10529 final long origId = Binder.clearCallingIdentity(); 10530 ComponentName res = mServices.startServiceLocked(null, service, 10531 resolvedType, -1, uid); 10532 Binder.restoreCallingIdentity(origId); 10533 return res; 10534 } 10535 } 10536 10537 public int stopService(IApplicationThread caller, Intent service, 10538 String resolvedType) { 10539 enforceNotIsolatedCaller("stopService"); 10540 // Refuse possible leaked file descriptors 10541 if (service != null && service.hasFileDescriptors() == true) { 10542 throw new IllegalArgumentException("File descriptors passed in Intent"); 10543 } 10544 10545 synchronized(this) { 10546 return mServices.stopServiceLocked(caller, service, resolvedType); 10547 } 10548 } 10549 10550 public IBinder peekService(Intent service, String resolvedType) { 10551 enforceNotIsolatedCaller("peekService"); 10552 // Refuse possible leaked file descriptors 10553 if (service != null && service.hasFileDescriptors() == true) { 10554 throw new IllegalArgumentException("File descriptors passed in Intent"); 10555 } 10556 synchronized(this) { 10557 return mServices.peekServiceLocked(service, resolvedType); 10558 } 10559 } 10560 10561 public boolean stopServiceToken(ComponentName className, IBinder token, 10562 int startId) { 10563 synchronized(this) { 10564 return mServices.stopServiceTokenLocked(className, token, startId); 10565 } 10566 } 10567 10568 public void setServiceForeground(ComponentName className, IBinder token, 10569 int id, Notification notification, boolean removeNotification) { 10570 synchronized(this) { 10571 mServices.setServiceForegroundLocked(className, token, id, notification, 10572 removeNotification); 10573 } 10574 } 10575 10576 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10577 String className, int flags) { 10578 boolean result = false; 10579 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10580 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10581 if (ActivityManager.checkUidPermission( 10582 android.Manifest.permission.INTERACT_ACROSS_USERS, 10583 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10584 ComponentName comp = new ComponentName(aInfo.packageName, className); 10585 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10586 + " requests FLAG_SINGLE_USER, but app does not hold " 10587 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10588 Slog.w(TAG, msg); 10589 throw new SecurityException(msg); 10590 } 10591 result = true; 10592 } 10593 } else if (componentProcessName == aInfo.packageName) { 10594 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10595 } else if ("system".equals(componentProcessName)) { 10596 result = true; 10597 } 10598 if (DEBUG_MU) { 10599 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10600 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10601 } 10602 return result; 10603 } 10604 10605 public int bindService(IApplicationThread caller, IBinder token, 10606 Intent service, String resolvedType, 10607 IServiceConnection connection, int flags, int userId) { 10608 enforceNotIsolatedCaller("bindService"); 10609 // Refuse possible leaked file descriptors 10610 if (service != null && service.hasFileDescriptors() == true) { 10611 throw new IllegalArgumentException("File descriptors passed in Intent"); 10612 } 10613 10614 checkValidCaller(Binder.getCallingUid(), userId); 10615 10616 synchronized(this) { 10617 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10618 connection, flags, userId); 10619 } 10620 } 10621 10622 public boolean unbindService(IServiceConnection connection) { 10623 synchronized (this) { 10624 return mServices.unbindServiceLocked(connection); 10625 } 10626 } 10627 10628 public void publishService(IBinder token, Intent intent, IBinder service) { 10629 // Refuse possible leaked file descriptors 10630 if (intent != null && intent.hasFileDescriptors() == true) { 10631 throw new IllegalArgumentException("File descriptors passed in Intent"); 10632 } 10633 10634 synchronized(this) { 10635 if (!(token instanceof ServiceRecord)) { 10636 throw new IllegalArgumentException("Invalid service token"); 10637 } 10638 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10639 } 10640 } 10641 10642 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10643 // Refuse possible leaked file descriptors 10644 if (intent != null && intent.hasFileDescriptors() == true) { 10645 throw new IllegalArgumentException("File descriptors passed in Intent"); 10646 } 10647 10648 synchronized(this) { 10649 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10650 } 10651 } 10652 10653 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10654 synchronized(this) { 10655 if (!(token instanceof ServiceRecord)) { 10656 throw new IllegalArgumentException("Invalid service token"); 10657 } 10658 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10659 } 10660 } 10661 10662 // ========================================================= 10663 // BACKUP AND RESTORE 10664 // ========================================================= 10665 10666 // Cause the target app to be launched if necessary and its backup agent 10667 // instantiated. The backup agent will invoke backupAgentCreated() on the 10668 // activity manager to announce its creation. 10669 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10670 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10671 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10672 10673 synchronized(this) { 10674 // !!! TODO: currently no check here that we're already bound 10675 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10676 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10677 synchronized (stats) { 10678 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10679 } 10680 10681 // Backup agent is now in use, its package can't be stopped. 10682 try { 10683 AppGlobals.getPackageManager().setPackageStoppedState( 10684 app.packageName, false, UserId.getUserId(app.uid)); 10685 } catch (RemoteException e) { 10686 } catch (IllegalArgumentException e) { 10687 Slog.w(TAG, "Failed trying to unstop package " 10688 + app.packageName + ": " + e); 10689 } 10690 10691 BackupRecord r = new BackupRecord(ss, app, backupMode); 10692 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10693 ? new ComponentName(app.packageName, app.backupAgentName) 10694 : new ComponentName("android", "FullBackupAgent"); 10695 // startProcessLocked() returns existing proc's record if it's already running 10696 ProcessRecord proc = startProcessLocked(app.processName, app, 10697 false, 0, "backup", hostingName, false, false); 10698 if (proc == null) { 10699 Slog.e(TAG, "Unable to start backup agent process " + r); 10700 return false; 10701 } 10702 10703 r.app = proc; 10704 mBackupTarget = r; 10705 mBackupAppName = app.packageName; 10706 10707 // Try not to kill the process during backup 10708 updateOomAdjLocked(proc); 10709 10710 // If the process is already attached, schedule the creation of the backup agent now. 10711 // If it is not yet live, this will be done when it attaches to the framework. 10712 if (proc.thread != null) { 10713 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10714 try { 10715 proc.thread.scheduleCreateBackupAgent(app, 10716 compatibilityInfoForPackageLocked(app), backupMode); 10717 } catch (RemoteException e) { 10718 // Will time out on the backup manager side 10719 } 10720 } else { 10721 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10722 } 10723 // Invariants: at this point, the target app process exists and the application 10724 // is either already running or in the process of coming up. mBackupTarget and 10725 // mBackupAppName describe the app, so that when it binds back to the AM we 10726 // know that it's scheduled for a backup-agent operation. 10727 } 10728 10729 return true; 10730 } 10731 10732 // A backup agent has just come up 10733 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10734 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10735 + " = " + agent); 10736 10737 synchronized(this) { 10738 if (!agentPackageName.equals(mBackupAppName)) { 10739 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10740 return; 10741 } 10742 } 10743 10744 long oldIdent = Binder.clearCallingIdentity(); 10745 try { 10746 IBackupManager bm = IBackupManager.Stub.asInterface( 10747 ServiceManager.getService(Context.BACKUP_SERVICE)); 10748 bm.agentConnected(agentPackageName, agent); 10749 } catch (RemoteException e) { 10750 // can't happen; the backup manager service is local 10751 } catch (Exception e) { 10752 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10753 e.printStackTrace(); 10754 } finally { 10755 Binder.restoreCallingIdentity(oldIdent); 10756 } 10757 } 10758 10759 // done with this agent 10760 public void unbindBackupAgent(ApplicationInfo appInfo) { 10761 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10762 if (appInfo == null) { 10763 Slog.w(TAG, "unbind backup agent for null app"); 10764 return; 10765 } 10766 10767 synchronized(this) { 10768 if (mBackupAppName == null) { 10769 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10770 return; 10771 } 10772 10773 if (!mBackupAppName.equals(appInfo.packageName)) { 10774 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10775 return; 10776 } 10777 10778 ProcessRecord proc = mBackupTarget.app; 10779 mBackupTarget = null; 10780 mBackupAppName = null; 10781 10782 // Not backing this app up any more; reset its OOM adjustment 10783 updateOomAdjLocked(proc); 10784 10785 // If the app crashed during backup, 'thread' will be null here 10786 if (proc.thread != null) { 10787 try { 10788 proc.thread.scheduleDestroyBackupAgent(appInfo, 10789 compatibilityInfoForPackageLocked(appInfo)); 10790 } catch (Exception e) { 10791 Slog.e(TAG, "Exception when unbinding backup agent:"); 10792 e.printStackTrace(); 10793 } 10794 } 10795 } 10796 } 10797 // ========================================================= 10798 // BROADCASTS 10799 // ========================================================= 10800 10801 private final List getStickiesLocked(String action, IntentFilter filter, 10802 List cur) { 10803 final ContentResolver resolver = mContext.getContentResolver(); 10804 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10805 if (list == null) { 10806 return cur; 10807 } 10808 int N = list.size(); 10809 for (int i=0; i<N; i++) { 10810 Intent intent = list.get(i); 10811 if (filter.match(resolver, intent, true, TAG) >= 0) { 10812 if (cur == null) { 10813 cur = new ArrayList<Intent>(); 10814 } 10815 cur.add(intent); 10816 } 10817 } 10818 return cur; 10819 } 10820 10821 boolean isPendingBroadcastProcessLocked(int pid) { 10822 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10823 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10824 } 10825 10826 void skipPendingBroadcastLocked(int pid) { 10827 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10828 for (BroadcastQueue queue : mBroadcastQueues) { 10829 queue.skipPendingBroadcastLocked(pid); 10830 } 10831 } 10832 10833 // The app just attached; send any pending broadcasts that it should receive 10834 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10835 boolean didSomething = false; 10836 for (BroadcastQueue queue : mBroadcastQueues) { 10837 didSomething |= queue.sendPendingBroadcastsLocked(app); 10838 } 10839 return didSomething; 10840 } 10841 10842 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10843 IIntentReceiver receiver, IntentFilter filter, String permission) { 10844 enforceNotIsolatedCaller("registerReceiver"); 10845 int callingUid; 10846 synchronized(this) { 10847 ProcessRecord callerApp = null; 10848 if (caller != null) { 10849 callerApp = getRecordForAppLocked(caller); 10850 if (callerApp == null) { 10851 throw new SecurityException( 10852 "Unable to find app for caller " + caller 10853 + " (pid=" + Binder.getCallingPid() 10854 + ") when registering receiver " + receiver); 10855 } 10856 if (callerApp.info.uid != Process.SYSTEM_UID && 10857 !callerApp.pkgList.contains(callerPackage)) { 10858 throw new SecurityException("Given caller package " + callerPackage 10859 + " is not running in process " + callerApp); 10860 } 10861 callingUid = callerApp.info.uid; 10862 } else { 10863 callerPackage = null; 10864 callingUid = Binder.getCallingUid(); 10865 } 10866 10867 List allSticky = null; 10868 10869 // Look for any matching sticky broadcasts... 10870 Iterator actions = filter.actionsIterator(); 10871 if (actions != null) { 10872 while (actions.hasNext()) { 10873 String action = (String)actions.next(); 10874 allSticky = getStickiesLocked(action, filter, allSticky); 10875 } 10876 } else { 10877 allSticky = getStickiesLocked(null, filter, allSticky); 10878 } 10879 10880 // The first sticky in the list is returned directly back to 10881 // the client. 10882 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10883 10884 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10885 + ": " + sticky); 10886 10887 if (receiver == null) { 10888 return sticky; 10889 } 10890 10891 ReceiverList rl 10892 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10893 if (rl == null) { 10894 rl = new ReceiverList(this, callerApp, 10895 Binder.getCallingPid(), 10896 Binder.getCallingUid(), receiver); 10897 if (rl.app != null) { 10898 rl.app.receivers.add(rl); 10899 } else { 10900 try { 10901 receiver.asBinder().linkToDeath(rl, 0); 10902 } catch (RemoteException e) { 10903 return sticky; 10904 } 10905 rl.linkedToDeath = true; 10906 } 10907 mRegisteredReceivers.put(receiver.asBinder(), rl); 10908 } 10909 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10910 permission, callingUid); 10911 rl.add(bf); 10912 if (!bf.debugCheck()) { 10913 Slog.w(TAG, "==> For Dynamic broadast"); 10914 } 10915 mReceiverResolver.addFilter(bf); 10916 10917 // Enqueue broadcasts for all existing stickies that match 10918 // this filter. 10919 if (allSticky != null) { 10920 ArrayList receivers = new ArrayList(); 10921 receivers.add(bf); 10922 10923 int N = allSticky.size(); 10924 for (int i=0; i<N; i++) { 10925 Intent intent = (Intent)allSticky.get(i); 10926 BroadcastQueue queue = broadcastQueueForIntent(intent); 10927 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10928 null, -1, -1, null, receivers, null, 0, null, null, 10929 false, true, true, false); 10930 queue.enqueueParallelBroadcastLocked(r); 10931 queue.scheduleBroadcastsLocked(); 10932 } 10933 } 10934 10935 return sticky; 10936 } 10937 } 10938 10939 public void unregisterReceiver(IIntentReceiver receiver) { 10940 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10941 10942 final long origId = Binder.clearCallingIdentity(); 10943 try { 10944 boolean doTrim = false; 10945 10946 synchronized(this) { 10947 ReceiverList rl 10948 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10949 if (rl != null) { 10950 if (rl.curBroadcast != null) { 10951 BroadcastRecord r = rl.curBroadcast; 10952 final boolean doNext = finishReceiverLocked( 10953 receiver.asBinder(), r.resultCode, r.resultData, 10954 r.resultExtras, r.resultAbort, true); 10955 if (doNext) { 10956 doTrim = true; 10957 r.queue.processNextBroadcast(false); 10958 } 10959 } 10960 10961 if (rl.app != null) { 10962 rl.app.receivers.remove(rl); 10963 } 10964 removeReceiverLocked(rl); 10965 if (rl.linkedToDeath) { 10966 rl.linkedToDeath = false; 10967 rl.receiver.asBinder().unlinkToDeath(rl, 0); 10968 } 10969 } 10970 } 10971 10972 // If we actually concluded any broadcasts, we might now be able 10973 // to trim the recipients' apps from our working set 10974 if (doTrim) { 10975 trimApplications(); 10976 return; 10977 } 10978 10979 } finally { 10980 Binder.restoreCallingIdentity(origId); 10981 } 10982 } 10983 10984 void removeReceiverLocked(ReceiverList rl) { 10985 mRegisteredReceivers.remove(rl.receiver.asBinder()); 10986 int N = rl.size(); 10987 for (int i=0; i<N; i++) { 10988 mReceiverResolver.removeFilter(rl.get(i)); 10989 } 10990 } 10991 10992 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 10993 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10994 ProcessRecord r = mLruProcesses.get(i); 10995 if (r.thread != null) { 10996 try { 10997 r.thread.dispatchPackageBroadcast(cmd, packages); 10998 } catch (RemoteException ex) { 10999 } 11000 } 11001 } 11002 } 11003 11004 private final int broadcastIntentLocked(ProcessRecord callerApp, 11005 String callerPackage, Intent intent, String resolvedType, 11006 IIntentReceiver resultTo, int resultCode, String resultData, 11007 Bundle map, String requiredPermission, 11008 boolean ordered, boolean sticky, int callingPid, int callingUid, 11009 int userId) { 11010 intent = new Intent(intent); 11011 11012 // By default broadcasts do not go to stopped apps. 11013 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11014 11015 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11016 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11017 + " ordered=" + ordered + " userid=" + userId); 11018 if ((resultTo != null) && !ordered) { 11019 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11020 } 11021 11022 boolean onlySendToCaller = false; 11023 11024 // If the caller is trying to send this broadcast to a different 11025 // user, verify that is allowed. 11026 if (UserId.getUserId(callingUid) != userId) { 11027 if (checkComponentPermission( 11028 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11029 callingPid, callingUid, -1, true) 11030 != PackageManager.PERMISSION_GRANTED) { 11031 if (checkComponentPermission( 11032 android.Manifest.permission.INTERACT_ACROSS_USERS, 11033 callingPid, callingUid, -1, true) 11034 == PackageManager.PERMISSION_GRANTED) { 11035 onlySendToCaller = true; 11036 } else { 11037 String msg = "Permission Denial: " + intent.getAction() 11038 + " broadcast from " + callerPackage 11039 + " asks to send as user " + userId 11040 + " but is calling from user " + UserId.getUserId(callingUid) 11041 + "; this requires " 11042 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11043 Slog.w(TAG, msg); 11044 throw new SecurityException(msg); 11045 } 11046 } 11047 } 11048 11049 // Handle special intents: if this broadcast is from the package 11050 // manager about a package being removed, we need to remove all of 11051 // its activities from the history stack. 11052 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11053 intent.getAction()); 11054 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11055 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11056 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11057 || uidRemoved) { 11058 if (checkComponentPermission( 11059 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11060 callingPid, callingUid, -1, true) 11061 == PackageManager.PERMISSION_GRANTED) { 11062 if (uidRemoved) { 11063 final Bundle intentExtras = intent.getExtras(); 11064 final int uid = intentExtras != null 11065 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11066 if (uid >= 0) { 11067 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11068 synchronized (bs) { 11069 bs.removeUidStatsLocked(uid); 11070 } 11071 } 11072 } else { 11073 // If resources are unvailble just force stop all 11074 // those packages and flush the attribute cache as well. 11075 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11076 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11077 if (list != null && (list.length > 0)) { 11078 for (String pkg : list) { 11079 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11080 } 11081 sendPackageBroadcastLocked( 11082 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11083 } 11084 } else { 11085 Uri data = intent.getData(); 11086 String ssp; 11087 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11088 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11089 forceStopPackageLocked(ssp, 11090 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11091 false, userId); 11092 } 11093 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11094 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11095 new String[] {ssp}); 11096 } 11097 } 11098 } 11099 } 11100 } else { 11101 String msg = "Permission Denial: " + intent.getAction() 11102 + " broadcast from " + callerPackage + " (pid=" + callingPid 11103 + ", uid=" + callingUid + ")" 11104 + " requires " 11105 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11106 Slog.w(TAG, msg); 11107 throw new SecurityException(msg); 11108 } 11109 11110 // Special case for adding a package: by default turn on compatibility 11111 // mode. 11112 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11113 Uri data = intent.getData(); 11114 String ssp; 11115 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11116 mCompatModePackages.handlePackageAddedLocked(ssp, 11117 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11118 } 11119 } 11120 11121 /* 11122 * If this is the time zone changed action, queue up a message that will reset the timezone 11123 * of all currently running processes. This message will get queued up before the broadcast 11124 * happens. 11125 */ 11126 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11127 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11128 } 11129 11130 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11131 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11132 } 11133 11134 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11135 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11136 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11137 } 11138 11139 /* 11140 * Prevent non-system code (defined here to be non-persistent 11141 * processes) from sending protected broadcasts. 11142 */ 11143 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11144 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11145 callingUid == 0) { 11146 // Always okay. 11147 } else if (callerApp == null || !callerApp.persistent) { 11148 try { 11149 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11150 intent.getAction())) { 11151 String msg = "Permission Denial: not allowed to send broadcast " 11152 + intent.getAction() + " from pid=" 11153 + callingPid + ", uid=" + callingUid; 11154 Slog.w(TAG, msg); 11155 throw new SecurityException(msg); 11156 } 11157 } catch (RemoteException e) { 11158 Slog.w(TAG, "Remote exception", e); 11159 return ActivityManager.BROADCAST_SUCCESS; 11160 } 11161 } 11162 11163 // Add to the sticky list if requested. 11164 if (sticky) { 11165 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11166 callingPid, callingUid) 11167 != PackageManager.PERMISSION_GRANTED) { 11168 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11169 + callingPid + ", uid=" + callingUid 11170 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11171 Slog.w(TAG, msg); 11172 throw new SecurityException(msg); 11173 } 11174 if (requiredPermission != null) { 11175 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11176 + " and enforce permission " + requiredPermission); 11177 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11178 } 11179 if (intent.getComponent() != null) { 11180 throw new SecurityException( 11181 "Sticky broadcasts can't target a specific component"); 11182 } 11183 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11184 if (list == null) { 11185 list = new ArrayList<Intent>(); 11186 mStickyBroadcasts.put(intent.getAction(), list); 11187 } 11188 int N = list.size(); 11189 int i; 11190 for (i=0; i<N; i++) { 11191 if (intent.filterEquals(list.get(i))) { 11192 // This sticky already exists, replace it. 11193 list.set(i, new Intent(intent)); 11194 break; 11195 } 11196 } 11197 if (i >= N) { 11198 list.add(new Intent(intent)); 11199 } 11200 } 11201 11202 // Figure out who all will receive this broadcast. 11203 List receivers = null; 11204 List<BroadcastFilter> registeredReceivers = null; 11205 try { 11206 // Need to resolve the intent to interested receivers... 11207 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11208 == 0) { 11209 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11210 intent, resolvedType, STOCK_PM_FLAGS, userId); 11211 } 11212 if (intent.getComponent() == null) { 11213 registeredReceivers = mReceiverResolver.queryIntent(intent, 11214 resolvedType, false, userId); 11215 } 11216 } catch (RemoteException ex) { 11217 // pm is in same process, this will never happen. 11218 } 11219 11220 final boolean replacePending = 11221 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11222 11223 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11224 + " replacePending=" + replacePending); 11225 11226 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11227 if (!ordered && NR > 0) { 11228 // If we are not serializing this broadcast, then send the 11229 // registered receivers separately so they don't wait for the 11230 // components to be launched. 11231 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11232 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11233 callerPackage, callingPid, callingUid, requiredPermission, 11234 registeredReceivers, resultTo, resultCode, resultData, map, 11235 ordered, sticky, false, onlySendToCaller); 11236 if (DEBUG_BROADCAST) Slog.v( 11237 TAG, "Enqueueing parallel broadcast " + r); 11238 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11239 if (!replaced) { 11240 queue.enqueueParallelBroadcastLocked(r); 11241 queue.scheduleBroadcastsLocked(); 11242 } 11243 registeredReceivers = null; 11244 NR = 0; 11245 } 11246 11247 // Merge into one list. 11248 int ir = 0; 11249 if (receivers != null) { 11250 // A special case for PACKAGE_ADDED: do not allow the package 11251 // being added to see this broadcast. This prevents them from 11252 // using this as a back door to get run as soon as they are 11253 // installed. Maybe in the future we want to have a special install 11254 // broadcast or such for apps, but we'd like to deliberately make 11255 // this decision. 11256 String skipPackages[] = null; 11257 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11258 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11259 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11260 Uri data = intent.getData(); 11261 if (data != null) { 11262 String pkgName = data.getSchemeSpecificPart(); 11263 if (pkgName != null) { 11264 skipPackages = new String[] { pkgName }; 11265 } 11266 } 11267 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11268 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11269 } 11270 if (skipPackages != null && (skipPackages.length > 0)) { 11271 for (String skipPackage : skipPackages) { 11272 if (skipPackage != null) { 11273 int NT = receivers.size(); 11274 for (int it=0; it<NT; it++) { 11275 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11276 if (curt.activityInfo.packageName.equals(skipPackage)) { 11277 receivers.remove(it); 11278 it--; 11279 NT--; 11280 } 11281 } 11282 } 11283 } 11284 } 11285 11286 int NT = receivers != null ? receivers.size() : 0; 11287 int it = 0; 11288 ResolveInfo curt = null; 11289 BroadcastFilter curr = null; 11290 while (it < NT && ir < NR) { 11291 if (curt == null) { 11292 curt = (ResolveInfo)receivers.get(it); 11293 } 11294 if (curr == null) { 11295 curr = registeredReceivers.get(ir); 11296 } 11297 if (curr.getPriority() >= curt.priority) { 11298 // Insert this broadcast record into the final list. 11299 receivers.add(it, curr); 11300 ir++; 11301 curr = null; 11302 it++; 11303 NT++; 11304 } else { 11305 // Skip to the next ResolveInfo in the final list. 11306 it++; 11307 curt = null; 11308 } 11309 } 11310 } 11311 while (ir < NR) { 11312 if (receivers == null) { 11313 receivers = new ArrayList(); 11314 } 11315 receivers.add(registeredReceivers.get(ir)); 11316 ir++; 11317 } 11318 11319 if ((receivers != null && receivers.size() > 0) 11320 || resultTo != null) { 11321 BroadcastQueue queue = broadcastQueueForIntent(intent); 11322 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11323 callerPackage, callingPid, callingUid, requiredPermission, 11324 receivers, resultTo, resultCode, resultData, map, ordered, 11325 sticky, false, onlySendToCaller); 11326 if (DEBUG_BROADCAST) Slog.v( 11327 TAG, "Enqueueing ordered broadcast " + r 11328 + ": prev had " + queue.mOrderedBroadcasts.size()); 11329 if (DEBUG_BROADCAST) { 11330 int seq = r.intent.getIntExtra("seq", -1); 11331 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11332 } 11333 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11334 if (!replaced) { 11335 queue.enqueueOrderedBroadcastLocked(r); 11336 queue.scheduleBroadcastsLocked(); 11337 } 11338 } 11339 11340 return ActivityManager.BROADCAST_SUCCESS; 11341 } 11342 11343 final Intent verifyBroadcastLocked(Intent intent) { 11344 // Refuse possible leaked file descriptors 11345 if (intent != null && intent.hasFileDescriptors() == true) { 11346 throw new IllegalArgumentException("File descriptors passed in Intent"); 11347 } 11348 11349 int flags = intent.getFlags(); 11350 11351 if (!mProcessesReady) { 11352 // if the caller really truly claims to know what they're doing, go 11353 // ahead and allow the broadcast without launching any receivers 11354 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11355 intent = new Intent(intent); 11356 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11357 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11358 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11359 + " before boot completion"); 11360 throw new IllegalStateException("Cannot broadcast before boot completed"); 11361 } 11362 } 11363 11364 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11365 throw new IllegalArgumentException( 11366 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11367 } 11368 11369 return intent; 11370 } 11371 11372 public final int broadcastIntent(IApplicationThread caller, 11373 Intent intent, String resolvedType, IIntentReceiver resultTo, 11374 int resultCode, String resultData, Bundle map, 11375 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11376 enforceNotIsolatedCaller("broadcastIntent"); 11377 synchronized(this) { 11378 intent = verifyBroadcastLocked(intent); 11379 11380 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11381 final int callingPid = Binder.getCallingPid(); 11382 final int callingUid = Binder.getCallingUid(); 11383 final long origId = Binder.clearCallingIdentity(); 11384 int res = broadcastIntentLocked(callerApp, 11385 callerApp != null ? callerApp.info.packageName : null, 11386 intent, resolvedType, resultTo, 11387 resultCode, resultData, map, requiredPermission, serialized, sticky, 11388 callingPid, callingUid, userId); 11389 Binder.restoreCallingIdentity(origId); 11390 return res; 11391 } 11392 } 11393 11394 int broadcastIntentInPackage(String packageName, int uid, 11395 Intent intent, String resolvedType, IIntentReceiver resultTo, 11396 int resultCode, String resultData, Bundle map, 11397 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11398 synchronized(this) { 11399 intent = verifyBroadcastLocked(intent); 11400 11401 final long origId = Binder.clearCallingIdentity(); 11402 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11403 resultTo, resultCode, resultData, map, requiredPermission, 11404 serialized, sticky, -1, uid, userId); 11405 Binder.restoreCallingIdentity(origId); 11406 return res; 11407 } 11408 } 11409 11410 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11411 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11412 // Refuse possible leaked file descriptors 11413 if (intent != null && intent.hasFileDescriptors() == true) { 11414 throw new IllegalArgumentException("File descriptors passed in Intent"); 11415 } 11416 11417 synchronized(this) { 11418 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11419 != PackageManager.PERMISSION_GRANTED) { 11420 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11421 + Binder.getCallingPid() 11422 + ", uid=" + Binder.getCallingUid() 11423 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11424 Slog.w(TAG, msg); 11425 throw new SecurityException(msg); 11426 } 11427 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11428 if (list != null) { 11429 int N = list.size(); 11430 int i; 11431 for (i=0; i<N; i++) { 11432 if (intent.filterEquals(list.get(i))) { 11433 list.remove(i); 11434 break; 11435 } 11436 } 11437 } 11438 } 11439 } 11440 11441 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11442 String resultData, Bundle resultExtras, boolean resultAbort, 11443 boolean explicit) { 11444 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11445 if (r == null) { 11446 Slog.w(TAG, "finishReceiver called but not found on queue"); 11447 return false; 11448 } 11449 11450 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11451 explicit); 11452 } 11453 11454 public void finishReceiver(IBinder who, int resultCode, String resultData, 11455 Bundle resultExtras, boolean resultAbort) { 11456 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11457 11458 // Refuse possible leaked file descriptors 11459 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11460 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11461 } 11462 11463 final long origId = Binder.clearCallingIdentity(); 11464 try { 11465 boolean doNext = false; 11466 BroadcastRecord r = null; 11467 11468 synchronized(this) { 11469 r = broadcastRecordForReceiverLocked(who); 11470 if (r != null) { 11471 doNext = r.queue.finishReceiverLocked(r, resultCode, 11472 resultData, resultExtras, resultAbort, true); 11473 } 11474 } 11475 11476 if (doNext) { 11477 r.queue.processNextBroadcast(false); 11478 } 11479 trimApplications(); 11480 } finally { 11481 Binder.restoreCallingIdentity(origId); 11482 } 11483 } 11484 11485 // ========================================================= 11486 // INSTRUMENTATION 11487 // ========================================================= 11488 11489 public boolean startInstrumentation(ComponentName className, 11490 String profileFile, int flags, Bundle arguments, 11491 IInstrumentationWatcher watcher) { 11492 enforceNotIsolatedCaller("startInstrumentation"); 11493 // Refuse possible leaked file descriptors 11494 if (arguments != null && arguments.hasFileDescriptors()) { 11495 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11496 } 11497 11498 synchronized(this) { 11499 InstrumentationInfo ii = null; 11500 ApplicationInfo ai = null; 11501 try { 11502 ii = mContext.getPackageManager().getInstrumentationInfo( 11503 className, STOCK_PM_FLAGS); 11504 ai = mContext.getPackageManager().getApplicationInfo( 11505 ii.targetPackage, STOCK_PM_FLAGS); 11506 } catch (PackageManager.NameNotFoundException e) { 11507 } 11508 if (ii == null) { 11509 reportStartInstrumentationFailure(watcher, className, 11510 "Unable to find instrumentation info for: " + className); 11511 return false; 11512 } 11513 if (ai == null) { 11514 reportStartInstrumentationFailure(watcher, className, 11515 "Unable to find instrumentation target package: " + ii.targetPackage); 11516 return false; 11517 } 11518 11519 int match = mContext.getPackageManager().checkSignatures( 11520 ii.targetPackage, ii.packageName); 11521 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11522 String msg = "Permission Denial: starting instrumentation " 11523 + className + " from pid=" 11524 + Binder.getCallingPid() 11525 + ", uid=" + Binder.getCallingPid() 11526 + " not allowed because package " + ii.packageName 11527 + " does not have a signature matching the target " 11528 + ii.targetPackage; 11529 reportStartInstrumentationFailure(watcher, className, msg); 11530 throw new SecurityException(msg); 11531 } 11532 11533 int userId = UserId.getCallingUserId(); 11534 final long origId = Binder.clearCallingIdentity(); 11535 // Instrumentation can kill and relaunch even persistent processes 11536 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11537 ProcessRecord app = addAppLocked(ai, false); 11538 app.instrumentationClass = className; 11539 app.instrumentationInfo = ai; 11540 app.instrumentationProfileFile = profileFile; 11541 app.instrumentationArguments = arguments; 11542 app.instrumentationWatcher = watcher; 11543 app.instrumentationResultClass = className; 11544 Binder.restoreCallingIdentity(origId); 11545 } 11546 11547 return true; 11548 } 11549 11550 /** 11551 * Report errors that occur while attempting to start Instrumentation. Always writes the 11552 * error to the logs, but if somebody is watching, send the report there too. This enables 11553 * the "am" command to report errors with more information. 11554 * 11555 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11556 * @param cn The component name of the instrumentation. 11557 * @param report The error report. 11558 */ 11559 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11560 ComponentName cn, String report) { 11561 Slog.w(TAG, report); 11562 try { 11563 if (watcher != null) { 11564 Bundle results = new Bundle(); 11565 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11566 results.putString("Error", report); 11567 watcher.instrumentationStatus(cn, -1, results); 11568 } 11569 } catch (RemoteException e) { 11570 Slog.w(TAG, e); 11571 } 11572 } 11573 11574 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11575 if (app.instrumentationWatcher != null) { 11576 try { 11577 // NOTE: IInstrumentationWatcher *must* be oneway here 11578 app.instrumentationWatcher.instrumentationFinished( 11579 app.instrumentationClass, 11580 resultCode, 11581 results); 11582 } catch (RemoteException e) { 11583 } 11584 } 11585 app.instrumentationWatcher = null; 11586 app.instrumentationClass = null; 11587 app.instrumentationInfo = null; 11588 app.instrumentationProfileFile = null; 11589 app.instrumentationArguments = null; 11590 11591 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11592 } 11593 11594 public void finishInstrumentation(IApplicationThread target, 11595 int resultCode, Bundle results) { 11596 int userId = UserId.getCallingUserId(); 11597 // Refuse possible leaked file descriptors 11598 if (results != null && results.hasFileDescriptors()) { 11599 throw new IllegalArgumentException("File descriptors passed in Intent"); 11600 } 11601 11602 synchronized(this) { 11603 ProcessRecord app = getRecordForAppLocked(target); 11604 if (app == null) { 11605 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11606 return; 11607 } 11608 final long origId = Binder.clearCallingIdentity(); 11609 finishInstrumentationLocked(app, resultCode, results); 11610 Binder.restoreCallingIdentity(origId); 11611 } 11612 } 11613 11614 // ========================================================= 11615 // CONFIGURATION 11616 // ========================================================= 11617 11618 public ConfigurationInfo getDeviceConfigurationInfo() { 11619 ConfigurationInfo config = new ConfigurationInfo(); 11620 synchronized (this) { 11621 config.reqTouchScreen = mConfiguration.touchscreen; 11622 config.reqKeyboardType = mConfiguration.keyboard; 11623 config.reqNavigation = mConfiguration.navigation; 11624 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11625 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11626 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11627 } 11628 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11629 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11630 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11631 } 11632 config.reqGlEsVersion = GL_ES_VERSION; 11633 } 11634 return config; 11635 } 11636 11637 public Configuration getConfiguration() { 11638 Configuration ci; 11639 synchronized(this) { 11640 ci = new Configuration(mConfiguration); 11641 } 11642 return ci; 11643 } 11644 11645 public void updatePersistentConfiguration(Configuration values) { 11646 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11647 "updateConfiguration()"); 11648 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11649 "updateConfiguration()"); 11650 if (values == null) { 11651 throw new NullPointerException("Configuration must not be null"); 11652 } 11653 11654 synchronized(this) { 11655 final long origId = Binder.clearCallingIdentity(); 11656 updateConfigurationLocked(values, null, true, false); 11657 Binder.restoreCallingIdentity(origId); 11658 } 11659 } 11660 11661 public void updateConfiguration(Configuration values) { 11662 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11663 "updateConfiguration()"); 11664 11665 synchronized(this) { 11666 if (values == null && mWindowManager != null) { 11667 // sentinel: fetch the current configuration from the window manager 11668 values = mWindowManager.computeNewConfiguration(); 11669 } 11670 11671 if (mWindowManager != null) { 11672 mProcessList.applyDisplaySize(mWindowManager); 11673 } 11674 11675 final long origId = Binder.clearCallingIdentity(); 11676 if (values != null) { 11677 Settings.System.clearConfiguration(values); 11678 } 11679 updateConfigurationLocked(values, null, false, false); 11680 Binder.restoreCallingIdentity(origId); 11681 } 11682 } 11683 11684 /** 11685 * Do either or both things: (1) change the current configuration, and (2) 11686 * make sure the given activity is running with the (now) current 11687 * configuration. Returns true if the activity has been left running, or 11688 * false if <var>starting</var> is being destroyed to match the new 11689 * configuration. 11690 * @param persistent TODO 11691 */ 11692 boolean updateConfigurationLocked(Configuration values, 11693 ActivityRecord starting, boolean persistent, boolean initLocale) { 11694 // do nothing if we are headless 11695 if (mHeadless) return true; 11696 11697 int changes = 0; 11698 11699 boolean kept = true; 11700 11701 if (values != null) { 11702 Configuration newConfig = new Configuration(mConfiguration); 11703 changes = newConfig.updateFrom(values); 11704 if (changes != 0) { 11705 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11706 Slog.i(TAG, "Updating configuration to: " + values); 11707 } 11708 11709 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11710 11711 if (values.locale != null && !initLocale) { 11712 saveLocaleLocked(values.locale, 11713 !values.locale.equals(mConfiguration.locale), 11714 values.userSetLocale); 11715 } 11716 11717 mConfigurationSeq++; 11718 if (mConfigurationSeq <= 0) { 11719 mConfigurationSeq = 1; 11720 } 11721 newConfig.seq = mConfigurationSeq; 11722 mConfiguration = newConfig; 11723 Slog.i(TAG, "Config changed: " + newConfig); 11724 11725 final Configuration configCopy = new Configuration(mConfiguration); 11726 11727 // TODO: If our config changes, should we auto dismiss any currently 11728 // showing dialogs? 11729 mShowDialogs = shouldShowDialogs(newConfig); 11730 11731 AttributeCache ac = AttributeCache.instance(); 11732 if (ac != null) { 11733 ac.updateConfiguration(configCopy); 11734 } 11735 11736 // Make sure all resources in our process are updated 11737 // right now, so that anyone who is going to retrieve 11738 // resource values after we return will be sure to get 11739 // the new ones. This is especially important during 11740 // boot, where the first config change needs to guarantee 11741 // all resources have that config before following boot 11742 // code is executed. 11743 mSystemThread.applyConfigurationToResources(configCopy); 11744 11745 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11746 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11747 msg.obj = new Configuration(configCopy); 11748 mHandler.sendMessage(msg); 11749 } 11750 11751 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11752 ProcessRecord app = mLruProcesses.get(i); 11753 try { 11754 if (app.thread != null) { 11755 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11756 + app.processName + " new config " + mConfiguration); 11757 app.thread.scheduleConfigurationChanged(configCopy); 11758 } 11759 } catch (Exception e) { 11760 } 11761 } 11762 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11763 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11764 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11765 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11766 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11767 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11768 broadcastIntentLocked(null, null, 11769 new Intent(Intent.ACTION_LOCALE_CHANGED), 11770 null, null, 0, null, null, 11771 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11772 } 11773 } 11774 } 11775 11776 if (changes != 0 && starting == null) { 11777 // If the configuration changed, and the caller is not already 11778 // in the process of starting an activity, then find the top 11779 // activity to check if its configuration needs to change. 11780 starting = mMainStack.topRunningActivityLocked(null); 11781 } 11782 11783 if (starting != null) { 11784 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11785 // And we need to make sure at this point that all other activities 11786 // are made visible with the correct configuration. 11787 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11788 } 11789 11790 if (values != null && mWindowManager != null) { 11791 mWindowManager.setNewConfiguration(mConfiguration); 11792 } 11793 11794 return kept; 11795 } 11796 11797 /** 11798 * Decide based on the configuration whether we should shouw the ANR, 11799 * crash, etc dialogs. The idea is that if there is no affordnace to 11800 * press the on-screen buttons, we shouldn't show the dialog. 11801 * 11802 * A thought: SystemUI might also want to get told about this, the Power 11803 * dialog / global actions also might want different behaviors. 11804 */ 11805 private static final boolean shouldShowDialogs(Configuration config) { 11806 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11807 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11808 } 11809 11810 /** 11811 * Save the locale. You must be inside a synchronized (this) block. 11812 */ 11813 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11814 if(isDiff) { 11815 SystemProperties.set("user.language", l.getLanguage()); 11816 SystemProperties.set("user.region", l.getCountry()); 11817 } 11818 11819 if(isPersist) { 11820 SystemProperties.set("persist.sys.language", l.getLanguage()); 11821 SystemProperties.set("persist.sys.country", l.getCountry()); 11822 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11823 } 11824 } 11825 11826 @Override 11827 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11828 ActivityRecord srec = ActivityRecord.forToken(token); 11829 return srec != null && srec.task.affinity != null && 11830 srec.task.affinity.equals(destAffinity); 11831 } 11832 11833 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11834 Intent resultData) { 11835 ComponentName dest = destIntent.getComponent(); 11836 11837 synchronized (this) { 11838 ActivityRecord srec = ActivityRecord.forToken(token); 11839 if (srec == null) { 11840 return false; 11841 } 11842 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11843 final int start = history.indexOf(srec); 11844 if (start < 0) { 11845 // Current activity is not in history stack; do nothing. 11846 return false; 11847 } 11848 int finishTo = start - 1; 11849 ActivityRecord parent = null; 11850 boolean foundParentInTask = false; 11851 if (dest != null) { 11852 TaskRecord tr = srec.task; 11853 for (int i = start - 1; i >= 0; i--) { 11854 ActivityRecord r = history.get(i); 11855 if (tr != r.task) { 11856 // Couldn't find parent in the same task; stop at the one above this. 11857 // (Root of current task; in-app "home" behavior) 11858 // Always at least finish the current activity. 11859 finishTo = Math.min(start - 1, i + 1); 11860 parent = history.get(finishTo); 11861 break; 11862 } else if (r.info.packageName.equals(dest.getPackageName()) && 11863 r.info.name.equals(dest.getClassName())) { 11864 finishTo = i; 11865 parent = r; 11866 foundParentInTask = true; 11867 break; 11868 } 11869 } 11870 } 11871 11872 if (mController != null) { 11873 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11874 if (next != null) { 11875 // ask watcher if this is allowed 11876 boolean resumeOK = true; 11877 try { 11878 resumeOK = mController.activityResuming(next.packageName); 11879 } catch (RemoteException e) { 11880 mController = null; 11881 } 11882 11883 if (!resumeOK) { 11884 return false; 11885 } 11886 } 11887 } 11888 final long origId = Binder.clearCallingIdentity(); 11889 for (int i = start; i > finishTo; i--) { 11890 ActivityRecord r = history.get(i); 11891 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11892 "navigate-up"); 11893 // Only return the supplied result for the first activity finished 11894 resultCode = Activity.RESULT_CANCELED; 11895 resultData = null; 11896 } 11897 11898 if (parent != null && foundParentInTask) { 11899 final int parentLaunchMode = parent.info.launchMode; 11900 final int destIntentFlags = destIntent.getFlags(); 11901 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11902 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11903 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11904 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11905 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11906 } else { 11907 try { 11908 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11909 destIntent.getComponent(), 0, UserId.getCallingUserId()); 11910 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11911 null, aInfo, parent.appToken, null, 11912 0, -1, parent.launchedFromUid, 0, null, true, null); 11913 foundParentInTask = res == ActivityManager.START_SUCCESS; 11914 } catch (RemoteException e) { 11915 foundParentInTask = false; 11916 } 11917 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11918 resultData, "navigate-up"); 11919 } 11920 } 11921 Binder.restoreCallingIdentity(origId); 11922 return foundParentInTask; 11923 } 11924 } 11925 11926 public int getLaunchedFromUid(IBinder activityToken) { 11927 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11928 if (srec == null) { 11929 return -1; 11930 } 11931 return srec.launchedFromUid; 11932 } 11933 11934 // ========================================================= 11935 // LIFETIME MANAGEMENT 11936 // ========================================================= 11937 11938 // Returns which broadcast queue the app is the current [or imminent] receiver 11939 // on, or 'null' if the app is not an active broadcast recipient. 11940 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11941 BroadcastRecord r = app.curReceiver; 11942 if (r != null) { 11943 return r.queue; 11944 } 11945 11946 // It's not the current receiver, but it might be starting up to become one 11947 synchronized (this) { 11948 for (BroadcastQueue queue : mBroadcastQueues) { 11949 r = queue.mPendingBroadcast; 11950 if (r != null && r.curApp == app) { 11951 // found it; report which queue it's in 11952 return queue; 11953 } 11954 } 11955 } 11956 11957 return null; 11958 } 11959 11960 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 11961 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 11962 if (mAdjSeq == app.adjSeq) { 11963 // This adjustment has already been computed. If we are calling 11964 // from the top, we may have already computed our adjustment with 11965 // an earlier hidden adjustment that isn't really for us... if 11966 // so, use the new hidden adjustment. 11967 if (!recursed && app.hidden) { 11968 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 11969 } 11970 return app.curRawAdj; 11971 } 11972 11973 if (app.thread == null) { 11974 app.adjSeq = mAdjSeq; 11975 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 11976 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 11977 } 11978 11979 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 11980 app.adjSource = null; 11981 app.adjTarget = null; 11982 app.empty = false; 11983 app.hidden = false; 11984 11985 final int activitiesSize = app.activities.size(); 11986 11987 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 11988 // The max adjustment doesn't allow this app to be anything 11989 // below foreground, so it is not worth doing work for it. 11990 app.adjType = "fixed"; 11991 app.adjSeq = mAdjSeq; 11992 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 11993 app.foregroundActivities = false; 11994 app.keeping = true; 11995 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 11996 // System process can do UI, and when they do we want to have 11997 // them trim their memory after the user leaves the UI. To 11998 // facilitate this, here we need to determine whether or not it 11999 // is currently showing UI. 12000 app.systemNoUi = true; 12001 if (app == TOP_APP) { 12002 app.systemNoUi = false; 12003 } else if (activitiesSize > 0) { 12004 for (int j = 0; j < activitiesSize; j++) { 12005 final ActivityRecord r = app.activities.get(j); 12006 if (r.visible) { 12007 app.systemNoUi = false; 12008 break; 12009 } 12010 } 12011 } 12012 return (app.curAdj=app.maxAdj); 12013 } 12014 12015 app.keeping = false; 12016 app.systemNoUi = false; 12017 12018 // Determine the importance of the process, starting with most 12019 // important to least, and assign an appropriate OOM adjustment. 12020 int adj; 12021 int schedGroup; 12022 boolean foregroundActivities = false; 12023 boolean interesting = false; 12024 BroadcastQueue queue; 12025 if (app == TOP_APP) { 12026 // The last app on the list is the foreground app. 12027 adj = ProcessList.FOREGROUND_APP_ADJ; 12028 schedGroup = Process.THREAD_GROUP_DEFAULT; 12029 app.adjType = "top-activity"; 12030 foregroundActivities = true; 12031 interesting = true; 12032 } else if (app.instrumentationClass != null) { 12033 // Don't want to kill running instrumentation. 12034 adj = ProcessList.FOREGROUND_APP_ADJ; 12035 schedGroup = Process.THREAD_GROUP_DEFAULT; 12036 app.adjType = "instrumentation"; 12037 interesting = true; 12038 } else if ((queue = isReceivingBroadcast(app)) != null) { 12039 // An app that is currently receiving a broadcast also 12040 // counts as being in the foreground for OOM killer purposes. 12041 // It's placed in a sched group based on the nature of the 12042 // broadcast as reflected by which queue it's active in. 12043 adj = ProcessList.FOREGROUND_APP_ADJ; 12044 schedGroup = (queue == mFgBroadcastQueue) 12045 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12046 app.adjType = "broadcast"; 12047 } else if (app.executingServices.size() > 0) { 12048 // An app that is currently executing a service callback also 12049 // counts as being in the foreground. 12050 adj = ProcessList.FOREGROUND_APP_ADJ; 12051 schedGroup = Process.THREAD_GROUP_DEFAULT; 12052 app.adjType = "exec-service"; 12053 } else if (activitiesSize > 0) { 12054 // This app is in the background with paused activities. 12055 // We inspect activities to potentially upgrade adjustment further below. 12056 adj = hiddenAdj; 12057 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12058 app.hidden = true; 12059 app.adjType = "bg-activities"; 12060 } else { 12061 // A very not-needed process. If this is lower in the lru list, 12062 // we will push it in to the empty bucket. 12063 adj = hiddenAdj; 12064 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12065 app.hidden = true; 12066 app.empty = true; 12067 app.adjType = "bg-empty"; 12068 } 12069 12070 boolean hasStoppingActivities = false; 12071 12072 // Examine all activities if not already foreground. 12073 if (!foregroundActivities && activitiesSize > 0) { 12074 for (int j = 0; j < activitiesSize; j++) { 12075 final ActivityRecord r = app.activities.get(j); 12076 if (r.visible) { 12077 // App has a visible activity; only upgrade adjustment. 12078 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12079 adj = ProcessList.VISIBLE_APP_ADJ; 12080 app.adjType = "visible"; 12081 } 12082 schedGroup = Process.THREAD_GROUP_DEFAULT; 12083 app.hidden = false; 12084 foregroundActivities = true; 12085 break; 12086 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12087 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12088 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12089 app.adjType = "pausing"; 12090 } 12091 app.hidden = false; 12092 foregroundActivities = true; 12093 } else if (r.state == ActivityState.STOPPING) { 12094 // We will apply the actual adjustment later, because 12095 // we want to allow this process to immediately go through 12096 // any memory trimming that is in effect. 12097 app.hidden = false; 12098 foregroundActivities = true; 12099 hasStoppingActivities = true; 12100 } 12101 } 12102 } 12103 12104 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12105 if (app.foregroundServices) { 12106 // The user is aware of this app, so make it visible. 12107 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12108 app.hidden = false; 12109 app.adjType = "foreground-service"; 12110 schedGroup = Process.THREAD_GROUP_DEFAULT; 12111 } else if (app.forcingToForeground != null) { 12112 // The user is aware of this app, so make it visible. 12113 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12114 app.hidden = false; 12115 app.adjType = "force-foreground"; 12116 app.adjSource = app.forcingToForeground; 12117 schedGroup = Process.THREAD_GROUP_DEFAULT; 12118 } 12119 } 12120 12121 if (app.foregroundServices) { 12122 interesting = true; 12123 } 12124 12125 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12126 // We don't want to kill the current heavy-weight process. 12127 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12128 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12129 app.hidden = false; 12130 app.adjType = "heavy"; 12131 } 12132 12133 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12134 // This process is hosting what we currently consider to be the 12135 // home app, so we don't want to let it go into the background. 12136 adj = ProcessList.HOME_APP_ADJ; 12137 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12138 app.hidden = false; 12139 app.adjType = "home"; 12140 } 12141 12142 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12143 && app.activities.size() > 0) { 12144 // This was the previous process that showed UI to the user. 12145 // We want to try to keep it around more aggressively, to give 12146 // a good experience around switching between two apps. 12147 adj = ProcessList.PREVIOUS_APP_ADJ; 12148 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12149 app.hidden = false; 12150 app.adjType = "previous"; 12151 } 12152 12153 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12154 + " reason=" + app.adjType); 12155 12156 // By default, we use the computed adjustment. It may be changed if 12157 // there are applications dependent on our services or providers, but 12158 // this gives us a baseline and makes sure we don't get into an 12159 // infinite recursion. 12160 app.adjSeq = mAdjSeq; 12161 app.curRawAdj = app.nonStoppingAdj = adj; 12162 12163 if (mBackupTarget != null && app == mBackupTarget.app) { 12164 // If possible we want to avoid killing apps while they're being backed up 12165 if (adj > ProcessList.BACKUP_APP_ADJ) { 12166 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12167 adj = ProcessList.BACKUP_APP_ADJ; 12168 app.adjType = "backup"; 12169 app.hidden = false; 12170 } 12171 } 12172 12173 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12174 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12175 final long now = SystemClock.uptimeMillis(); 12176 // This process is more important if the top activity is 12177 // bound to the service. 12178 Iterator<ServiceRecord> jt = app.services.iterator(); 12179 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12180 ServiceRecord s = jt.next(); 12181 if (s.startRequested) { 12182 if (app.hasShownUi && app != mHomeProcess) { 12183 // If this process has shown some UI, let it immediately 12184 // go to the LRU list because it may be pretty heavy with 12185 // UI stuff. We'll tag it with a label just to help 12186 // debug and understand what is going on. 12187 if (adj > ProcessList.SERVICE_ADJ) { 12188 app.adjType = "started-bg-ui-services"; 12189 } 12190 } else { 12191 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12192 // This service has seen some activity within 12193 // recent memory, so we will keep its process ahead 12194 // of the background processes. 12195 if (adj > ProcessList.SERVICE_ADJ) { 12196 adj = ProcessList.SERVICE_ADJ; 12197 app.adjType = "started-services"; 12198 app.hidden = false; 12199 } 12200 } 12201 // If we have let the service slide into the background 12202 // state, still have some text describing what it is doing 12203 // even though the service no longer has an impact. 12204 if (adj > ProcessList.SERVICE_ADJ) { 12205 app.adjType = "started-bg-services"; 12206 } 12207 } 12208 // Don't kill this process because it is doing work; it 12209 // has said it is doing work. 12210 app.keeping = true; 12211 } 12212 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12213 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12214 Iterator<ArrayList<ConnectionRecord>> kt 12215 = s.connections.values().iterator(); 12216 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12217 ArrayList<ConnectionRecord> clist = kt.next(); 12218 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12219 // XXX should compute this based on the max of 12220 // all connected clients. 12221 ConnectionRecord cr = clist.get(i); 12222 if (cr.binding.client == app) { 12223 // Binding to ourself is not interesting. 12224 continue; 12225 } 12226 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12227 ProcessRecord client = cr.binding.client; 12228 int clientAdj = adj; 12229 int myHiddenAdj = hiddenAdj; 12230 if (myHiddenAdj > client.hiddenAdj) { 12231 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12232 myHiddenAdj = client.hiddenAdj; 12233 } else { 12234 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12235 } 12236 } 12237 clientAdj = computeOomAdjLocked( 12238 client, myHiddenAdj, TOP_APP, true, doingAll); 12239 String adjType = null; 12240 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12241 // Not doing bind OOM management, so treat 12242 // this guy more like a started service. 12243 if (app.hasShownUi && app != mHomeProcess) { 12244 // If this process has shown some UI, let it immediately 12245 // go to the LRU list because it may be pretty heavy with 12246 // UI stuff. We'll tag it with a label just to help 12247 // debug and understand what is going on. 12248 if (adj > clientAdj) { 12249 adjType = "bound-bg-ui-services"; 12250 } 12251 app.hidden = false; 12252 clientAdj = adj; 12253 } else { 12254 if (now >= (s.lastActivity 12255 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12256 // This service has not seen activity within 12257 // recent memory, so allow it to drop to the 12258 // LRU list if there is no other reason to keep 12259 // it around. We'll also tag it with a label just 12260 // to help debug and undertand what is going on. 12261 if (adj > clientAdj) { 12262 adjType = "bound-bg-services"; 12263 } 12264 clientAdj = adj; 12265 } 12266 } 12267 } 12268 if (adj > clientAdj) { 12269 // If this process has recently shown UI, and 12270 // the process that is binding to it is less 12271 // important than being visible, then we don't 12272 // care about the binding as much as we care 12273 // about letting this process get into the LRU 12274 // list to be killed and restarted if needed for 12275 // memory. 12276 if (app.hasShownUi && app != mHomeProcess 12277 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12278 adjType = "bound-bg-ui-services"; 12279 } else { 12280 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12281 |Context.BIND_IMPORTANT)) != 0) { 12282 adj = clientAdj; 12283 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12284 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12285 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12286 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12287 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12288 adj = clientAdj; 12289 } else { 12290 app.pendingUiClean = true; 12291 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12292 adj = ProcessList.VISIBLE_APP_ADJ; 12293 } 12294 } 12295 if (!client.hidden) { 12296 app.hidden = false; 12297 } 12298 if (client.keeping) { 12299 app.keeping = true; 12300 } 12301 adjType = "service"; 12302 } 12303 } 12304 if (adjType != null) { 12305 app.adjType = adjType; 12306 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12307 .REASON_SERVICE_IN_USE; 12308 app.adjSource = cr.binding.client; 12309 app.adjSourceOom = clientAdj; 12310 app.adjTarget = s.name; 12311 } 12312 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12313 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12314 schedGroup = Process.THREAD_GROUP_DEFAULT; 12315 } 12316 } 12317 } 12318 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12319 ActivityRecord a = cr.activity; 12320 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12321 (a.visible || a.state == ActivityState.RESUMED 12322 || a.state == ActivityState.PAUSING)) { 12323 adj = ProcessList.FOREGROUND_APP_ADJ; 12324 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12325 schedGroup = Process.THREAD_GROUP_DEFAULT; 12326 } 12327 app.hidden = false; 12328 app.adjType = "service"; 12329 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12330 .REASON_SERVICE_IN_USE; 12331 app.adjSource = a; 12332 app.adjSourceOom = adj; 12333 app.adjTarget = s.name; 12334 } 12335 } 12336 } 12337 } 12338 } 12339 } 12340 12341 // Finally, if this process has active services running in it, we 12342 // would like to avoid killing it unless it would prevent the current 12343 // application from running. By default we put the process in 12344 // with the rest of the background processes; as we scan through 12345 // its services we may bump it up from there. 12346 if (adj > hiddenAdj) { 12347 adj = hiddenAdj; 12348 app.hidden = false; 12349 app.adjType = "bg-services"; 12350 } 12351 } 12352 12353 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12354 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12355 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12356 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12357 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12358 ContentProviderRecord cpr = jt.next(); 12359 for (int i = cpr.connections.size()-1; 12360 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12361 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12362 i--) { 12363 ContentProviderConnection conn = cpr.connections.get(i); 12364 ProcessRecord client = conn.client; 12365 if (client == app) { 12366 // Being our own client is not interesting. 12367 continue; 12368 } 12369 int myHiddenAdj = hiddenAdj; 12370 if (myHiddenAdj > client.hiddenAdj) { 12371 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12372 myHiddenAdj = client.hiddenAdj; 12373 } else { 12374 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12375 } 12376 } 12377 int clientAdj = computeOomAdjLocked( 12378 client, myHiddenAdj, TOP_APP, true, doingAll); 12379 if (adj > clientAdj) { 12380 if (app.hasShownUi && app != mHomeProcess 12381 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12382 app.adjType = "bg-ui-provider"; 12383 } else { 12384 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12385 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12386 app.adjType = "provider"; 12387 } 12388 if (!client.hidden) { 12389 app.hidden = false; 12390 } 12391 if (client.keeping) { 12392 app.keeping = true; 12393 } 12394 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12395 .REASON_PROVIDER_IN_USE; 12396 app.adjSource = client; 12397 app.adjSourceOom = clientAdj; 12398 app.adjTarget = cpr.name; 12399 } 12400 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12401 schedGroup = Process.THREAD_GROUP_DEFAULT; 12402 } 12403 } 12404 // If the provider has external (non-framework) process 12405 // dependencies, ensure that its adjustment is at least 12406 // FOREGROUND_APP_ADJ. 12407 if (cpr.hasExternalProcessHandles()) { 12408 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12409 adj = ProcessList.FOREGROUND_APP_ADJ; 12410 schedGroup = Process.THREAD_GROUP_DEFAULT; 12411 app.hidden = false; 12412 app.keeping = true; 12413 app.adjType = "provider"; 12414 app.adjTarget = cpr.name; 12415 } 12416 } 12417 } 12418 } 12419 12420 if (adj == ProcessList.SERVICE_ADJ) { 12421 if (doingAll) { 12422 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12423 mNewNumServiceProcs++; 12424 } 12425 if (app.serviceb) { 12426 adj = ProcessList.SERVICE_B_ADJ; 12427 } 12428 } else { 12429 app.serviceb = false; 12430 } 12431 12432 app.nonStoppingAdj = adj; 12433 12434 if (hasStoppingActivities) { 12435 // Only upgrade adjustment. 12436 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12437 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12438 app.adjType = "stopping"; 12439 } 12440 } 12441 12442 app.curRawAdj = adj; 12443 12444 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12445 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12446 if (adj > app.maxAdj) { 12447 adj = app.maxAdj; 12448 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12449 schedGroup = Process.THREAD_GROUP_DEFAULT; 12450 } 12451 } 12452 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12453 app.keeping = true; 12454 } 12455 12456 if (app.hasAboveClient) { 12457 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12458 // then we need to drop its adjustment to be lower than the service's 12459 // in order to honor the request. We want to drop it by one adjustment 12460 // level... but there is special meaning applied to various levels so 12461 // we will skip some of them. 12462 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12463 // System process will not get dropped, ever 12464 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12465 adj = ProcessList.VISIBLE_APP_ADJ; 12466 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12467 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12468 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12469 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12470 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12471 adj++; 12472 } 12473 } 12474 12475 int importance = app.memImportance; 12476 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12477 app.curAdj = adj; 12478 app.curSchedGroup = schedGroup; 12479 if (!interesting) { 12480 // For this reporting, if there is not something explicitly 12481 // interesting in this process then we will push it to the 12482 // background importance. 12483 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12484 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12485 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12486 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12487 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12488 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12489 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12490 } else if (adj >= ProcessList.SERVICE_ADJ) { 12491 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12492 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12493 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12494 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12495 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12496 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12497 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12498 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12499 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12500 } else { 12501 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12502 } 12503 } 12504 12505 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12506 if (foregroundActivities != app.foregroundActivities) { 12507 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12508 } 12509 if (changes != 0) { 12510 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12511 app.memImportance = importance; 12512 app.foregroundActivities = foregroundActivities; 12513 int i = mPendingProcessChanges.size()-1; 12514 ProcessChangeItem item = null; 12515 while (i >= 0) { 12516 item = mPendingProcessChanges.get(i); 12517 if (item.pid == app.pid) { 12518 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12519 break; 12520 } 12521 i--; 12522 } 12523 if (i < 0) { 12524 // No existing item in pending changes; need a new one. 12525 final int NA = mAvailProcessChanges.size(); 12526 if (NA > 0) { 12527 item = mAvailProcessChanges.remove(NA-1); 12528 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12529 } else { 12530 item = new ProcessChangeItem(); 12531 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12532 } 12533 item.changes = 0; 12534 item.pid = app.pid; 12535 item.uid = app.info.uid; 12536 if (mPendingProcessChanges.size() == 0) { 12537 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12538 "*** Enqueueing dispatch processes changed!"); 12539 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12540 } 12541 mPendingProcessChanges.add(item); 12542 } 12543 item.changes |= changes; 12544 item.importance = importance; 12545 item.foregroundActivities = foregroundActivities; 12546 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12547 + Integer.toHexString(System.identityHashCode(item)) 12548 + " " + app.toShortString() + ": changes=" + item.changes 12549 + " importance=" + item.importance 12550 + " foreground=" + item.foregroundActivities 12551 + " type=" + app.adjType + " source=" + app.adjSource 12552 + " target=" + app.adjTarget); 12553 } 12554 12555 return app.curRawAdj; 12556 } 12557 12558 /** 12559 * Ask a given process to GC right now. 12560 */ 12561 final void performAppGcLocked(ProcessRecord app) { 12562 try { 12563 app.lastRequestedGc = SystemClock.uptimeMillis(); 12564 if (app.thread != null) { 12565 if (app.reportLowMemory) { 12566 app.reportLowMemory = false; 12567 app.thread.scheduleLowMemory(); 12568 } else { 12569 app.thread.processInBackground(); 12570 } 12571 } 12572 } catch (Exception e) { 12573 // whatever. 12574 } 12575 } 12576 12577 /** 12578 * Returns true if things are idle enough to perform GCs. 12579 */ 12580 private final boolean canGcNowLocked() { 12581 boolean processingBroadcasts = false; 12582 for (BroadcastQueue q : mBroadcastQueues) { 12583 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12584 processingBroadcasts = true; 12585 } 12586 } 12587 return !processingBroadcasts 12588 && (mSleeping || (mMainStack.mResumedActivity != null && 12589 mMainStack.mResumedActivity.idle)); 12590 } 12591 12592 /** 12593 * Perform GCs on all processes that are waiting for it, but only 12594 * if things are idle. 12595 */ 12596 final void performAppGcsLocked() { 12597 final int N = mProcessesToGc.size(); 12598 if (N <= 0) { 12599 return; 12600 } 12601 if (canGcNowLocked()) { 12602 while (mProcessesToGc.size() > 0) { 12603 ProcessRecord proc = mProcessesToGc.remove(0); 12604 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12605 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12606 <= SystemClock.uptimeMillis()) { 12607 // To avoid spamming the system, we will GC processes one 12608 // at a time, waiting a few seconds between each. 12609 performAppGcLocked(proc); 12610 scheduleAppGcsLocked(); 12611 return; 12612 } else { 12613 // It hasn't been long enough since we last GCed this 12614 // process... put it in the list to wait for its time. 12615 addProcessToGcListLocked(proc); 12616 break; 12617 } 12618 } 12619 } 12620 12621 scheduleAppGcsLocked(); 12622 } 12623 } 12624 12625 /** 12626 * If all looks good, perform GCs on all processes waiting for them. 12627 */ 12628 final void performAppGcsIfAppropriateLocked() { 12629 if (canGcNowLocked()) { 12630 performAppGcsLocked(); 12631 return; 12632 } 12633 // Still not idle, wait some more. 12634 scheduleAppGcsLocked(); 12635 } 12636 12637 /** 12638 * Schedule the execution of all pending app GCs. 12639 */ 12640 final void scheduleAppGcsLocked() { 12641 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12642 12643 if (mProcessesToGc.size() > 0) { 12644 // Schedule a GC for the time to the next process. 12645 ProcessRecord proc = mProcessesToGc.get(0); 12646 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12647 12648 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12649 long now = SystemClock.uptimeMillis(); 12650 if (when < (now+GC_TIMEOUT)) { 12651 when = now + GC_TIMEOUT; 12652 } 12653 mHandler.sendMessageAtTime(msg, when); 12654 } 12655 } 12656 12657 /** 12658 * Add a process to the array of processes waiting to be GCed. Keeps the 12659 * list in sorted order by the last GC time. The process can't already be 12660 * on the list. 12661 */ 12662 final void addProcessToGcListLocked(ProcessRecord proc) { 12663 boolean added = false; 12664 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12665 if (mProcessesToGc.get(i).lastRequestedGc < 12666 proc.lastRequestedGc) { 12667 added = true; 12668 mProcessesToGc.add(i+1, proc); 12669 break; 12670 } 12671 } 12672 if (!added) { 12673 mProcessesToGc.add(0, proc); 12674 } 12675 } 12676 12677 /** 12678 * Set up to ask a process to GC itself. This will either do it 12679 * immediately, or put it on the list of processes to gc the next 12680 * time things are idle. 12681 */ 12682 final void scheduleAppGcLocked(ProcessRecord app) { 12683 long now = SystemClock.uptimeMillis(); 12684 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12685 return; 12686 } 12687 if (!mProcessesToGc.contains(app)) { 12688 addProcessToGcListLocked(app); 12689 scheduleAppGcsLocked(); 12690 } 12691 } 12692 12693 final void checkExcessivePowerUsageLocked(boolean doKills) { 12694 updateCpuStatsNow(); 12695 12696 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12697 boolean doWakeKills = doKills; 12698 boolean doCpuKills = doKills; 12699 if (mLastPowerCheckRealtime == 0) { 12700 doWakeKills = false; 12701 } 12702 if (mLastPowerCheckUptime == 0) { 12703 doCpuKills = false; 12704 } 12705 if (stats.isScreenOn()) { 12706 doWakeKills = false; 12707 } 12708 final long curRealtime = SystemClock.elapsedRealtime(); 12709 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12710 final long curUptime = SystemClock.uptimeMillis(); 12711 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12712 mLastPowerCheckRealtime = curRealtime; 12713 mLastPowerCheckUptime = curUptime; 12714 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12715 doWakeKills = false; 12716 } 12717 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12718 doCpuKills = false; 12719 } 12720 int i = mLruProcesses.size(); 12721 while (i > 0) { 12722 i--; 12723 ProcessRecord app = mLruProcesses.get(i); 12724 if (!app.keeping) { 12725 long wtime; 12726 synchronized (stats) { 12727 wtime = stats.getProcessWakeTime(app.info.uid, 12728 app.pid, curRealtime); 12729 } 12730 long wtimeUsed = wtime - app.lastWakeTime; 12731 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12732 if (DEBUG_POWER) { 12733 StringBuilder sb = new StringBuilder(128); 12734 sb.append("Wake for "); 12735 app.toShortString(sb); 12736 sb.append(": over "); 12737 TimeUtils.formatDuration(realtimeSince, sb); 12738 sb.append(" used "); 12739 TimeUtils.formatDuration(wtimeUsed, sb); 12740 sb.append(" ("); 12741 sb.append((wtimeUsed*100)/realtimeSince); 12742 sb.append("%)"); 12743 Slog.i(TAG, sb.toString()); 12744 sb.setLength(0); 12745 sb.append("CPU for "); 12746 app.toShortString(sb); 12747 sb.append(": over "); 12748 TimeUtils.formatDuration(uptimeSince, sb); 12749 sb.append(" used "); 12750 TimeUtils.formatDuration(cputimeUsed, sb); 12751 sb.append(" ("); 12752 sb.append((cputimeUsed*100)/uptimeSince); 12753 sb.append("%)"); 12754 Slog.i(TAG, sb.toString()); 12755 } 12756 // If a process has held a wake lock for more 12757 // than 50% of the time during this period, 12758 // that sounds bad. Kill! 12759 if (doWakeKills && realtimeSince > 0 12760 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12761 synchronized (stats) { 12762 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12763 realtimeSince, wtimeUsed); 12764 } 12765 Slog.w(TAG, "Excessive wake lock in " + app.processName 12766 + " (pid " + app.pid + "): held " + wtimeUsed 12767 + " during " + realtimeSince); 12768 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12769 app.processName, app.setAdj, "excessive wake lock"); 12770 Process.killProcessQuiet(app.pid); 12771 } else if (doCpuKills && uptimeSince > 0 12772 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12773 synchronized (stats) { 12774 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12775 uptimeSince, cputimeUsed); 12776 } 12777 Slog.w(TAG, "Excessive CPU in " + app.processName 12778 + " (pid " + app.pid + "): used " + cputimeUsed 12779 + " during " + uptimeSince); 12780 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12781 app.processName, app.setAdj, "excessive cpu"); 12782 Process.killProcessQuiet(app.pid); 12783 } else { 12784 app.lastWakeTime = wtime; 12785 app.lastCpuTime = app.curCpuTime; 12786 } 12787 } 12788 } 12789 } 12790 12791 private final boolean updateOomAdjLocked( 12792 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 12793 app.hiddenAdj = hiddenAdj; 12794 12795 if (app.thread == null) { 12796 return false; 12797 } 12798 12799 final boolean wasKeeping = app.keeping; 12800 12801 boolean success = true; 12802 12803 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 12804 12805 if (app.curRawAdj != app.setRawAdj) { 12806 if (wasKeeping && !app.keeping) { 12807 // This app is no longer something we want to keep. Note 12808 // its current wake lock time to later know to kill it if 12809 // it is not behaving well. 12810 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12811 synchronized (stats) { 12812 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12813 app.pid, SystemClock.elapsedRealtime()); 12814 } 12815 app.lastCpuTime = app.curCpuTime; 12816 } 12817 12818 app.setRawAdj = app.curRawAdj; 12819 } 12820 12821 if (app.curAdj != app.setAdj) { 12822 if (Process.setOomAdj(app.pid, app.curAdj)) { 12823 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12824 TAG, "Set " + app.pid + " " + app.processName + 12825 " adj " + app.curAdj + ": " + app.adjType); 12826 app.setAdj = app.curAdj; 12827 } else { 12828 success = false; 12829 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12830 } 12831 } 12832 if (app.setSchedGroup != app.curSchedGroup) { 12833 app.setSchedGroup = app.curSchedGroup; 12834 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12835 "Setting process group of " + app.processName 12836 + " to " + app.curSchedGroup); 12837 if (app.waitingToKill != null && 12838 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12839 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12840 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12841 app.processName, app.setAdj, app.waitingToKill); 12842 app.killedBackground = true; 12843 Process.killProcessQuiet(app.pid); 12844 success = false; 12845 } else { 12846 if (true) { 12847 long oldId = Binder.clearCallingIdentity(); 12848 try { 12849 Process.setProcessGroup(app.pid, app.curSchedGroup); 12850 } catch (Exception e) { 12851 Slog.w(TAG, "Failed setting process group of " + app.pid 12852 + " to " + app.curSchedGroup); 12853 e.printStackTrace(); 12854 } finally { 12855 Binder.restoreCallingIdentity(oldId); 12856 } 12857 } else { 12858 if (app.thread != null) { 12859 try { 12860 app.thread.setSchedulingGroup(app.curSchedGroup); 12861 } catch (RemoteException e) { 12862 } 12863 } 12864 } 12865 } 12866 } 12867 return success; 12868 } 12869 12870 private final ActivityRecord resumedAppLocked() { 12871 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12872 if (resumedActivity == null || resumedActivity.app == null) { 12873 resumedActivity = mMainStack.mPausingActivity; 12874 if (resumedActivity == null || resumedActivity.app == null) { 12875 resumedActivity = mMainStack.topRunningActivityLocked(null); 12876 } 12877 } 12878 return resumedActivity; 12879 } 12880 12881 final boolean updateOomAdjLocked(ProcessRecord app) { 12882 final ActivityRecord TOP_ACT = resumedAppLocked(); 12883 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12884 int curAdj = app.curAdj; 12885 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12886 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12887 12888 mAdjSeq++; 12889 12890 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 12891 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12892 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12893 if (nowHidden != wasHidden) { 12894 // Changed to/from hidden state, so apps after it in the LRU 12895 // list may also be changed. 12896 updateOomAdjLocked(); 12897 } 12898 return success; 12899 } 12900 12901 final void updateOomAdjLocked() { 12902 final ActivityRecord TOP_ACT = resumedAppLocked(); 12903 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12904 12905 if (false) { 12906 RuntimeException e = new RuntimeException(); 12907 e.fillInStackTrace(); 12908 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12909 } 12910 12911 mAdjSeq++; 12912 mNewNumServiceProcs = 0; 12913 12914 // Let's determine how many processes we have running vs. 12915 // how many slots we have for background processes; we may want 12916 // to put multiple processes in a slot of there are enough of 12917 // them. 12918 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 12919 int factor = (mLruProcesses.size()-4)/numSlots; 12920 if (factor < 1) factor = 1; 12921 int step = 0; 12922 int numHidden = 0; 12923 int numTrimming = 0; 12924 12925 // First update the OOM adjustment for each of the 12926 // application processes based on their current state. 12927 int i = mLruProcesses.size(); 12928 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 12929 while (i > 0) { 12930 i--; 12931 ProcessRecord app = mLruProcesses.get(i); 12932 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 12933 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 12934 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 12935 && app.curAdj == curHiddenAdj) { 12936 step++; 12937 if (step >= factor) { 12938 step = 0; 12939 curHiddenAdj++; 12940 } 12941 } 12942 if (!app.killedBackground) { 12943 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12944 numHidden++; 12945 if (numHidden > mProcessLimit) { 12946 Slog.i(TAG, "No longer want " + app.processName 12947 + " (pid " + app.pid + "): hidden #" + numHidden); 12948 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12949 app.processName, app.setAdj, "too many background"); 12950 app.killedBackground = true; 12951 Process.killProcessQuiet(app.pid); 12952 } 12953 } 12954 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 12955 // If this is an isolated process, and there are no 12956 // services running in it, then the process is no longer 12957 // needed. We agressively kill these because we can by 12958 // definition not re-use the same process again, and it is 12959 // good to avoid having whatever code was running in them 12960 // left sitting around after no longer needed. 12961 Slog.i(TAG, "Isolated process " + app.processName 12962 + " (pid " + app.pid + ") no longer needed"); 12963 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12964 app.processName, app.setAdj, "isolated not needed"); 12965 app.killedBackground = true; 12966 Process.killProcessQuiet(app.pid); 12967 } 12968 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 12969 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 12970 && !app.killedBackground) { 12971 numTrimming++; 12972 } 12973 } 12974 } 12975 12976 mNumServiceProcs = mNewNumServiceProcs; 12977 12978 // Now determine the memory trimming level of background processes. 12979 // Unfortunately we need to start at the back of the list to do this 12980 // properly. We only do this if the number of background apps we 12981 // are managing to keep around is less than half the maximum we desire; 12982 // if we are keeping a good number around, we'll let them use whatever 12983 // memory they want. 12984 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 12985 final int N = mLruProcesses.size(); 12986 factor = numTrimming/3; 12987 int minFactor = 2; 12988 if (mHomeProcess != null) minFactor++; 12989 if (mPreviousProcess != null) minFactor++; 12990 if (factor < minFactor) factor = minFactor; 12991 step = 0; 12992 int fgTrimLevel; 12993 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 12994 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 12995 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 12996 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 12997 } else { 12998 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 12999 } 13000 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13001 for (i=0; i<N; i++) { 13002 ProcessRecord app = mLruProcesses.get(i); 13003 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13004 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13005 && !app.killedBackground) { 13006 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13007 try { 13008 app.thread.scheduleTrimMemory(curLevel); 13009 } catch (RemoteException e) { 13010 } 13011 if (false) { 13012 // For now we won't do this; our memory trimming seems 13013 // to be good enough at this point that destroying 13014 // activities causes more harm than good. 13015 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13016 && app != mHomeProcess && app != mPreviousProcess) { 13017 // Need to do this on its own message because the stack may not 13018 // be in a consistent state at this point. 13019 // For these apps we will also finish their activities 13020 // to help them free memory. 13021 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13022 } 13023 } 13024 } 13025 app.trimMemoryLevel = curLevel; 13026 step++; 13027 if (step >= factor) { 13028 step = 0; 13029 switch (curLevel) { 13030 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13031 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13032 break; 13033 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13034 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13035 break; 13036 } 13037 } 13038 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13039 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13040 && app.thread != null) { 13041 try { 13042 app.thread.scheduleTrimMemory( 13043 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13044 } catch (RemoteException e) { 13045 } 13046 } 13047 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13048 } else { 13049 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13050 && app.pendingUiClean) { 13051 // If this application is now in the background and it 13052 // had done UI, then give it the special trim level to 13053 // have it free UI resources. 13054 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13055 if (app.trimMemoryLevel < level && app.thread != null) { 13056 try { 13057 app.thread.scheduleTrimMemory(level); 13058 } catch (RemoteException e) { 13059 } 13060 } 13061 app.pendingUiClean = false; 13062 } 13063 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13064 try { 13065 app.thread.scheduleTrimMemory(fgTrimLevel); 13066 } catch (RemoteException e) { 13067 } 13068 } 13069 app.trimMemoryLevel = fgTrimLevel; 13070 } 13071 } 13072 } else { 13073 final int N = mLruProcesses.size(); 13074 for (i=0; i<N; i++) { 13075 ProcessRecord app = mLruProcesses.get(i); 13076 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13077 && app.pendingUiClean) { 13078 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13079 && app.thread != null) { 13080 try { 13081 app.thread.scheduleTrimMemory( 13082 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13083 } catch (RemoteException e) { 13084 } 13085 } 13086 app.pendingUiClean = false; 13087 } 13088 app.trimMemoryLevel = 0; 13089 } 13090 } 13091 13092 if (mAlwaysFinishActivities) { 13093 // Need to do this on its own message because the stack may not 13094 // be in a consistent state at this point. 13095 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13096 } 13097 } 13098 13099 final void trimApplications() { 13100 synchronized (this) { 13101 int i; 13102 13103 // First remove any unused application processes whose package 13104 // has been removed. 13105 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13106 final ProcessRecord app = mRemovedProcesses.get(i); 13107 if (app.activities.size() == 0 13108 && app.curReceiver == null && app.services.size() == 0) { 13109 Slog.i( 13110 TAG, "Exiting empty application process " 13111 + app.processName + " (" 13112 + (app.thread != null ? app.thread.asBinder() : null) 13113 + ")\n"); 13114 if (app.pid > 0 && app.pid != MY_PID) { 13115 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13116 app.processName, app.setAdj, "empty"); 13117 Process.killProcessQuiet(app.pid); 13118 } else { 13119 try { 13120 app.thread.scheduleExit(); 13121 } catch (Exception e) { 13122 // Ignore exceptions. 13123 } 13124 } 13125 cleanUpApplicationRecordLocked(app, false, true, -1); 13126 mRemovedProcesses.remove(i); 13127 13128 if (app.persistent) { 13129 if (app.persistent) { 13130 addAppLocked(app.info, false); 13131 } 13132 } 13133 } 13134 } 13135 13136 // Now update the oom adj for all processes. 13137 updateOomAdjLocked(); 13138 } 13139 } 13140 13141 /** This method sends the specified signal to each of the persistent apps */ 13142 public void signalPersistentProcesses(int sig) throws RemoteException { 13143 if (sig != Process.SIGNAL_USR1) { 13144 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13145 } 13146 13147 synchronized (this) { 13148 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13149 != PackageManager.PERMISSION_GRANTED) { 13150 throw new SecurityException("Requires permission " 13151 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13152 } 13153 13154 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13155 ProcessRecord r = mLruProcesses.get(i); 13156 if (r.thread != null && r.persistent) { 13157 Process.sendSignal(r.pid, sig); 13158 } 13159 } 13160 } 13161 } 13162 13163 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13164 if (proc == null || proc == mProfileProc) { 13165 proc = mProfileProc; 13166 path = mProfileFile; 13167 profileType = mProfileType; 13168 clearProfilerLocked(); 13169 } 13170 if (proc == null) { 13171 return; 13172 } 13173 try { 13174 proc.thread.profilerControl(false, path, null, profileType); 13175 } catch (RemoteException e) { 13176 throw new IllegalStateException("Process disappeared"); 13177 } 13178 } 13179 13180 private void clearProfilerLocked() { 13181 if (mProfileFd != null) { 13182 try { 13183 mProfileFd.close(); 13184 } catch (IOException e) { 13185 } 13186 } 13187 mProfileApp = null; 13188 mProfileProc = null; 13189 mProfileFile = null; 13190 mProfileType = 0; 13191 mAutoStopProfiler = false; 13192 } 13193 13194 public boolean profileControl(String process, boolean start, 13195 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13196 13197 try { 13198 synchronized (this) { 13199 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13200 // its own permission. 13201 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13202 != PackageManager.PERMISSION_GRANTED) { 13203 throw new SecurityException("Requires permission " 13204 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13205 } 13206 13207 if (start && fd == null) { 13208 throw new IllegalArgumentException("null fd"); 13209 } 13210 13211 ProcessRecord proc = null; 13212 if (process != null) { 13213 try { 13214 int pid = Integer.parseInt(process); 13215 synchronized (mPidsSelfLocked) { 13216 proc = mPidsSelfLocked.get(pid); 13217 } 13218 } catch (NumberFormatException e) { 13219 } 13220 13221 if (proc == null) { 13222 HashMap<String, SparseArray<ProcessRecord>> all 13223 = mProcessNames.getMap(); 13224 SparseArray<ProcessRecord> procs = all.get(process); 13225 if (procs != null && procs.size() > 0) { 13226 proc = procs.valueAt(0); 13227 } 13228 } 13229 } 13230 13231 if (start && (proc == null || proc.thread == null)) { 13232 throw new IllegalArgumentException("Unknown process: " + process); 13233 } 13234 13235 if (start) { 13236 stopProfilerLocked(null, null, 0); 13237 setProfileApp(proc.info, proc.processName, path, fd, false); 13238 mProfileProc = proc; 13239 mProfileType = profileType; 13240 try { 13241 fd = fd.dup(); 13242 } catch (IOException e) { 13243 fd = null; 13244 } 13245 proc.thread.profilerControl(start, path, fd, profileType); 13246 fd = null; 13247 mProfileFd = null; 13248 } else { 13249 stopProfilerLocked(proc, path, profileType); 13250 if (fd != null) { 13251 try { 13252 fd.close(); 13253 } catch (IOException e) { 13254 } 13255 } 13256 } 13257 13258 return true; 13259 } 13260 } catch (RemoteException e) { 13261 throw new IllegalStateException("Process disappeared"); 13262 } finally { 13263 if (fd != null) { 13264 try { 13265 fd.close(); 13266 } catch (IOException e) { 13267 } 13268 } 13269 } 13270 } 13271 13272 public boolean dumpHeap(String process, boolean managed, 13273 String path, ParcelFileDescriptor fd) throws RemoteException { 13274 13275 try { 13276 synchronized (this) { 13277 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13278 // its own permission (same as profileControl). 13279 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13280 != PackageManager.PERMISSION_GRANTED) { 13281 throw new SecurityException("Requires permission " 13282 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13283 } 13284 13285 if (fd == null) { 13286 throw new IllegalArgumentException("null fd"); 13287 } 13288 13289 ProcessRecord proc = null; 13290 try { 13291 int pid = Integer.parseInt(process); 13292 synchronized (mPidsSelfLocked) { 13293 proc = mPidsSelfLocked.get(pid); 13294 } 13295 } catch (NumberFormatException e) { 13296 } 13297 13298 if (proc == null) { 13299 HashMap<String, SparseArray<ProcessRecord>> all 13300 = mProcessNames.getMap(); 13301 SparseArray<ProcessRecord> procs = all.get(process); 13302 if (procs != null && procs.size() > 0) { 13303 proc = procs.valueAt(0); 13304 } 13305 } 13306 13307 if (proc == null || proc.thread == null) { 13308 throw new IllegalArgumentException("Unknown process: " + process); 13309 } 13310 13311 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13312 if (!isDebuggable) { 13313 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13314 throw new SecurityException("Process not debuggable: " + proc); 13315 } 13316 } 13317 13318 proc.thread.dumpHeap(managed, path, fd); 13319 fd = null; 13320 return true; 13321 } 13322 } catch (RemoteException e) { 13323 throw new IllegalStateException("Process disappeared"); 13324 } finally { 13325 if (fd != null) { 13326 try { 13327 fd.close(); 13328 } catch (IOException e) { 13329 } 13330 } 13331 } 13332 } 13333 13334 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13335 public void monitor() { 13336 synchronized (this) { } 13337 } 13338 13339 void onCoreSettingsChange(Bundle settings) { 13340 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13341 ProcessRecord processRecord = mLruProcesses.get(i); 13342 try { 13343 if (processRecord.thread != null) { 13344 processRecord.thread.setCoreSettings(settings); 13345 } 13346 } catch (RemoteException re) { 13347 /* ignore */ 13348 } 13349 } 13350 } 13351 13352 // Multi-user methods 13353 13354 private int mCurrentUserId; 13355 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 13356 13357 public boolean switchUser(int userId) { 13358 final int callingUid = Binder.getCallingUid(); 13359 if (callingUid != 0 && callingUid != Process.myUid()) { 13360 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13361 return false; 13362 } 13363 if (mCurrentUserId == userId) 13364 return true; 13365 13366 synchronized (this) { 13367 // Check if user is already logged in, otherwise check if user exists first before 13368 // adding to the list of logged in users. 13369 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13370 if (!userExists(userId)) { 13371 return false; 13372 } 13373 mLoggedInUsers.append(userId, userId); 13374 } 13375 13376 mCurrentUserId = userId; 13377 boolean haveActivities = mMainStack.switchUser(userId); 13378 if (!haveActivities) { 13379 startHomeActivityLocked(userId); 13380 } 13381 13382 } 13383 13384 // Inform of user switch 13385 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13386 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 13387 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 13388 13389 return true; 13390 } 13391 13392 @Override 13393 public UserInfo getCurrentUser() throws RemoteException { 13394 final int callingUid = Binder.getCallingUid(); 13395 if (callingUid != 0 && callingUid != Process.myUid()) { 13396 Slog.e(TAG, "Trying to get user from unauthorized app"); 13397 return null; 13398 } 13399 return AppGlobals.getPackageManager().getUser(mCurrentUserId); 13400 } 13401 13402 private void onUserRemoved(Intent intent) { 13403 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 13404 if (extraUserId < 1) return; 13405 13406 // Kill all the processes for the user 13407 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13408 synchronized (this) { 13409 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13410 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13411 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13412 for (int i = 0; i < uids.size(); i++) { 13413 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 13414 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13415 } 13416 } 13417 } 13418 13419 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13420 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13421 false, false, true, true, extraUserId); 13422 } 13423 } 13424 } 13425 13426 private boolean userExists(int userId) { 13427 try { 13428 UserInfo user = AppGlobals.getPackageManager().getUser(userId); 13429 return user != null; 13430 } catch (RemoteException re) { 13431 // Won't happen, in same process 13432 } 13433 13434 return false; 13435 } 13436 13437 private void checkValidCaller(int uid, int userId) { 13438 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13439 13440 throw new SecurityException("Caller uid=" + uid 13441 + " is not privileged to communicate with user=" + userId); 13442 } 13443 13444 private int applyUserId(int uid, int userId) { 13445 return UserId.getUid(userId, uid); 13446 } 13447 13448 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13449 if (info == null) return null; 13450 ApplicationInfo newInfo = new ApplicationInfo(info); 13451 newInfo.uid = applyUserId(info.uid, userId); 13452 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13453 + info.packageName; 13454 return newInfo; 13455 } 13456 13457 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13458 if (aInfo == null 13459 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 13460 return aInfo; 13461 } 13462 13463 ActivityInfo info = new ActivityInfo(aInfo); 13464 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13465 return info; 13466 } 13467} 13468