ActivityManagerService.java revision f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IThumbnailReceiver; 51import android.app.Instrumentation; 52import android.app.Notification; 53import android.app.NotificationManager; 54import android.app.PendingIntent; 55import android.app.Service; 56import android.app.backup.IBackupManager; 57import android.content.ActivityNotFoundException; 58import android.content.BroadcastReceiver; 59import android.content.ClipData; 60import android.content.ComponentCallbacks2; 61import android.content.ComponentName; 62import android.content.ContentProvider; 63import android.content.ContentResolver; 64import android.content.Context; 65import android.content.DialogInterface; 66import android.content.IContentProvider; 67import android.content.IIntentReceiver; 68import android.content.IIntentSender; 69import android.content.Intent; 70import android.content.IntentFilter; 71import android.content.IntentSender; 72import android.content.pm.ActivityInfo; 73import android.content.pm.ApplicationInfo; 74import android.content.pm.ConfigurationInfo; 75import android.content.pm.IPackageDataObserver; 76import android.content.pm.IPackageManager; 77import android.content.pm.InstrumentationInfo; 78import android.content.pm.PackageInfo; 79import android.content.pm.PackageManager; 80import android.content.pm.UserInfo; 81import android.content.pm.PackageManager.NameNotFoundException; 82import android.content.pm.PathPermission; 83import android.content.pm.ProviderInfo; 84import android.content.pm.ResolveInfo; 85import android.content.pm.ServiceInfo; 86import android.content.res.CompatibilityInfo; 87import android.content.res.Configuration; 88import android.graphics.Bitmap; 89import android.net.Proxy; 90import android.net.ProxyProperties; 91import android.net.Uri; 92import android.os.Binder; 93import android.os.Build; 94import android.os.Bundle; 95import android.os.Debug; 96import android.os.DropBoxManager; 97import android.os.Environment; 98import android.os.FileObserver; 99import android.os.FileUtils; 100import android.os.Handler; 101import android.os.IBinder; 102import android.os.IPermissionController; 103import android.os.Looper; 104import android.os.Message; 105import android.os.Parcel; 106import android.os.ParcelFileDescriptor; 107import android.os.Process; 108import android.os.RemoteCallbackList; 109import android.os.RemoteException; 110import android.os.ServiceManager; 111import android.os.StrictMode; 112import android.os.SystemClock; 113import android.os.SystemProperties; 114import android.os.UserHandle; 115import android.os.UserManager; 116import android.provider.Settings; 117import android.text.format.Time; 118import android.util.EventLog; 119import android.util.Log; 120import android.util.Pair; 121import android.util.PrintWriterPrinter; 122import android.util.Slog; 123import android.util.SparseArray; 124import android.util.SparseIntArray; 125import android.util.TimeUtils; 126import android.view.Gravity; 127import android.view.LayoutInflater; 128import android.view.View; 129import android.view.WindowManager; 130import android.view.WindowManagerPolicy; 131 132import java.io.BufferedInputStream; 133import java.io.BufferedOutputStream; 134import java.io.BufferedReader; 135import java.io.DataInputStream; 136import java.io.DataOutputStream; 137import java.io.File; 138import java.io.FileDescriptor; 139import java.io.FileInputStream; 140import java.io.FileNotFoundException; 141import java.io.FileOutputStream; 142import java.io.IOException; 143import java.io.InputStreamReader; 144import java.io.PrintWriter; 145import java.io.StringWriter; 146import java.lang.ref.WeakReference; 147import java.util.ArrayList; 148import java.util.Collection; 149import java.util.Collections; 150import java.util.Comparator; 151import java.util.HashMap; 152import java.util.HashSet; 153import java.util.Iterator; 154import java.util.List; 155import java.util.Locale; 156import java.util.Map; 157import java.util.Map.Entry; 158import java.util.Set; 159import java.util.concurrent.atomic.AtomicBoolean; 160import java.util.concurrent.atomic.AtomicLong; 161 162public final class ActivityManagerService extends ActivityManagerNative 163 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 164 private static final String USER_DATA_DIR = "/data/user/"; 165 static final String TAG = "ActivityManager"; 166 static final String TAG_MU = "ActivityManagerServiceMU"; 167 static final boolean DEBUG = false; 168 static final boolean localLOGV = DEBUG; 169 static final boolean DEBUG_SWITCH = localLOGV || false; 170 static final boolean DEBUG_TASKS = localLOGV || false; 171 static final boolean DEBUG_PAUSE = localLOGV || false; 172 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 173 static final boolean DEBUG_TRANSITION = localLOGV || false; 174 static final boolean DEBUG_BROADCAST = localLOGV || false; 175 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 177 static final boolean DEBUG_SERVICE = localLOGV || false; 178 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 179 static final boolean DEBUG_VISBILITY = localLOGV || false; 180 static final boolean DEBUG_PROCESSES = localLOGV || false; 181 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 182 static final boolean DEBUG_PROVIDER = localLOGV || false; 183 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 184 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 185 static final boolean DEBUG_RESULTS = localLOGV || false; 186 static final boolean DEBUG_BACKUP = localLOGV || false; 187 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 188 static final boolean DEBUG_POWER = localLOGV || false; 189 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 190 static final boolean DEBUG_MU = localLOGV || false; 191 static final boolean VALIDATE_TOKENS = false; 192 static final boolean SHOW_ACTIVITY_START_TIME = true; 193 194 // Control over CPU and battery monitoring. 195 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 196 static final boolean MONITOR_CPU_USAGE = true; 197 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 198 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 199 static final boolean MONITOR_THREAD_CPU_USAGE = false; 200 201 // The flags that are set for all calls we make to the package manager. 202 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 203 204 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 205 206 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 207 208 // Maximum number of recent tasks that we can remember. 209 static final int MAX_RECENT_TASKS = 20; 210 211 // Amount of time after a call to stopAppSwitches() during which we will 212 // prevent further untrusted switches from happening. 213 static final long APP_SWITCH_DELAY_TIME = 5*1000; 214 215 // How long we wait for a launched process to attach to the activity manager 216 // before we decide it's never going to come up for real. 217 static final int PROC_START_TIMEOUT = 10*1000; 218 219 // How long we wait for a launched process to attach to the activity manager 220 // before we decide it's never going to come up for real, when the process was 221 // started with a wrapper for instrumentation (such as Valgrind) because it 222 // could take much longer than usual. 223 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 224 225 // How long to wait after going idle before forcing apps to GC. 226 static final int GC_TIMEOUT = 5*1000; 227 228 // The minimum amount of time between successive GC requests for a process. 229 static final int GC_MIN_INTERVAL = 60*1000; 230 231 // The rate at which we check for apps using excessive power -- 15 mins. 232 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 233 234 // The minimum sample duration we will allow before deciding we have 235 // enough data on wake locks to start killing things. 236 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 237 238 // The minimum sample duration we will allow before deciding we have 239 // enough data on CPU usage to start killing things. 240 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 241 242 // How long we allow a receiver to run before giving up on it. 243 static final int BROADCAST_FG_TIMEOUT = 10*1000; 244 static final int BROADCAST_BG_TIMEOUT = 60*1000; 245 246 // How long we wait until we timeout on key dispatching. 247 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 248 249 // How long we wait until we timeout on key dispatching during instrumentation. 250 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 251 252 static final int MY_PID = Process.myPid(); 253 254 static final String[] EMPTY_STRING_ARRAY = new String[0]; 255 256 public ActivityStack mMainStack; 257 258 private final boolean mHeadless; 259 260 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 261 // default actuion automatically. Important for devices without direct input 262 // devices. 263 private boolean mShowDialogs = true; 264 265 /** 266 * Description of a request to start a new activity, which has been held 267 * due to app switches being disabled. 268 */ 269 static class PendingActivityLaunch { 270 ActivityRecord r; 271 ActivityRecord sourceRecord; 272 int startFlags; 273 } 274 275 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 276 = new ArrayList<PendingActivityLaunch>(); 277 278 279 BroadcastQueue mFgBroadcastQueue; 280 BroadcastQueue mBgBroadcastQueue; 281 // Convenient for easy iteration over the queues. Foreground is first 282 // so that dispatch of foreground broadcasts gets precedence. 283 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 284 285 BroadcastQueue broadcastQueueForIntent(Intent intent) { 286 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 287 if (DEBUG_BACKGROUND_BROADCAST) { 288 Slog.i(TAG, "Broadcast intent " + intent + " on " 289 + (isFg ? "foreground" : "background") 290 + " queue"); 291 } 292 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 293 } 294 295 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 296 for (BroadcastQueue queue : mBroadcastQueues) { 297 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 298 if (r != null) { 299 return r; 300 } 301 } 302 return null; 303 } 304 305 /** 306 * Activity we have told the window manager to have key focus. 307 */ 308 ActivityRecord mFocusedActivity = null; 309 /** 310 * List of intents that were used to start the most recent tasks. 311 */ 312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 313 314 /** 315 * Process management. 316 */ 317 final ProcessList mProcessList = new ProcessList(); 318 319 /** 320 * All of the applications we currently have running organized by name. 321 * The keys are strings of the application package name (as 322 * returned by the package manager), and the keys are ApplicationRecord 323 * objects. 324 */ 325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 326 327 /** 328 * The currently running isolated processes. 329 */ 330 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 331 332 /** 333 * Counter for assigning isolated process uids, to avoid frequently reusing the 334 * same ones. 335 */ 336 int mNextIsolatedProcessUid = 0; 337 338 /** 339 * The currently running heavy-weight process, if any. 340 */ 341 ProcessRecord mHeavyWeightProcess = null; 342 343 /** 344 * The last time that various processes have crashed. 345 */ 346 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 347 348 /** 349 * Set of applications that we consider to be bad, and will reject 350 * incoming broadcasts from (which the user has no control over). 351 * Processes are added to this set when they have crashed twice within 352 * a minimum amount of time; they are removed from it when they are 353 * later restarted (hopefully due to some user action). The value is the 354 * time it was added to the list. 355 */ 356 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 357 358 /** 359 * All of the processes we currently have running organized by pid. 360 * The keys are the pid running the application. 361 * 362 * <p>NOTE: This object is protected by its own lock, NOT the global 363 * activity manager lock! 364 */ 365 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 366 367 /** 368 * All of the processes that have been forced to be foreground. The key 369 * is the pid of the caller who requested it (we hold a death 370 * link on it). 371 */ 372 abstract class ForegroundToken implements IBinder.DeathRecipient { 373 int pid; 374 IBinder token; 375 } 376 final SparseArray<ForegroundToken> mForegroundProcesses 377 = new SparseArray<ForegroundToken>(); 378 379 /** 380 * List of records for processes that someone had tried to start before the 381 * system was ready. We don't start them at that point, but ensure they 382 * are started by the time booting is complete. 383 */ 384 final ArrayList<ProcessRecord> mProcessesOnHold 385 = new ArrayList<ProcessRecord>(); 386 387 /** 388 * List of persistent applications that are in the process 389 * of being started. 390 */ 391 final ArrayList<ProcessRecord> mPersistentStartingProcesses 392 = new ArrayList<ProcessRecord>(); 393 394 /** 395 * Processes that are being forcibly torn down. 396 */ 397 final ArrayList<ProcessRecord> mRemovedProcesses 398 = new ArrayList<ProcessRecord>(); 399 400 /** 401 * List of running applications, sorted by recent usage. 402 * The first entry in the list is the least recently used. 403 * It contains ApplicationRecord objects. This list does NOT include 404 * any persistent application records (since we never want to exit them). 405 */ 406 final ArrayList<ProcessRecord> mLruProcesses 407 = new ArrayList<ProcessRecord>(); 408 409 /** 410 * List of processes that should gc as soon as things are idle. 411 */ 412 final ArrayList<ProcessRecord> mProcessesToGc 413 = new ArrayList<ProcessRecord>(); 414 415 /** 416 * This is the process holding what we currently consider to be 417 * the "home" activity. 418 */ 419 ProcessRecord mHomeProcess; 420 421 /** 422 * This is the process holding the activity the user last visited that 423 * is in a different process from the one they are currently in. 424 */ 425 ProcessRecord mPreviousProcess; 426 427 /** 428 * The time at which the previous process was last visible. 429 */ 430 long mPreviousProcessVisibleTime; 431 432 /** 433 * Packages that the user has asked to have run in screen size 434 * compatibility mode instead of filling the screen. 435 */ 436 final CompatModePackages mCompatModePackages; 437 438 /** 439 * Set of PendingResultRecord objects that are currently active. 440 */ 441 final HashSet mPendingResultRecords = new HashSet(); 442 443 /** 444 * Set of IntentSenderRecord objects that are currently active. 445 */ 446 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 447 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 448 449 /** 450 * Fingerprints (hashCode()) of stack traces that we've 451 * already logged DropBox entries for. Guarded by itself. If 452 * something (rogue user app) forces this over 453 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 454 */ 455 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 456 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 457 458 /** 459 * Strict Mode background batched logging state. 460 * 461 * The string buffer is guarded by itself, and its lock is also 462 * used to determine if another batched write is already 463 * in-flight. 464 */ 465 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 466 467 /** 468 * Keeps track of all IIntentReceivers that have been registered for 469 * broadcasts. Hash keys are the receiver IBinder, hash value is 470 * a ReceiverList. 471 */ 472 final HashMap mRegisteredReceivers = new HashMap(); 473 474 /** 475 * Resolver for broadcast intents to registered receivers. 476 * Holds BroadcastFilter (subclass of IntentFilter). 477 */ 478 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 479 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 480 @Override 481 protected boolean allowFilterResult( 482 BroadcastFilter filter, List<BroadcastFilter> dest) { 483 IBinder target = filter.receiverList.receiver.asBinder(); 484 for (int i=dest.size()-1; i>=0; i--) { 485 if (dest.get(i).receiverList.receiver.asBinder() == target) { 486 return false; 487 } 488 } 489 return true; 490 } 491 492 @Override 493 protected BroadcastFilter[] newArray(int size) { 494 return new BroadcastFilter[size]; 495 } 496 497 @Override 498 protected String packageForFilter(BroadcastFilter filter) { 499 return filter.packageName; 500 } 501 }; 502 503 /** 504 * State of all active sticky broadcasts. Keys are the action of the 505 * sticky Intent, values are an ArrayList of all broadcasted intents with 506 * that action (which should usually be one). 507 */ 508 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 509 new HashMap<String, ArrayList<Intent>>(); 510 511 final ActiveServices mServices; 512 513 /** 514 * Backup/restore process management 515 */ 516 String mBackupAppName = null; 517 BackupRecord mBackupTarget = null; 518 519 /** 520 * List of PendingThumbnailsRecord objects of clients who are still 521 * waiting to receive all of the thumbnails for a task. 522 */ 523 final ArrayList mPendingThumbnails = new ArrayList(); 524 525 /** 526 * List of HistoryRecord objects that have been finished and must 527 * still report back to a pending thumbnail receiver. 528 */ 529 final ArrayList mCancelledThumbnails = new ArrayList(); 530 531 final ProviderMap mProviderMap = new ProviderMap(); 532 533 /** 534 * List of content providers who have clients waiting for them. The 535 * application is currently being launched and the provider will be 536 * removed from this list once it is published. 537 */ 538 final ArrayList<ContentProviderRecord> mLaunchingProviders 539 = new ArrayList<ContentProviderRecord>(); 540 541 /** 542 * Global set of specific Uri permissions that have been granted. 543 */ 544 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 545 = new SparseArray<HashMap<Uri, UriPermission>>(); 546 547 CoreSettingsObserver mCoreSettingsObserver; 548 549 /** 550 * Thread-local storage used to carry caller permissions over through 551 * indirect content-provider access. 552 * @see #ActivityManagerService.openContentUri() 553 */ 554 private class Identity { 555 public int pid; 556 public int uid; 557 558 Identity(int _pid, int _uid) { 559 pid = _pid; 560 uid = _uid; 561 } 562 } 563 564 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 565 566 /** 567 * All information we have collected about the runtime performance of 568 * any user id that can impact battery performance. 569 */ 570 final BatteryStatsService mBatteryStatsService; 571 572 /** 573 * information about component usage 574 */ 575 final UsageStatsService mUsageStatsService; 576 577 /** 578 * Current configuration information. HistoryRecord objects are given 579 * a reference to this object to indicate which configuration they are 580 * currently running in, so this object must be kept immutable. 581 */ 582 Configuration mConfiguration = new Configuration(); 583 584 /** 585 * Current sequencing integer of the configuration, for skipping old 586 * configurations. 587 */ 588 int mConfigurationSeq = 0; 589 590 /** 591 * Hardware-reported OpenGLES version. 592 */ 593 final int GL_ES_VERSION; 594 595 /** 596 * List of initialization arguments to pass to all processes when binding applications to them. 597 * For example, references to the commonly used services. 598 */ 599 HashMap<String, IBinder> mAppBindArgs; 600 601 /** 602 * Temporary to avoid allocations. Protected by main lock. 603 */ 604 final StringBuilder mStringBuilder = new StringBuilder(256); 605 606 /** 607 * Used to control how we initialize the service. 608 */ 609 boolean mStartRunning = false; 610 ComponentName mTopComponent; 611 String mTopAction; 612 String mTopData; 613 boolean mProcessesReady = false; 614 boolean mSystemReady = false; 615 boolean mBooting = false; 616 boolean mWaitingUpdate = false; 617 boolean mDidUpdate = false; 618 boolean mOnBattery = false; 619 boolean mLaunchWarningShown = false; 620 621 Context mContext; 622 623 int mFactoryTest; 624 625 boolean mCheckedForSetup; 626 627 /** 628 * The time at which we will allow normal application switches again, 629 * after a call to {@link #stopAppSwitches()}. 630 */ 631 long mAppSwitchesAllowedTime; 632 633 /** 634 * This is set to true after the first switch after mAppSwitchesAllowedTime 635 * is set; any switches after that will clear the time. 636 */ 637 boolean mDidAppSwitch; 638 639 /** 640 * Last time (in realtime) at which we checked for power usage. 641 */ 642 long mLastPowerCheckRealtime; 643 644 /** 645 * Last time (in uptime) at which we checked for power usage. 646 */ 647 long mLastPowerCheckUptime; 648 649 /** 650 * Set while we are wanting to sleep, to prevent any 651 * activities from being started/resumed. 652 */ 653 boolean mSleeping = false; 654 655 /** 656 * State of external calls telling us if the device is asleep. 657 */ 658 boolean mWentToSleep = false; 659 660 /** 661 * State of external call telling us if the lock screen is shown. 662 */ 663 boolean mLockScreenShown = false; 664 665 /** 666 * Set if we are shutting down the system, similar to sleeping. 667 */ 668 boolean mShuttingDown = false; 669 670 /** 671 * Task identifier that activities are currently being started 672 * in. Incremented each time a new task is created. 673 * todo: Replace this with a TokenSpace class that generates non-repeating 674 * integers that won't wrap. 675 */ 676 int mCurTask = 1; 677 678 /** 679 * Current sequence id for oom_adj computation traversal. 680 */ 681 int mAdjSeq = 0; 682 683 /** 684 * Current sequence id for process LRU updating. 685 */ 686 int mLruSeq = 0; 687 688 /** 689 * Keep track of the non-hidden/empty process we last found, to help 690 * determine how to distribute hidden/empty processes next time. 691 */ 692 int mNumNonHiddenProcs = 0; 693 694 /** 695 * Keep track of the number of hidden procs, to balance oom adj 696 * distribution between those and empty procs. 697 */ 698 int mNumHiddenProcs = 0; 699 700 /** 701 * Keep track of the number of service processes we last found, to 702 * determine on the next iteration which should be B services. 703 */ 704 int mNumServiceProcs = 0; 705 int mNewNumServiceProcs = 0; 706 707 /** 708 * System monitoring: number of processes that died since the last 709 * N procs were started. 710 */ 711 int[] mProcDeaths = new int[20]; 712 713 /** 714 * This is set if we had to do a delayed dexopt of an app before launching 715 * it, to increasing the ANR timeouts in that case. 716 */ 717 boolean mDidDexOpt; 718 719 String mDebugApp = null; 720 boolean mWaitForDebugger = false; 721 boolean mDebugTransient = false; 722 String mOrigDebugApp = null; 723 boolean mOrigWaitForDebugger = false; 724 boolean mAlwaysFinishActivities = false; 725 IActivityController mController = null; 726 String mProfileApp = null; 727 ProcessRecord mProfileProc = null; 728 String mProfileFile; 729 ParcelFileDescriptor mProfileFd; 730 int mProfileType = 0; 731 boolean mAutoStopProfiler = false; 732 String mOpenGlTraceApp = null; 733 734 static class ProcessChangeItem { 735 static final int CHANGE_ACTIVITIES = 1<<0; 736 static final int CHANGE_IMPORTANCE= 1<<1; 737 int changes; 738 int uid; 739 int pid; 740 int importance; 741 boolean foregroundActivities; 742 } 743 744 final RemoteCallbackList<IProcessObserver> mProcessObservers 745 = new RemoteCallbackList<IProcessObserver>(); 746 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 747 748 final ArrayList<ProcessChangeItem> mPendingProcessChanges 749 = new ArrayList<ProcessChangeItem>(); 750 final ArrayList<ProcessChangeItem> mAvailProcessChanges 751 = new ArrayList<ProcessChangeItem>(); 752 753 /** 754 * Callback of last caller to {@link #requestPss}. 755 */ 756 Runnable mRequestPssCallback; 757 758 /** 759 * Remaining processes for which we are waiting results from the last 760 * call to {@link #requestPss}. 761 */ 762 final ArrayList<ProcessRecord> mRequestPssList 763 = new ArrayList<ProcessRecord>(); 764 765 /** 766 * Runtime statistics collection thread. This object's lock is used to 767 * protect all related state. 768 */ 769 final Thread mProcessStatsThread; 770 771 /** 772 * Used to collect process stats when showing not responding dialog. 773 * Protected by mProcessStatsThread. 774 */ 775 final ProcessStats mProcessStats = new ProcessStats( 776 MONITOR_THREAD_CPU_USAGE); 777 final AtomicLong mLastCpuTime = new AtomicLong(0); 778 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 779 780 long mLastWriteTime = 0; 781 782 /** 783 * Set to true after the system has finished booting. 784 */ 785 boolean mBooted = false; 786 787 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 788 int mProcessLimitOverride = -1; 789 790 WindowManagerService mWindowManager; 791 792 static ActivityManagerService mSelf; 793 static ActivityThread mSystemThread; 794 795 private int mCurrentUserId; 796 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 797 private UserManager mUserManager; 798 799 private final class AppDeathRecipient implements IBinder.DeathRecipient { 800 final ProcessRecord mApp; 801 final int mPid; 802 final IApplicationThread mAppThread; 803 804 AppDeathRecipient(ProcessRecord app, int pid, 805 IApplicationThread thread) { 806 if (localLOGV) Slog.v( 807 TAG, "New death recipient " + this 808 + " for thread " + thread.asBinder()); 809 mApp = app; 810 mPid = pid; 811 mAppThread = thread; 812 } 813 814 public void binderDied() { 815 if (localLOGV) Slog.v( 816 TAG, "Death received in " + this 817 + " for thread " + mAppThread.asBinder()); 818 synchronized(ActivityManagerService.this) { 819 appDiedLocked(mApp, mPid, mAppThread); 820 } 821 } 822 } 823 824 static final int SHOW_ERROR_MSG = 1; 825 static final int SHOW_NOT_RESPONDING_MSG = 2; 826 static final int SHOW_FACTORY_ERROR_MSG = 3; 827 static final int UPDATE_CONFIGURATION_MSG = 4; 828 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 829 static final int WAIT_FOR_DEBUGGER_MSG = 6; 830 static final int SERVICE_TIMEOUT_MSG = 12; 831 static final int UPDATE_TIME_ZONE = 13; 832 static final int SHOW_UID_ERROR_MSG = 14; 833 static final int IM_FEELING_LUCKY_MSG = 15; 834 static final int PROC_START_TIMEOUT_MSG = 20; 835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 836 static final int KILL_APPLICATION_MSG = 22; 837 static final int FINALIZE_PENDING_INTENT_MSG = 23; 838 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 842 static final int CLEAR_DNS_CACHE = 28; 843 static final int UPDATE_HTTP_PROXY = 29; 844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 845 static final int DISPATCH_PROCESSES_CHANGED = 31; 846 static final int DISPATCH_PROCESS_DIED = 32; 847 static final int REPORT_MEM_USAGE = 33; 848 849 static final int FIRST_ACTIVITY_STACK_MSG = 100; 850 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 851 static final int FIRST_COMPAT_MODE_MSG = 300; 852 853 AlertDialog mUidAlert; 854 CompatModeDialog mCompatModeDialog; 855 long mLastMemUsageReportTime = 0; 856 857 final Handler mHandler = new Handler() { 858 //public Handler() { 859 // if (localLOGV) Slog.v(TAG, "Handler started!"); 860 //} 861 862 public void handleMessage(Message msg) { 863 switch (msg.what) { 864 case SHOW_ERROR_MSG: { 865 HashMap data = (HashMap) msg.obj; 866 synchronized (ActivityManagerService.this) { 867 ProcessRecord proc = (ProcessRecord)data.get("app"); 868 if (proc != null && proc.crashDialog != null) { 869 Slog.e(TAG, "App already has crash dialog: " + proc); 870 return; 871 } 872 AppErrorResult res = (AppErrorResult) data.get("result"); 873 if (mShowDialogs && !mSleeping && !mShuttingDown) { 874 Dialog d = new AppErrorDialog(mContext, res, proc); 875 d.show(); 876 proc.crashDialog = d; 877 } else { 878 // The device is asleep, so just pretend that the user 879 // saw a crash dialog and hit "force quit". 880 res.set(0); 881 } 882 } 883 884 ensureBootCompleted(); 885 } break; 886 case SHOW_NOT_RESPONDING_MSG: { 887 synchronized (ActivityManagerService.this) { 888 HashMap data = (HashMap) msg.obj; 889 ProcessRecord proc = (ProcessRecord)data.get("app"); 890 if (proc != null && proc.anrDialog != null) { 891 Slog.e(TAG, "App already has anr dialog: " + proc); 892 return; 893 } 894 895 Intent intent = new Intent("android.intent.action.ANR"); 896 if (!mProcessesReady) { 897 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 898 | Intent.FLAG_RECEIVER_FOREGROUND); 899 } 900 broadcastIntentLocked(null, null, intent, 901 null, null, 0, null, null, null, 902 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 903 904 if (mShowDialogs) { 905 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 906 mContext, proc, (ActivityRecord)data.get("activity")); 907 d.show(); 908 proc.anrDialog = d; 909 } else { 910 // Just kill the app if there is no dialog to be shown. 911 killAppAtUsersRequest(proc, null); 912 } 913 } 914 915 ensureBootCompleted(); 916 } break; 917 case SHOW_STRICT_MODE_VIOLATION_MSG: { 918 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 919 synchronized (ActivityManagerService.this) { 920 ProcessRecord proc = (ProcessRecord) data.get("app"); 921 if (proc == null) { 922 Slog.e(TAG, "App not found when showing strict mode dialog."); 923 break; 924 } 925 if (proc.crashDialog != null) { 926 Slog.e(TAG, "App already has strict mode dialog: " + proc); 927 return; 928 } 929 AppErrorResult res = (AppErrorResult) data.get("result"); 930 if (mShowDialogs && !mSleeping && !mShuttingDown) { 931 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 932 d.show(); 933 proc.crashDialog = d; 934 } else { 935 // The device is asleep, so just pretend that the user 936 // saw a crash dialog and hit "force quit". 937 res.set(0); 938 } 939 } 940 ensureBootCompleted(); 941 } break; 942 case SHOW_FACTORY_ERROR_MSG: { 943 Dialog d = new FactoryErrorDialog( 944 mContext, msg.getData().getCharSequence("msg")); 945 d.show(); 946 ensureBootCompleted(); 947 } break; 948 case UPDATE_CONFIGURATION_MSG: { 949 final ContentResolver resolver = mContext.getContentResolver(); 950 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 951 } break; 952 case GC_BACKGROUND_PROCESSES_MSG: { 953 synchronized (ActivityManagerService.this) { 954 performAppGcsIfAppropriateLocked(); 955 } 956 } break; 957 case WAIT_FOR_DEBUGGER_MSG: { 958 synchronized (ActivityManagerService.this) { 959 ProcessRecord app = (ProcessRecord)msg.obj; 960 if (msg.arg1 != 0) { 961 if (!app.waitedForDebugger) { 962 Dialog d = new AppWaitingForDebuggerDialog( 963 ActivityManagerService.this, 964 mContext, app); 965 app.waitDialog = d; 966 app.waitedForDebugger = true; 967 d.show(); 968 } 969 } else { 970 if (app.waitDialog != null) { 971 app.waitDialog.dismiss(); 972 app.waitDialog = null; 973 } 974 } 975 } 976 } break; 977 case SERVICE_TIMEOUT_MSG: { 978 if (mDidDexOpt) { 979 mDidDexOpt = false; 980 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 981 nmsg.obj = msg.obj; 982 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 983 return; 984 } 985 mServices.serviceTimeout((ProcessRecord)msg.obj); 986 } break; 987 case UPDATE_TIME_ZONE: { 988 synchronized (ActivityManagerService.this) { 989 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 990 ProcessRecord r = mLruProcesses.get(i); 991 if (r.thread != null) { 992 try { 993 r.thread.updateTimeZone(); 994 } catch (RemoteException ex) { 995 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 996 } 997 } 998 } 999 } 1000 } break; 1001 case CLEAR_DNS_CACHE: { 1002 synchronized (ActivityManagerService.this) { 1003 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1004 ProcessRecord r = mLruProcesses.get(i); 1005 if (r.thread != null) { 1006 try { 1007 r.thread.clearDnsCache(); 1008 } catch (RemoteException ex) { 1009 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1010 } 1011 } 1012 } 1013 } 1014 } break; 1015 case UPDATE_HTTP_PROXY: { 1016 ProxyProperties proxy = (ProxyProperties)msg.obj; 1017 String host = ""; 1018 String port = ""; 1019 String exclList = ""; 1020 if (proxy != null) { 1021 host = proxy.getHost(); 1022 port = Integer.toString(proxy.getPort()); 1023 exclList = proxy.getExclusionList(); 1024 } 1025 synchronized (ActivityManagerService.this) { 1026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1027 ProcessRecord r = mLruProcesses.get(i); 1028 if (r.thread != null) { 1029 try { 1030 r.thread.setHttpProxy(host, port, exclList); 1031 } catch (RemoteException ex) { 1032 Slog.w(TAG, "Failed to update http proxy for: " + 1033 r.info.processName); 1034 } 1035 } 1036 } 1037 } 1038 } break; 1039 case SHOW_UID_ERROR_MSG: { 1040 String title = "System UIDs Inconsistent"; 1041 String text = "UIDs on the system are inconsistent, you need to wipe your" 1042 + " data partition or your device will be unstable."; 1043 Log.e(TAG, title + ": " + text); 1044 if (mShowDialogs) { 1045 // XXX This is a temporary dialog, no need to localize. 1046 AlertDialog d = new BaseErrorDialog(mContext); 1047 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1048 d.setCancelable(false); 1049 d.setTitle(title); 1050 d.setMessage(text); 1051 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1052 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1053 mUidAlert = d; 1054 d.show(); 1055 } 1056 } break; 1057 case IM_FEELING_LUCKY_MSG: { 1058 if (mUidAlert != null) { 1059 mUidAlert.dismiss(); 1060 mUidAlert = null; 1061 } 1062 } break; 1063 case PROC_START_TIMEOUT_MSG: { 1064 if (mDidDexOpt) { 1065 mDidDexOpt = false; 1066 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1067 nmsg.obj = msg.obj; 1068 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1069 return; 1070 } 1071 ProcessRecord app = (ProcessRecord)msg.obj; 1072 synchronized (ActivityManagerService.this) { 1073 processStartTimedOutLocked(app); 1074 } 1075 } break; 1076 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1077 synchronized (ActivityManagerService.this) { 1078 doPendingActivityLaunchesLocked(true); 1079 } 1080 } break; 1081 case KILL_APPLICATION_MSG: { 1082 synchronized (ActivityManagerService.this) { 1083 int uid = msg.arg1; 1084 boolean restart = (msg.arg2 == 1); 1085 String pkg = (String) msg.obj; 1086 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1087 UserHandle.getUserId(uid)); 1088 } 1089 } break; 1090 case FINALIZE_PENDING_INTENT_MSG: { 1091 ((PendingIntentRecord)msg.obj).completeFinalize(); 1092 } break; 1093 case POST_HEAVY_NOTIFICATION_MSG: { 1094 INotificationManager inm = NotificationManager.getService(); 1095 if (inm == null) { 1096 return; 1097 } 1098 1099 ActivityRecord root = (ActivityRecord)msg.obj; 1100 ProcessRecord process = root.app; 1101 if (process == null) { 1102 return; 1103 } 1104 1105 try { 1106 Context context = mContext.createPackageContext(process.info.packageName, 0); 1107 String text = mContext.getString(R.string.heavy_weight_notification, 1108 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1109 Notification notification = new Notification(); 1110 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1111 notification.when = 0; 1112 notification.flags = Notification.FLAG_ONGOING_EVENT; 1113 notification.tickerText = text; 1114 notification.defaults = 0; // please be quiet 1115 notification.sound = null; 1116 notification.vibrate = null; 1117 notification.setLatestEventInfo(context, text, 1118 mContext.getText(R.string.heavy_weight_notification_detail), 1119 PendingIntent.getActivity(mContext, 0, root.intent, 1120 PendingIntent.FLAG_CANCEL_CURRENT)); 1121 1122 try { 1123 int[] outId = new int[1]; 1124 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1125 notification, outId); 1126 } catch (RuntimeException e) { 1127 Slog.w(ActivityManagerService.TAG, 1128 "Error showing notification for heavy-weight app", e); 1129 } catch (RemoteException e) { 1130 } 1131 } catch (NameNotFoundException e) { 1132 Slog.w(TAG, "Unable to create context for heavy notification", e); 1133 } 1134 } break; 1135 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1136 INotificationManager inm = NotificationManager.getService(); 1137 if (inm == null) { 1138 return; 1139 } 1140 try { 1141 inm.cancelNotification("android", 1142 R.string.heavy_weight_notification); 1143 } catch (RuntimeException e) { 1144 Slog.w(ActivityManagerService.TAG, 1145 "Error canceling notification for service", e); 1146 } catch (RemoteException e) { 1147 } 1148 } break; 1149 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1150 synchronized (ActivityManagerService.this) { 1151 checkExcessivePowerUsageLocked(true); 1152 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1153 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1154 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1155 } 1156 } break; 1157 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1158 synchronized (ActivityManagerService.this) { 1159 ActivityRecord ar = (ActivityRecord)msg.obj; 1160 if (mCompatModeDialog != null) { 1161 if (mCompatModeDialog.mAppInfo.packageName.equals( 1162 ar.info.applicationInfo.packageName)) { 1163 return; 1164 } 1165 mCompatModeDialog.dismiss(); 1166 mCompatModeDialog = null; 1167 } 1168 if (ar != null && false) { 1169 if (mCompatModePackages.getPackageAskCompatModeLocked( 1170 ar.packageName)) { 1171 int mode = mCompatModePackages.computeCompatModeLocked( 1172 ar.info.applicationInfo); 1173 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1174 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1175 mCompatModeDialog = new CompatModeDialog( 1176 ActivityManagerService.this, mContext, 1177 ar.info.applicationInfo); 1178 mCompatModeDialog.show(); 1179 } 1180 } 1181 } 1182 } 1183 break; 1184 } 1185 case DISPATCH_PROCESSES_CHANGED: { 1186 dispatchProcessesChanged(); 1187 break; 1188 } 1189 case DISPATCH_PROCESS_DIED: { 1190 final int pid = msg.arg1; 1191 final int uid = msg.arg2; 1192 dispatchProcessDied(pid, uid); 1193 break; 1194 } 1195 case REPORT_MEM_USAGE: { 1196 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1197 if (!isDebuggable) { 1198 return; 1199 } 1200 synchronized (ActivityManagerService.this) { 1201 long now = SystemClock.uptimeMillis(); 1202 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1203 // Don't report more than every 5 minutes to somewhat 1204 // avoid spamming. 1205 return; 1206 } 1207 mLastMemUsageReportTime = now; 1208 } 1209 Thread thread = new Thread() { 1210 @Override public void run() { 1211 StringBuilder dropBuilder = new StringBuilder(1024); 1212 StringBuilder logBuilder = new StringBuilder(1024); 1213 StringWriter oomSw = new StringWriter(); 1214 PrintWriter oomPw = new PrintWriter(oomSw); 1215 StringWriter catSw = new StringWriter(); 1216 PrintWriter catPw = new PrintWriter(catSw); 1217 String[] emptyArgs = new String[] { }; 1218 StringBuilder tag = new StringBuilder(128); 1219 StringBuilder stack = new StringBuilder(128); 1220 tag.append("Low on memory -- "); 1221 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1222 tag, stack); 1223 dropBuilder.append(stack); 1224 dropBuilder.append('\n'); 1225 dropBuilder.append('\n'); 1226 String oomString = oomSw.toString(); 1227 dropBuilder.append(oomString); 1228 dropBuilder.append('\n'); 1229 logBuilder.append(oomString); 1230 try { 1231 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1232 "procrank", }); 1233 final InputStreamReader converter = new InputStreamReader( 1234 proc.getInputStream()); 1235 BufferedReader in = new BufferedReader(converter); 1236 String line; 1237 while (true) { 1238 line = in.readLine(); 1239 if (line == null) { 1240 break; 1241 } 1242 if (line.length() > 0) { 1243 logBuilder.append(line); 1244 logBuilder.append('\n'); 1245 } 1246 dropBuilder.append(line); 1247 dropBuilder.append('\n'); 1248 } 1249 converter.close(); 1250 } catch (IOException e) { 1251 } 1252 synchronized (ActivityManagerService.this) { 1253 catPw.println(); 1254 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1255 catPw.println(); 1256 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1257 false, false, null); 1258 catPw.println(); 1259 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1260 } 1261 dropBuilder.append(catSw.toString()); 1262 addErrorToDropBox("lowmem", null, "system_server", null, 1263 null, tag.toString(), dropBuilder.toString(), null, null); 1264 Slog.i(TAG, logBuilder.toString()); 1265 synchronized (ActivityManagerService.this) { 1266 long now = SystemClock.uptimeMillis(); 1267 if (mLastMemUsageReportTime < now) { 1268 mLastMemUsageReportTime = now; 1269 } 1270 } 1271 } 1272 }; 1273 thread.start(); 1274 break; 1275 } 1276 } 1277 } 1278 }; 1279 1280 public static void setSystemProcess() { 1281 try { 1282 ActivityManagerService m = mSelf; 1283 1284 ServiceManager.addService("activity", m, true); 1285 ServiceManager.addService("meminfo", new MemBinder(m)); 1286 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1287 ServiceManager.addService("dbinfo", new DbBinder(m)); 1288 if (MONITOR_CPU_USAGE) { 1289 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1290 } 1291 ServiceManager.addService("permission", new PermissionController(m)); 1292 1293 ApplicationInfo info = 1294 mSelf.mContext.getPackageManager().getApplicationInfo( 1295 "android", STOCK_PM_FLAGS); 1296 mSystemThread.installSystemApplicationInfo(info); 1297 1298 synchronized (mSelf) { 1299 ProcessRecord app = mSelf.newProcessRecordLocked( 1300 mSystemThread.getApplicationThread(), info, 1301 info.processName, false); 1302 app.persistent = true; 1303 app.pid = MY_PID; 1304 app.maxAdj = ProcessList.SYSTEM_ADJ; 1305 mSelf.mProcessNames.put(app.processName, app.uid, app); 1306 synchronized (mSelf.mPidsSelfLocked) { 1307 mSelf.mPidsSelfLocked.put(app.pid, app); 1308 } 1309 mSelf.updateLruProcessLocked(app, true, true); 1310 } 1311 } catch (PackageManager.NameNotFoundException e) { 1312 throw new RuntimeException( 1313 "Unable to find android system package", e); 1314 } 1315 } 1316 1317 public void setWindowManager(WindowManagerService wm) { 1318 mWindowManager = wm; 1319 } 1320 1321 public static final Context main(int factoryTest) { 1322 AThread thr = new AThread(); 1323 thr.start(); 1324 1325 synchronized (thr) { 1326 while (thr.mService == null) { 1327 try { 1328 thr.wait(); 1329 } catch (InterruptedException e) { 1330 } 1331 } 1332 } 1333 1334 ActivityManagerService m = thr.mService; 1335 mSelf = m; 1336 ActivityThread at = ActivityThread.systemMain(); 1337 mSystemThread = at; 1338 Context context = at.getSystemContext(); 1339 context.setTheme(android.R.style.Theme_Holo); 1340 m.mContext = context; 1341 m.mFactoryTest = factoryTest; 1342 m.mMainStack = new ActivityStack(m, context, true); 1343 1344 m.mBatteryStatsService.publish(context); 1345 m.mUsageStatsService.publish(context); 1346 1347 synchronized (thr) { 1348 thr.mReady = true; 1349 thr.notifyAll(); 1350 } 1351 1352 m.startRunning(null, null, null, null); 1353 1354 return context; 1355 } 1356 1357 public static ActivityManagerService self() { 1358 return mSelf; 1359 } 1360 1361 static class AThread extends Thread { 1362 ActivityManagerService mService; 1363 boolean mReady = false; 1364 1365 public AThread() { 1366 super("ActivityManager"); 1367 } 1368 1369 public void run() { 1370 Looper.prepare(); 1371 1372 android.os.Process.setThreadPriority( 1373 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1374 android.os.Process.setCanSelfBackground(false); 1375 1376 ActivityManagerService m = new ActivityManagerService(); 1377 1378 synchronized (this) { 1379 mService = m; 1380 notifyAll(); 1381 } 1382 1383 synchronized (this) { 1384 while (!mReady) { 1385 try { 1386 wait(); 1387 } catch (InterruptedException e) { 1388 } 1389 } 1390 } 1391 1392 // For debug builds, log event loop stalls to dropbox for analysis. 1393 if (StrictMode.conditionallyEnableDebugLogging()) { 1394 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1395 } 1396 1397 Looper.loop(); 1398 } 1399 } 1400 1401 static class MemBinder extends Binder { 1402 ActivityManagerService mActivityManagerService; 1403 MemBinder(ActivityManagerService activityManagerService) { 1404 mActivityManagerService = activityManagerService; 1405 } 1406 1407 @Override 1408 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1409 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1410 != PackageManager.PERMISSION_GRANTED) { 1411 pw.println("Permission Denial: can't dump meminfo from from pid=" 1412 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1413 + " without permission " + android.Manifest.permission.DUMP); 1414 return; 1415 } 1416 1417 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1418 false, null, null, null); 1419 } 1420 } 1421 1422 static class GraphicsBinder extends Binder { 1423 ActivityManagerService mActivityManagerService; 1424 GraphicsBinder(ActivityManagerService activityManagerService) { 1425 mActivityManagerService = activityManagerService; 1426 } 1427 1428 @Override 1429 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1430 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1431 != PackageManager.PERMISSION_GRANTED) { 1432 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1433 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1434 + " without permission " + android.Manifest.permission.DUMP); 1435 return; 1436 } 1437 1438 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1439 } 1440 } 1441 1442 static class DbBinder extends Binder { 1443 ActivityManagerService mActivityManagerService; 1444 DbBinder(ActivityManagerService activityManagerService) { 1445 mActivityManagerService = activityManagerService; 1446 } 1447 1448 @Override 1449 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1450 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1451 != PackageManager.PERMISSION_GRANTED) { 1452 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1453 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1454 + " without permission " + android.Manifest.permission.DUMP); 1455 return; 1456 } 1457 1458 mActivityManagerService.dumpDbInfo(fd, pw, args); 1459 } 1460 } 1461 1462 static class CpuBinder extends Binder { 1463 ActivityManagerService mActivityManagerService; 1464 CpuBinder(ActivityManagerService activityManagerService) { 1465 mActivityManagerService = activityManagerService; 1466 } 1467 1468 @Override 1469 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1470 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1471 != PackageManager.PERMISSION_GRANTED) { 1472 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1473 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1474 + " without permission " + android.Manifest.permission.DUMP); 1475 return; 1476 } 1477 1478 synchronized (mActivityManagerService.mProcessStatsThread) { 1479 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1480 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1481 SystemClock.uptimeMillis())); 1482 } 1483 } 1484 } 1485 1486 private ActivityManagerService() { 1487 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1488 1489 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1490 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1491 mBroadcastQueues[0] = mFgBroadcastQueue; 1492 mBroadcastQueues[1] = mBgBroadcastQueue; 1493 1494 mServices = new ActiveServices(this); 1495 1496 File dataDir = Environment.getDataDirectory(); 1497 File systemDir = new File(dataDir, "system"); 1498 systemDir.mkdirs(); 1499 mBatteryStatsService = new BatteryStatsService(new File( 1500 systemDir, "batterystats.bin").toString()); 1501 mBatteryStatsService.getActiveStatistics().readLocked(); 1502 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1503 mOnBattery = DEBUG_POWER ? true 1504 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1505 mBatteryStatsService.getActiveStatistics().setCallback(this); 1506 1507 mUsageStatsService = new UsageStatsService(new File( 1508 systemDir, "usagestats").toString()); 1509 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1510 1511 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1512 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1513 1514 mConfiguration.setToDefaults(); 1515 mConfiguration.locale = Locale.getDefault(); 1516 mConfigurationSeq = mConfiguration.seq = 1; 1517 mProcessStats.init(); 1518 1519 mCompatModePackages = new CompatModePackages(this, systemDir); 1520 1521 // Add ourself to the Watchdog monitors. 1522 Watchdog.getInstance().addMonitor(this); 1523 1524 mProcessStatsThread = new Thread("ProcessStats") { 1525 public void run() { 1526 while (true) { 1527 try { 1528 try { 1529 synchronized(this) { 1530 final long now = SystemClock.uptimeMillis(); 1531 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1532 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1533 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1534 // + ", write delay=" + nextWriteDelay); 1535 if (nextWriteDelay < nextCpuDelay) { 1536 nextCpuDelay = nextWriteDelay; 1537 } 1538 if (nextCpuDelay > 0) { 1539 mProcessStatsMutexFree.set(true); 1540 this.wait(nextCpuDelay); 1541 } 1542 } 1543 } catch (InterruptedException e) { 1544 } 1545 updateCpuStatsNow(); 1546 } catch (Exception e) { 1547 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1548 } 1549 } 1550 } 1551 }; 1552 mProcessStatsThread.start(); 1553 } 1554 1555 @Override 1556 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1557 throws RemoteException { 1558 if (code == SYSPROPS_TRANSACTION) { 1559 // We need to tell all apps about the system property change. 1560 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1561 synchronized(this) { 1562 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1563 final int NA = apps.size(); 1564 for (int ia=0; ia<NA; ia++) { 1565 ProcessRecord app = apps.valueAt(ia); 1566 if (app.thread != null) { 1567 procs.add(app.thread.asBinder()); 1568 } 1569 } 1570 } 1571 } 1572 1573 int N = procs.size(); 1574 for (int i=0; i<N; i++) { 1575 Parcel data2 = Parcel.obtain(); 1576 try { 1577 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1578 } catch (RemoteException e) { 1579 } 1580 data2.recycle(); 1581 } 1582 } 1583 try { 1584 return super.onTransact(code, data, reply, flags); 1585 } catch (RuntimeException e) { 1586 // The activity manager only throws security exceptions, so let's 1587 // log all others. 1588 if (!(e instanceof SecurityException)) { 1589 Slog.e(TAG, "Activity Manager Crash", e); 1590 } 1591 throw e; 1592 } 1593 } 1594 1595 void updateCpuStats() { 1596 final long now = SystemClock.uptimeMillis(); 1597 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1598 return; 1599 } 1600 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1601 synchronized (mProcessStatsThread) { 1602 mProcessStatsThread.notify(); 1603 } 1604 } 1605 } 1606 1607 void updateCpuStatsNow() { 1608 synchronized (mProcessStatsThread) { 1609 mProcessStatsMutexFree.set(false); 1610 final long now = SystemClock.uptimeMillis(); 1611 boolean haveNewCpuStats = false; 1612 1613 if (MONITOR_CPU_USAGE && 1614 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1615 mLastCpuTime.set(now); 1616 haveNewCpuStats = true; 1617 mProcessStats.update(); 1618 //Slog.i(TAG, mProcessStats.printCurrentState()); 1619 //Slog.i(TAG, "Total CPU usage: " 1620 // + mProcessStats.getTotalCpuPercent() + "%"); 1621 1622 // Slog the cpu usage if the property is set. 1623 if ("true".equals(SystemProperties.get("events.cpu"))) { 1624 int user = mProcessStats.getLastUserTime(); 1625 int system = mProcessStats.getLastSystemTime(); 1626 int iowait = mProcessStats.getLastIoWaitTime(); 1627 int irq = mProcessStats.getLastIrqTime(); 1628 int softIrq = mProcessStats.getLastSoftIrqTime(); 1629 int idle = mProcessStats.getLastIdleTime(); 1630 1631 int total = user + system + iowait + irq + softIrq + idle; 1632 if (total == 0) total = 1; 1633 1634 EventLog.writeEvent(EventLogTags.CPU, 1635 ((user+system+iowait+irq+softIrq) * 100) / total, 1636 (user * 100) / total, 1637 (system * 100) / total, 1638 (iowait * 100) / total, 1639 (irq * 100) / total, 1640 (softIrq * 100) / total); 1641 } 1642 } 1643 1644 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1645 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1646 synchronized(bstats) { 1647 synchronized(mPidsSelfLocked) { 1648 if (haveNewCpuStats) { 1649 if (mOnBattery) { 1650 int perc = bstats.startAddingCpuLocked(); 1651 int totalUTime = 0; 1652 int totalSTime = 0; 1653 final int N = mProcessStats.countStats(); 1654 for (int i=0; i<N; i++) { 1655 ProcessStats.Stats st = mProcessStats.getStats(i); 1656 if (!st.working) { 1657 continue; 1658 } 1659 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1660 int otherUTime = (st.rel_utime*perc)/100; 1661 int otherSTime = (st.rel_stime*perc)/100; 1662 totalUTime += otherUTime; 1663 totalSTime += otherSTime; 1664 if (pr != null) { 1665 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1666 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1667 st.rel_stime-otherSTime); 1668 ps.addSpeedStepTimes(cpuSpeedTimes); 1669 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1670 } else { 1671 BatteryStatsImpl.Uid.Proc ps = 1672 bstats.getProcessStatsLocked(st.name, st.pid); 1673 if (ps != null) { 1674 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1675 st.rel_stime-otherSTime); 1676 ps.addSpeedStepTimes(cpuSpeedTimes); 1677 } 1678 } 1679 } 1680 bstats.finishAddingCpuLocked(perc, totalUTime, 1681 totalSTime, cpuSpeedTimes); 1682 } 1683 } 1684 } 1685 1686 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1687 mLastWriteTime = now; 1688 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1689 } 1690 } 1691 } 1692 } 1693 1694 @Override 1695 public void batteryNeedsCpuUpdate() { 1696 updateCpuStatsNow(); 1697 } 1698 1699 @Override 1700 public void batteryPowerChanged(boolean onBattery) { 1701 // When plugging in, update the CPU stats first before changing 1702 // the plug state. 1703 updateCpuStatsNow(); 1704 synchronized (this) { 1705 synchronized(mPidsSelfLocked) { 1706 mOnBattery = DEBUG_POWER ? true : onBattery; 1707 } 1708 } 1709 } 1710 1711 /** 1712 * Initialize the application bind args. These are passed to each 1713 * process when the bindApplication() IPC is sent to the process. They're 1714 * lazily setup to make sure the services are running when they're asked for. 1715 */ 1716 private HashMap<String, IBinder> getCommonServicesLocked() { 1717 if (mAppBindArgs == null) { 1718 mAppBindArgs = new HashMap<String, IBinder>(); 1719 1720 // Setup the application init args 1721 mAppBindArgs.put("package", ServiceManager.getService("package")); 1722 mAppBindArgs.put("window", ServiceManager.getService("window")); 1723 mAppBindArgs.put(Context.ALARM_SERVICE, 1724 ServiceManager.getService(Context.ALARM_SERVICE)); 1725 } 1726 return mAppBindArgs; 1727 } 1728 1729 final void setFocusedActivityLocked(ActivityRecord r) { 1730 if (mFocusedActivity != r) { 1731 mFocusedActivity = r; 1732 if (r != null) { 1733 mWindowManager.setFocusedApp(r.appToken, true); 1734 } 1735 } 1736 } 1737 1738 private final void updateLruProcessInternalLocked(ProcessRecord app, 1739 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1740 // put it on the LRU to keep track of when it should be exited. 1741 int lrui = mLruProcesses.indexOf(app); 1742 if (lrui >= 0) mLruProcesses.remove(lrui); 1743 1744 int i = mLruProcesses.size()-1; 1745 int skipTop = 0; 1746 1747 app.lruSeq = mLruSeq; 1748 1749 // compute the new weight for this process. 1750 if (updateActivityTime) { 1751 app.lastActivityTime = SystemClock.uptimeMillis(); 1752 } 1753 if (app.activities.size() > 0) { 1754 // If this process has activities, we more strongly want to keep 1755 // it around. 1756 app.lruWeight = app.lastActivityTime; 1757 } else if (app.pubProviders.size() > 0) { 1758 // If this process contains content providers, we want to keep 1759 // it a little more strongly. 1760 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1761 // Also don't let it kick out the first few "real" hidden processes. 1762 skipTop = ProcessList.MIN_HIDDEN_APPS; 1763 } else { 1764 // If this process doesn't have activities, we less strongly 1765 // want to keep it around, and generally want to avoid getting 1766 // in front of any very recently used activities. 1767 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1768 // Also don't let it kick out the first few "real" hidden processes. 1769 skipTop = ProcessList.MIN_HIDDEN_APPS; 1770 } 1771 1772 while (i >= 0) { 1773 ProcessRecord p = mLruProcesses.get(i); 1774 // If this app shouldn't be in front of the first N background 1775 // apps, then skip over that many that are currently hidden. 1776 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1777 skipTop--; 1778 } 1779 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1780 mLruProcesses.add(i+1, app); 1781 break; 1782 } 1783 i--; 1784 } 1785 if (i < 0) { 1786 mLruProcesses.add(0, app); 1787 } 1788 1789 // If the app is currently using a content provider or service, 1790 // bump those processes as well. 1791 if (app.connections.size() > 0) { 1792 for (ConnectionRecord cr : app.connections) { 1793 if (cr.binding != null && cr.binding.service != null 1794 && cr.binding.service.app != null 1795 && cr.binding.service.app.lruSeq != mLruSeq) { 1796 updateLruProcessInternalLocked(cr.binding.service.app, false, 1797 updateActivityTime, i+1); 1798 } 1799 } 1800 } 1801 for (int j=app.conProviders.size()-1; j>=0; j--) { 1802 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1803 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1804 updateLruProcessInternalLocked(cpr.proc, false, 1805 updateActivityTime, i+1); 1806 } 1807 } 1808 1809 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1810 if (oomAdj) { 1811 updateOomAdjLocked(); 1812 } 1813 } 1814 1815 final void updateLruProcessLocked(ProcessRecord app, 1816 boolean oomAdj, boolean updateActivityTime) { 1817 mLruSeq++; 1818 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1819 } 1820 1821 final ProcessRecord getProcessRecordLocked( 1822 String processName, int uid) { 1823 if (uid == Process.SYSTEM_UID) { 1824 // The system gets to run in any process. If there are multiple 1825 // processes with the same uid, just pick the first (this 1826 // should never happen). 1827 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1828 processName); 1829 if (procs == null) return null; 1830 final int N = procs.size(); 1831 for (int i = 0; i < N; i++) { 1832 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1833 } 1834 } 1835 ProcessRecord proc = mProcessNames.get(processName, uid); 1836 return proc; 1837 } 1838 1839 void ensurePackageDexOpt(String packageName) { 1840 IPackageManager pm = AppGlobals.getPackageManager(); 1841 try { 1842 if (pm.performDexOpt(packageName)) { 1843 mDidDexOpt = true; 1844 } 1845 } catch (RemoteException e) { 1846 } 1847 } 1848 1849 boolean isNextTransitionForward() { 1850 int transit = mWindowManager.getPendingAppTransition(); 1851 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1852 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1853 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1854 } 1855 1856 final ProcessRecord startProcessLocked(String processName, 1857 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1858 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1859 boolean isolated) { 1860 ProcessRecord app; 1861 if (!isolated) { 1862 app = getProcessRecordLocked(processName, info.uid); 1863 } else { 1864 // If this is an isolated process, it can't re-use an existing process. 1865 app = null; 1866 } 1867 // We don't have to do anything more if: 1868 // (1) There is an existing application record; and 1869 // (2) The caller doesn't think it is dead, OR there is no thread 1870 // object attached to it so we know it couldn't have crashed; and 1871 // (3) There is a pid assigned to it, so it is either starting or 1872 // already running. 1873 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1874 + " app=" + app + " knownToBeDead=" + knownToBeDead 1875 + " thread=" + (app != null ? app.thread : null) 1876 + " pid=" + (app != null ? app.pid : -1)); 1877 if (app != null && app.pid > 0) { 1878 if (!knownToBeDead || app.thread == null) { 1879 // We already have the app running, or are waiting for it to 1880 // come up (we have a pid but not yet its thread), so keep it. 1881 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1882 // If this is a new package in the process, add the package to the list 1883 app.addPackage(info.packageName); 1884 return app; 1885 } else { 1886 // An application record is attached to a previous process, 1887 // clean it up now. 1888 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1889 handleAppDiedLocked(app, true, true); 1890 } 1891 } 1892 1893 String hostingNameStr = hostingName != null 1894 ? hostingName.flattenToShortString() : null; 1895 1896 if (!isolated) { 1897 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1898 // If we are in the background, then check to see if this process 1899 // is bad. If so, we will just silently fail. 1900 if (mBadProcesses.get(info.processName, info.uid) != null) { 1901 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1902 + "/" + info.processName); 1903 return null; 1904 } 1905 } else { 1906 // When the user is explicitly starting a process, then clear its 1907 // crash count so that we won't make it bad until they see at 1908 // least one crash dialog again, and make the process good again 1909 // if it had been bad. 1910 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1911 + "/" + info.processName); 1912 mProcessCrashTimes.remove(info.processName, info.uid); 1913 if (mBadProcesses.get(info.processName, info.uid) != null) { 1914 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1915 info.processName); 1916 mBadProcesses.remove(info.processName, info.uid); 1917 if (app != null) { 1918 app.bad = false; 1919 } 1920 } 1921 } 1922 } 1923 1924 if (app == null) { 1925 app = newProcessRecordLocked(null, info, processName, isolated); 1926 if (app == null) { 1927 Slog.w(TAG, "Failed making new process record for " 1928 + processName + "/" + info.uid + " isolated=" + isolated); 1929 return null; 1930 } 1931 mProcessNames.put(processName, app.uid, app); 1932 if (isolated) { 1933 mIsolatedProcesses.put(app.uid, app); 1934 } 1935 } else { 1936 // If this is a new package in the process, add the package to the list 1937 app.addPackage(info.packageName); 1938 } 1939 1940 // If the system is not ready yet, then hold off on starting this 1941 // process until it is. 1942 if (!mProcessesReady 1943 && !isAllowedWhileBooting(info) 1944 && !allowWhileBooting) { 1945 if (!mProcessesOnHold.contains(app)) { 1946 mProcessesOnHold.add(app); 1947 } 1948 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1949 return app; 1950 } 1951 1952 startProcessLocked(app, hostingType, hostingNameStr); 1953 return (app.pid != 0) ? app : null; 1954 } 1955 1956 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1957 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1958 } 1959 1960 private final void startProcessLocked(ProcessRecord app, 1961 String hostingType, String hostingNameStr) { 1962 if (app.pid > 0 && app.pid != MY_PID) { 1963 synchronized (mPidsSelfLocked) { 1964 mPidsSelfLocked.remove(app.pid); 1965 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1966 } 1967 app.setPid(0); 1968 } 1969 1970 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1971 "startProcessLocked removing on hold: " + app); 1972 mProcessesOnHold.remove(app); 1973 1974 updateCpuStats(); 1975 1976 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1977 mProcDeaths[0] = 0; 1978 1979 try { 1980 int uid = app.uid; 1981 1982 int[] gids = null; 1983 if (!app.isolated) { 1984 try { 1985 gids = mContext.getPackageManager().getPackageGids( 1986 app.info.packageName); 1987 } catch (PackageManager.NameNotFoundException e) { 1988 Slog.w(TAG, "Unable to retrieve gids", e); 1989 } 1990 } 1991 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1992 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1993 && mTopComponent != null 1994 && app.processName.equals(mTopComponent.getPackageName())) { 1995 uid = 0; 1996 } 1997 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1998 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1999 uid = 0; 2000 } 2001 } 2002 int debugFlags = 0; 2003 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2004 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2005 // Also turn on CheckJNI for debuggable apps. It's quite 2006 // awkward to turn on otherwise. 2007 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2008 } 2009 // Run the app in safe mode if its manifest requests so or the 2010 // system is booted in safe mode. 2011 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2012 Zygote.systemInSafeMode == true) { 2013 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2014 } 2015 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2016 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2017 } 2018 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2019 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2020 } 2021 if ("1".equals(SystemProperties.get("debug.assert"))) { 2022 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2023 } 2024 2025 // Start the process. It will either succeed and return a result containing 2026 // the PID of the new process, or else throw a RuntimeException. 2027 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2028 app.processName, uid, uid, gids, debugFlags, 2029 app.info.targetSdkVersion, null, null); 2030 2031 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2032 synchronized (bs) { 2033 if (bs.isOnBattery()) { 2034 app.batteryStats.incStartsLocked(); 2035 } 2036 } 2037 2038 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2039 app.processName, hostingType, 2040 hostingNameStr != null ? hostingNameStr : ""); 2041 2042 if (app.persistent) { 2043 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2044 } 2045 2046 StringBuilder buf = mStringBuilder; 2047 buf.setLength(0); 2048 buf.append("Start proc "); 2049 buf.append(app.processName); 2050 buf.append(" for "); 2051 buf.append(hostingType); 2052 if (hostingNameStr != null) { 2053 buf.append(" "); 2054 buf.append(hostingNameStr); 2055 } 2056 buf.append(": pid="); 2057 buf.append(startResult.pid); 2058 buf.append(" uid="); 2059 buf.append(uid); 2060 buf.append(" gids={"); 2061 if (gids != null) { 2062 for (int gi=0; gi<gids.length; gi++) { 2063 if (gi != 0) buf.append(", "); 2064 buf.append(gids[gi]); 2065 2066 } 2067 } 2068 buf.append("}"); 2069 Slog.i(TAG, buf.toString()); 2070 app.setPid(startResult.pid); 2071 app.usingWrapper = startResult.usingWrapper; 2072 app.removed = false; 2073 synchronized (mPidsSelfLocked) { 2074 this.mPidsSelfLocked.put(startResult.pid, app); 2075 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2076 msg.obj = app; 2077 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2078 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2079 } 2080 } catch (RuntimeException e) { 2081 // XXX do better error recovery. 2082 app.setPid(0); 2083 Slog.e(TAG, "Failure starting process " + app.processName, e); 2084 } 2085 } 2086 2087 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2088 if (resumed) { 2089 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2090 } else { 2091 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2092 } 2093 } 2094 2095 boolean startHomeActivityLocked(int userId) { 2096 if (mHeadless) { 2097 // Added because none of the other calls to ensureBootCompleted seem to fire 2098 // when running headless. 2099 ensureBootCompleted(); 2100 return false; 2101 } 2102 2103 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2104 && mTopAction == null) { 2105 // We are running in factory test mode, but unable to find 2106 // the factory test app, so just sit around displaying the 2107 // error message and don't try to start anything. 2108 return false; 2109 } 2110 Intent intent = new Intent( 2111 mTopAction, 2112 mTopData != null ? Uri.parse(mTopData) : null); 2113 intent.setComponent(mTopComponent); 2114 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2115 intent.addCategory(Intent.CATEGORY_HOME); 2116 } 2117 ActivityInfo aInfo = 2118 intent.resolveActivityInfo(mContext.getPackageManager(), 2119 STOCK_PM_FLAGS); 2120 if (aInfo != null) { 2121 intent.setComponent(new ComponentName( 2122 aInfo.applicationInfo.packageName, aInfo.name)); 2123 // Don't do this if the home app is currently being 2124 // instrumented. 2125 aInfo = new ActivityInfo(aInfo); 2126 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2127 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2128 aInfo.applicationInfo.uid); 2129 if (app == null || app.instrumentationClass == null) { 2130 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2131 mMainStack.startActivityLocked(null, intent, null, aInfo, 2132 null, null, 0, 0, 0, 0, null, false, null); 2133 } 2134 } 2135 2136 return true; 2137 } 2138 2139 /** 2140 * Starts the "new version setup screen" if appropriate. 2141 */ 2142 void startSetupActivityLocked() { 2143 // Only do this once per boot. 2144 if (mCheckedForSetup) { 2145 return; 2146 } 2147 2148 // We will show this screen if the current one is a different 2149 // version than the last one shown, and we are not running in 2150 // low-level factory test mode. 2151 final ContentResolver resolver = mContext.getContentResolver(); 2152 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2153 Settings.Secure.getInt(resolver, 2154 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2155 mCheckedForSetup = true; 2156 2157 // See if we should be showing the platform update setup UI. 2158 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2159 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2160 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2161 2162 // We don't allow third party apps to replace this. 2163 ResolveInfo ri = null; 2164 for (int i=0; ris != null && i<ris.size(); i++) { 2165 if ((ris.get(i).activityInfo.applicationInfo.flags 2166 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2167 ri = ris.get(i); 2168 break; 2169 } 2170 } 2171 2172 if (ri != null) { 2173 String vers = ri.activityInfo.metaData != null 2174 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2175 : null; 2176 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2177 vers = ri.activityInfo.applicationInfo.metaData.getString( 2178 Intent.METADATA_SETUP_VERSION); 2179 } 2180 String lastVers = Settings.Secure.getString( 2181 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2182 if (vers != null && !vers.equals(lastVers)) { 2183 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2184 intent.setComponent(new ComponentName( 2185 ri.activityInfo.packageName, ri.activityInfo.name)); 2186 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2187 null, null, 0, 0, 0, 0, null, false, null); 2188 } 2189 } 2190 } 2191 } 2192 2193 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2194 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2195 } 2196 2197 void enforceNotIsolatedCaller(String caller) { 2198 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2199 throw new SecurityException("Isolated process not allowed to call " + caller); 2200 } 2201 } 2202 2203 public int getFrontActivityScreenCompatMode() { 2204 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2205 synchronized (this) { 2206 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2207 } 2208 } 2209 2210 public void setFrontActivityScreenCompatMode(int mode) { 2211 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2212 "setFrontActivityScreenCompatMode"); 2213 synchronized (this) { 2214 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2215 } 2216 } 2217 2218 public int getPackageScreenCompatMode(String packageName) { 2219 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2220 synchronized (this) { 2221 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2222 } 2223 } 2224 2225 public void setPackageScreenCompatMode(String packageName, int mode) { 2226 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2227 "setPackageScreenCompatMode"); 2228 synchronized (this) { 2229 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2230 } 2231 } 2232 2233 public boolean getPackageAskScreenCompat(String packageName) { 2234 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2235 synchronized (this) { 2236 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2237 } 2238 } 2239 2240 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2241 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2242 "setPackageAskScreenCompat"); 2243 synchronized (this) { 2244 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2245 } 2246 } 2247 2248 void reportResumedActivityLocked(ActivityRecord r) { 2249 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2250 updateUsageStats(r, true); 2251 } 2252 2253 private void dispatchProcessesChanged() { 2254 int N; 2255 synchronized (this) { 2256 N = mPendingProcessChanges.size(); 2257 if (mActiveProcessChanges.length < N) { 2258 mActiveProcessChanges = new ProcessChangeItem[N]; 2259 } 2260 mPendingProcessChanges.toArray(mActiveProcessChanges); 2261 mAvailProcessChanges.addAll(mPendingProcessChanges); 2262 mPendingProcessChanges.clear(); 2263 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2264 } 2265 int i = mProcessObservers.beginBroadcast(); 2266 while (i > 0) { 2267 i--; 2268 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2269 if (observer != null) { 2270 try { 2271 for (int j=0; j<N; j++) { 2272 ProcessChangeItem item = mActiveProcessChanges[j]; 2273 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2274 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2275 + item.pid + " uid=" + item.uid + ": " 2276 + item.foregroundActivities); 2277 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2278 item.foregroundActivities); 2279 } 2280 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2282 + item.pid + " uid=" + item.uid + ": " + item.importance); 2283 observer.onImportanceChanged(item.pid, item.uid, 2284 item.importance); 2285 } 2286 } 2287 } catch (RemoteException e) { 2288 } 2289 } 2290 } 2291 mProcessObservers.finishBroadcast(); 2292 } 2293 2294 private void dispatchProcessDied(int pid, int uid) { 2295 int i = mProcessObservers.beginBroadcast(); 2296 while (i > 0) { 2297 i--; 2298 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2299 if (observer != null) { 2300 try { 2301 observer.onProcessDied(pid, uid); 2302 } catch (RemoteException e) { 2303 } 2304 } 2305 } 2306 mProcessObservers.finishBroadcast(); 2307 } 2308 2309 final void doPendingActivityLaunchesLocked(boolean doResume) { 2310 final int N = mPendingActivityLaunches.size(); 2311 if (N <= 0) { 2312 return; 2313 } 2314 for (int i=0; i<N; i++) { 2315 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2316 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2317 pal.startFlags, doResume && i == (N-1), null); 2318 } 2319 mPendingActivityLaunches.clear(); 2320 } 2321 2322 public final int startActivity(IApplicationThread caller, 2323 Intent intent, String resolvedType, IBinder resultTo, 2324 String resultWho, int requestCode, int startFlags, 2325 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2326 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2327 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2328 } 2329 2330 public final int startActivityAsUser(IApplicationThread caller, 2331 Intent intent, String resolvedType, IBinder resultTo, 2332 String resultWho, int requestCode, int startFlags, 2333 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2334 enforceNotIsolatedCaller("startActivity"); 2335 if (userId != UserHandle.getCallingUserId()) { 2336 // Requesting a different user, make sure that they have the permission 2337 if (checkComponentPermission( 2338 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2339 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2340 == PackageManager.PERMISSION_GRANTED) { 2341 // Translate to the current user id, if caller wasn't aware 2342 if (userId == UserHandle.USER_CURRENT) { 2343 userId = mCurrentUserId; 2344 } 2345 } else { 2346 String msg = "Permission Denial: " 2347 + "Request to startActivity as user " + userId 2348 + " but is calling from user " + UserHandle.getCallingUserId() 2349 + "; this requires " 2350 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2351 Slog.w(TAG, msg); 2352 throw new SecurityException(msg); 2353 } 2354 } else { 2355 if (intent.getCategories() != null 2356 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2357 // Requesting home, set the identity to the current user 2358 // HACK! 2359 userId = mCurrentUserId; 2360 } else { 2361 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2362 // the current user's userId 2363 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2364 userId = 0; 2365 } else { 2366 userId = Binder.getOrigCallingUser(); 2367 } 2368 } 2369 } 2370 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2371 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2372 null, null, options, userId); 2373 } 2374 2375 public final WaitResult startActivityAndWait(IApplicationThread caller, 2376 Intent intent, String resolvedType, IBinder resultTo, 2377 String resultWho, int requestCode, int startFlags, String profileFile, 2378 ParcelFileDescriptor profileFd, Bundle options) { 2379 enforceNotIsolatedCaller("startActivityAndWait"); 2380 WaitResult res = new WaitResult(); 2381 int userId = Binder.getOrigCallingUser(); 2382 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2383 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2384 res, null, options, userId); 2385 return res; 2386 } 2387 2388 public final int startActivityWithConfig(IApplicationThread caller, 2389 Intent intent, String resolvedType, IBinder resultTo, 2390 String resultWho, int requestCode, int startFlags, Configuration config, 2391 Bundle options) { 2392 enforceNotIsolatedCaller("startActivityWithConfig"); 2393 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2394 resultTo, resultWho, requestCode, startFlags, 2395 null, null, null, config, options, Binder.getOrigCallingUser()); 2396 return ret; 2397 } 2398 2399 public int startActivityIntentSender(IApplicationThread caller, 2400 IntentSender intent, Intent fillInIntent, String resolvedType, 2401 IBinder resultTo, String resultWho, int requestCode, 2402 int flagsMask, int flagsValues, Bundle options) { 2403 enforceNotIsolatedCaller("startActivityIntentSender"); 2404 // Refuse possible leaked file descriptors 2405 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2406 throw new IllegalArgumentException("File descriptors passed in Intent"); 2407 } 2408 2409 IIntentSender sender = intent.getTarget(); 2410 if (!(sender instanceof PendingIntentRecord)) { 2411 throw new IllegalArgumentException("Bad PendingIntent object"); 2412 } 2413 2414 PendingIntentRecord pir = (PendingIntentRecord)sender; 2415 2416 synchronized (this) { 2417 // If this is coming from the currently resumed activity, it is 2418 // effectively saying that app switches are allowed at this point. 2419 if (mMainStack.mResumedActivity != null 2420 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2421 Binder.getCallingUid()) { 2422 mAppSwitchesAllowedTime = 0; 2423 } 2424 } 2425 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2426 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2427 return ret; 2428 } 2429 2430 public boolean startNextMatchingActivity(IBinder callingActivity, 2431 Intent intent, Bundle options) { 2432 // Refuse possible leaked file descriptors 2433 if (intent != null && intent.hasFileDescriptors() == true) { 2434 throw new IllegalArgumentException("File descriptors passed in Intent"); 2435 } 2436 2437 synchronized (this) { 2438 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2439 if (r == null) { 2440 ActivityOptions.abort(options); 2441 return false; 2442 } 2443 if (r.app == null || r.app.thread == null) { 2444 // The caller is not running... d'oh! 2445 ActivityOptions.abort(options); 2446 return false; 2447 } 2448 intent = new Intent(intent); 2449 // The caller is not allowed to change the data. 2450 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2451 // And we are resetting to find the next component... 2452 intent.setComponent(null); 2453 2454 ActivityInfo aInfo = null; 2455 try { 2456 List<ResolveInfo> resolves = 2457 AppGlobals.getPackageManager().queryIntentActivities( 2458 intent, r.resolvedType, 2459 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2460 UserHandle.getCallingUserId()); 2461 2462 // Look for the original activity in the list... 2463 final int N = resolves != null ? resolves.size() : 0; 2464 for (int i=0; i<N; i++) { 2465 ResolveInfo rInfo = resolves.get(i); 2466 if (rInfo.activityInfo.packageName.equals(r.packageName) 2467 && rInfo.activityInfo.name.equals(r.info.name)) { 2468 // We found the current one... the next matching is 2469 // after it. 2470 i++; 2471 if (i<N) { 2472 aInfo = resolves.get(i).activityInfo; 2473 } 2474 break; 2475 } 2476 } 2477 } catch (RemoteException e) { 2478 } 2479 2480 if (aInfo == null) { 2481 // Nobody who is next! 2482 ActivityOptions.abort(options); 2483 return false; 2484 } 2485 2486 intent.setComponent(new ComponentName( 2487 aInfo.applicationInfo.packageName, aInfo.name)); 2488 intent.setFlags(intent.getFlags()&~( 2489 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2490 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2491 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2492 Intent.FLAG_ACTIVITY_NEW_TASK)); 2493 2494 // Okay now we need to start the new activity, replacing the 2495 // currently running activity. This is a little tricky because 2496 // we want to start the new one as if the current one is finished, 2497 // but not finish the current one first so that there is no flicker. 2498 // And thus... 2499 final boolean wasFinishing = r.finishing; 2500 r.finishing = true; 2501 2502 // Propagate reply information over to the new activity. 2503 final ActivityRecord resultTo = r.resultTo; 2504 final String resultWho = r.resultWho; 2505 final int requestCode = r.requestCode; 2506 r.resultTo = null; 2507 if (resultTo != null) { 2508 resultTo.removeResultsLocked(r, resultWho, requestCode); 2509 } 2510 2511 final long origId = Binder.clearCallingIdentity(); 2512 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2513 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2514 resultWho, requestCode, -1, r.launchedFromUid, 0, 2515 options, false, null); 2516 Binder.restoreCallingIdentity(origId); 2517 2518 r.finishing = wasFinishing; 2519 if (res != ActivityManager.START_SUCCESS) { 2520 return false; 2521 } 2522 return true; 2523 } 2524 } 2525 2526 public final int startActivityInPackage(int uid, 2527 Intent intent, String resolvedType, IBinder resultTo, 2528 String resultWho, int requestCode, int startFlags, Bundle options) { 2529 2530 // This is so super not safe, that only the system (or okay root) 2531 // can do it. 2532 int userId = Binder.getOrigCallingUser(); 2533 final int callingUid = Binder.getCallingUid(); 2534 if (callingUid != 0 && callingUid != Process.myUid()) { 2535 throw new SecurityException( 2536 "startActivityInPackage only available to the system"); 2537 } 2538 2539 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2540 resultTo, resultWho, requestCode, startFlags, 2541 null, null, null, null, options, userId); 2542 return ret; 2543 } 2544 2545 public final int startActivities(IApplicationThread caller, 2546 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2547 enforceNotIsolatedCaller("startActivities"); 2548 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2549 options, Binder.getOrigCallingUser()); 2550 return ret; 2551 } 2552 2553 public final int startActivitiesInPackage(int uid, 2554 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2555 Bundle options) { 2556 2557 // This is so super not safe, that only the system (or okay root) 2558 // can do it. 2559 final int callingUid = Binder.getCallingUid(); 2560 if (callingUid != 0 && callingUid != Process.myUid()) { 2561 throw new SecurityException( 2562 "startActivityInPackage only available to the system"); 2563 } 2564 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2565 options, UserHandle.getUserId(uid)); 2566 return ret; 2567 } 2568 2569 final void addRecentTaskLocked(TaskRecord task) { 2570 int N = mRecentTasks.size(); 2571 // Quick case: check if the top-most recent task is the same. 2572 if (N > 0 && mRecentTasks.get(0) == task) { 2573 return; 2574 } 2575 // Remove any existing entries that are the same kind of task. 2576 for (int i=0; i<N; i++) { 2577 TaskRecord tr = mRecentTasks.get(i); 2578 if (task.userId == tr.userId 2579 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2580 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2581 mRecentTasks.remove(i); 2582 i--; 2583 N--; 2584 if (task.intent == null) { 2585 // If the new recent task we are adding is not fully 2586 // specified, then replace it with the existing recent task. 2587 task = tr; 2588 } 2589 } 2590 } 2591 if (N >= MAX_RECENT_TASKS) { 2592 mRecentTasks.remove(N-1); 2593 } 2594 mRecentTasks.add(0, task); 2595 } 2596 2597 public void setRequestedOrientation(IBinder token, 2598 int requestedOrientation) { 2599 synchronized (this) { 2600 ActivityRecord r = mMainStack.isInStackLocked(token); 2601 if (r == null) { 2602 return; 2603 } 2604 final long origId = Binder.clearCallingIdentity(); 2605 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2606 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2607 mConfiguration, 2608 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2609 if (config != null) { 2610 r.frozenBeforeDestroy = true; 2611 if (!updateConfigurationLocked(config, r, false, false)) { 2612 mMainStack.resumeTopActivityLocked(null); 2613 } 2614 } 2615 Binder.restoreCallingIdentity(origId); 2616 } 2617 } 2618 2619 public int getRequestedOrientation(IBinder token) { 2620 synchronized (this) { 2621 ActivityRecord r = mMainStack.isInStackLocked(token); 2622 if (r == null) { 2623 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2624 } 2625 return mWindowManager.getAppOrientation(r.appToken); 2626 } 2627 } 2628 2629 /** 2630 * This is the internal entry point for handling Activity.finish(). 2631 * 2632 * @param token The Binder token referencing the Activity we want to finish. 2633 * @param resultCode Result code, if any, from this Activity. 2634 * @param resultData Result data (Intent), if any, from this Activity. 2635 * 2636 * @return Returns true if the activity successfully finished, or false if it is still running. 2637 */ 2638 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2639 // Refuse possible leaked file descriptors 2640 if (resultData != null && resultData.hasFileDescriptors() == true) { 2641 throw new IllegalArgumentException("File descriptors passed in Intent"); 2642 } 2643 2644 synchronized(this) { 2645 if (mController != null) { 2646 // Find the first activity that is not finishing. 2647 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2648 if (next != null) { 2649 // ask watcher if this is allowed 2650 boolean resumeOK = true; 2651 try { 2652 resumeOK = mController.activityResuming(next.packageName); 2653 } catch (RemoteException e) { 2654 mController = null; 2655 } 2656 2657 if (!resumeOK) { 2658 return false; 2659 } 2660 } 2661 } 2662 final long origId = Binder.clearCallingIdentity(); 2663 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2664 resultData, "app-request"); 2665 Binder.restoreCallingIdentity(origId); 2666 return res; 2667 } 2668 } 2669 2670 public final void finishHeavyWeightApp() { 2671 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2672 != PackageManager.PERMISSION_GRANTED) { 2673 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2674 + Binder.getCallingPid() 2675 + ", uid=" + Binder.getCallingUid() 2676 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2677 Slog.w(TAG, msg); 2678 throw new SecurityException(msg); 2679 } 2680 2681 synchronized(this) { 2682 if (mHeavyWeightProcess == null) { 2683 return; 2684 } 2685 2686 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2687 mHeavyWeightProcess.activities); 2688 for (int i=0; i<activities.size(); i++) { 2689 ActivityRecord r = activities.get(i); 2690 if (!r.finishing) { 2691 int index = mMainStack.indexOfTokenLocked(r.appToken); 2692 if (index >= 0) { 2693 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2694 null, "finish-heavy"); 2695 } 2696 } 2697 } 2698 2699 mHeavyWeightProcess = null; 2700 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2701 } 2702 } 2703 2704 public void crashApplication(int uid, int initialPid, String packageName, 2705 String message) { 2706 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2707 != PackageManager.PERMISSION_GRANTED) { 2708 String msg = "Permission Denial: crashApplication() from pid=" 2709 + Binder.getCallingPid() 2710 + ", uid=" + Binder.getCallingUid() 2711 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2712 Slog.w(TAG, msg); 2713 throw new SecurityException(msg); 2714 } 2715 2716 synchronized(this) { 2717 ProcessRecord proc = null; 2718 2719 // Figure out which process to kill. We don't trust that initialPid 2720 // still has any relation to current pids, so must scan through the 2721 // list. 2722 synchronized (mPidsSelfLocked) { 2723 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2724 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2725 if (p.uid != uid) { 2726 continue; 2727 } 2728 if (p.pid == initialPid) { 2729 proc = p; 2730 break; 2731 } 2732 for (String str : p.pkgList) { 2733 if (str.equals(packageName)) { 2734 proc = p; 2735 } 2736 } 2737 } 2738 } 2739 2740 if (proc == null) { 2741 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2742 + " initialPid=" + initialPid 2743 + " packageName=" + packageName); 2744 return; 2745 } 2746 2747 if (proc.thread != null) { 2748 if (proc.pid == Process.myPid()) { 2749 Log.w(TAG, "crashApplication: trying to crash self!"); 2750 return; 2751 } 2752 long ident = Binder.clearCallingIdentity(); 2753 try { 2754 proc.thread.scheduleCrash(message); 2755 } catch (RemoteException e) { 2756 } 2757 Binder.restoreCallingIdentity(ident); 2758 } 2759 } 2760 } 2761 2762 public final void finishSubActivity(IBinder token, String resultWho, 2763 int requestCode) { 2764 synchronized(this) { 2765 final long origId = Binder.clearCallingIdentity(); 2766 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2767 Binder.restoreCallingIdentity(origId); 2768 } 2769 } 2770 2771 public boolean finishActivityAffinity(IBinder token) { 2772 synchronized(this) { 2773 final long origId = Binder.clearCallingIdentity(); 2774 boolean res = mMainStack.finishActivityAffinityLocked(token); 2775 Binder.restoreCallingIdentity(origId); 2776 return res; 2777 } 2778 } 2779 2780 public boolean willActivityBeVisible(IBinder token) { 2781 synchronized(this) { 2782 int i; 2783 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2784 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2785 if (r.appToken == token) { 2786 return true; 2787 } 2788 if (r.fullscreen && !r.finishing) { 2789 return false; 2790 } 2791 } 2792 return true; 2793 } 2794 } 2795 2796 public void overridePendingTransition(IBinder token, String packageName, 2797 int enterAnim, int exitAnim) { 2798 synchronized(this) { 2799 ActivityRecord self = mMainStack.isInStackLocked(token); 2800 if (self == null) { 2801 return; 2802 } 2803 2804 final long origId = Binder.clearCallingIdentity(); 2805 2806 if (self.state == ActivityState.RESUMED 2807 || self.state == ActivityState.PAUSING) { 2808 mWindowManager.overridePendingAppTransition(packageName, 2809 enterAnim, exitAnim, null); 2810 } 2811 2812 Binder.restoreCallingIdentity(origId); 2813 } 2814 } 2815 2816 /** 2817 * Main function for removing an existing process from the activity manager 2818 * as a result of that process going away. Clears out all connections 2819 * to the process. 2820 */ 2821 private final void handleAppDiedLocked(ProcessRecord app, 2822 boolean restarting, boolean allowRestart) { 2823 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2824 if (!restarting) { 2825 mLruProcesses.remove(app); 2826 } 2827 2828 if (mProfileProc == app) { 2829 clearProfilerLocked(); 2830 } 2831 2832 // Just in case... 2833 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2834 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2835 mMainStack.mPausingActivity = null; 2836 } 2837 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2838 mMainStack.mLastPausedActivity = null; 2839 } 2840 2841 // Remove this application's activities from active lists. 2842 mMainStack.removeHistoryRecordsForAppLocked(app); 2843 2844 boolean atTop = true; 2845 boolean hasVisibleActivities = false; 2846 2847 // Clean out the history list. 2848 int i = mMainStack.mHistory.size(); 2849 if (localLOGV) Slog.v( 2850 TAG, "Removing app " + app + " from history with " + i + " entries"); 2851 while (i > 0) { 2852 i--; 2853 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2854 if (localLOGV) Slog.v( 2855 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2856 if (r.app == app) { 2857 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2858 if (ActivityStack.DEBUG_ADD_REMOVE) { 2859 RuntimeException here = new RuntimeException("here"); 2860 here.fillInStackTrace(); 2861 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2862 + ": haveState=" + r.haveState 2863 + " stateNotNeeded=" + r.stateNotNeeded 2864 + " finishing=" + r.finishing 2865 + " state=" + r.state, here); 2866 } 2867 if (!r.finishing) { 2868 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2869 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2870 System.identityHashCode(r), 2871 r.task.taskId, r.shortComponentName, 2872 "proc died without state saved"); 2873 } 2874 mMainStack.removeActivityFromHistoryLocked(r); 2875 2876 } else { 2877 // We have the current state for this activity, so 2878 // it can be restarted later when needed. 2879 if (localLOGV) Slog.v( 2880 TAG, "Keeping entry, setting app to null"); 2881 if (r.visible) { 2882 hasVisibleActivities = true; 2883 } 2884 r.app = null; 2885 r.nowVisible = false; 2886 if (!r.haveState) { 2887 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2888 "App died, clearing saved state of " + r); 2889 r.icicle = null; 2890 } 2891 } 2892 2893 r.stack.cleanUpActivityLocked(r, true, true); 2894 } 2895 atTop = false; 2896 } 2897 2898 app.activities.clear(); 2899 2900 if (app.instrumentationClass != null) { 2901 Slog.w(TAG, "Crash of app " + app.processName 2902 + " running instrumentation " + app.instrumentationClass); 2903 Bundle info = new Bundle(); 2904 info.putString("shortMsg", "Process crashed."); 2905 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2906 } 2907 2908 if (!restarting) { 2909 if (!mMainStack.resumeTopActivityLocked(null)) { 2910 // If there was nothing to resume, and we are not already 2911 // restarting this process, but there is a visible activity that 2912 // is hosted by the process... then make sure all visible 2913 // activities are running, taking care of restarting this 2914 // process. 2915 if (hasVisibleActivities) { 2916 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2917 } 2918 } 2919 } 2920 } 2921 2922 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2923 IBinder threadBinder = thread.asBinder(); 2924 // Find the application record. 2925 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2926 ProcessRecord rec = mLruProcesses.get(i); 2927 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2928 return i; 2929 } 2930 } 2931 return -1; 2932 } 2933 2934 final ProcessRecord getRecordForAppLocked( 2935 IApplicationThread thread) { 2936 if (thread == null) { 2937 return null; 2938 } 2939 2940 int appIndex = getLRURecordIndexForAppLocked(thread); 2941 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2942 } 2943 2944 final void appDiedLocked(ProcessRecord app, int pid, 2945 IApplicationThread thread) { 2946 2947 mProcDeaths[0]++; 2948 2949 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2950 synchronized (stats) { 2951 stats.noteProcessDiedLocked(app.info.uid, pid); 2952 } 2953 2954 // Clean up already done if the process has been re-started. 2955 if (app.pid == pid && app.thread != null && 2956 app.thread.asBinder() == thread.asBinder()) { 2957 if (!app.killedBackground) { 2958 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2959 + ") has died."); 2960 } 2961 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2962 if (localLOGV) Slog.v( 2963 TAG, "Dying app: " + app + ", pid: " + pid 2964 + ", thread: " + thread.asBinder()); 2965 boolean doLowMem = app.instrumentationClass == null; 2966 handleAppDiedLocked(app, false, true); 2967 2968 if (doLowMem) { 2969 // If there are no longer any background processes running, 2970 // and the app that died was not running instrumentation, 2971 // then tell everyone we are now low on memory. 2972 boolean haveBg = false; 2973 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2974 ProcessRecord rec = mLruProcesses.get(i); 2975 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2976 haveBg = true; 2977 break; 2978 } 2979 } 2980 2981 if (!haveBg) { 2982 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2983 long now = SystemClock.uptimeMillis(); 2984 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2985 ProcessRecord rec = mLruProcesses.get(i); 2986 if (rec != app && rec.thread != null && 2987 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2988 // The low memory report is overriding any current 2989 // state for a GC request. Make sure to do 2990 // heavy/important/visible/foreground processes first. 2991 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2992 rec.lastRequestedGc = 0; 2993 } else { 2994 rec.lastRequestedGc = rec.lastLowMemory; 2995 } 2996 rec.reportLowMemory = true; 2997 rec.lastLowMemory = now; 2998 mProcessesToGc.remove(rec); 2999 addProcessToGcListLocked(rec); 3000 } 3001 } 3002 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3003 scheduleAppGcsLocked(); 3004 } 3005 } 3006 } else if (app.pid != pid) { 3007 // A new process has already been started. 3008 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3009 + ") has died and restarted (pid " + app.pid + ")."); 3010 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3011 } else if (DEBUG_PROCESSES) { 3012 Slog.d(TAG, "Received spurious death notification for thread " 3013 + thread.asBinder()); 3014 } 3015 } 3016 3017 /** 3018 * If a stack trace dump file is configured, dump process stack traces. 3019 * @param clearTraces causes the dump file to be erased prior to the new 3020 * traces being written, if true; when false, the new traces will be 3021 * appended to any existing file content. 3022 * @param firstPids of dalvik VM processes to dump stack traces for first 3023 * @param lastPids of dalvik VM processes to dump stack traces for last 3024 * @param nativeProcs optional list of native process names to dump stack crawls 3025 * @return file containing stack traces, or null if no dump file is configured 3026 */ 3027 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3028 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3029 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3030 if (tracesPath == null || tracesPath.length() == 0) { 3031 return null; 3032 } 3033 3034 File tracesFile = new File(tracesPath); 3035 try { 3036 File tracesDir = tracesFile.getParentFile(); 3037 if (!tracesDir.exists()) tracesFile.mkdirs(); 3038 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3039 3040 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3041 tracesFile.createNewFile(); 3042 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3043 } catch (IOException e) { 3044 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3045 return null; 3046 } 3047 3048 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3049 return tracesFile; 3050 } 3051 3052 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3053 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3054 // Use a FileObserver to detect when traces finish writing. 3055 // The order of traces is considered important to maintain for legibility. 3056 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3057 public synchronized void onEvent(int event, String path) { notify(); } 3058 }; 3059 3060 try { 3061 observer.startWatching(); 3062 3063 // First collect all of the stacks of the most important pids. 3064 if (firstPids != null) { 3065 try { 3066 int num = firstPids.size(); 3067 for (int i = 0; i < num; i++) { 3068 synchronized (observer) { 3069 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3070 observer.wait(200); // Wait for write-close, give up after 200msec 3071 } 3072 } 3073 } catch (InterruptedException e) { 3074 Log.wtf(TAG, e); 3075 } 3076 } 3077 3078 // Next measure CPU usage. 3079 if (processStats != null) { 3080 processStats.init(); 3081 System.gc(); 3082 processStats.update(); 3083 try { 3084 synchronized (processStats) { 3085 processStats.wait(500); // measure over 1/2 second. 3086 } 3087 } catch (InterruptedException e) { 3088 } 3089 processStats.update(); 3090 3091 // We'll take the stack crawls of just the top apps using CPU. 3092 final int N = processStats.countWorkingStats(); 3093 int numProcs = 0; 3094 for (int i=0; i<N && numProcs<5; i++) { 3095 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3096 if (lastPids.indexOfKey(stats.pid) >= 0) { 3097 numProcs++; 3098 try { 3099 synchronized (observer) { 3100 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3101 observer.wait(200); // Wait for write-close, give up after 200msec 3102 } 3103 } catch (InterruptedException e) { 3104 Log.wtf(TAG, e); 3105 } 3106 3107 } 3108 } 3109 } 3110 3111 } finally { 3112 observer.stopWatching(); 3113 } 3114 3115 if (nativeProcs != null) { 3116 int[] pids = Process.getPidsForCommands(nativeProcs); 3117 if (pids != null) { 3118 for (int pid : pids) { 3119 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3120 } 3121 } 3122 } 3123 } 3124 3125 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3126 if (true || IS_USER_BUILD) { 3127 return; 3128 } 3129 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3130 if (tracesPath == null || tracesPath.length() == 0) { 3131 return; 3132 } 3133 3134 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3135 StrictMode.allowThreadDiskWrites(); 3136 try { 3137 final File tracesFile = new File(tracesPath); 3138 final File tracesDir = tracesFile.getParentFile(); 3139 final File tracesTmp = new File(tracesDir, "__tmp__"); 3140 try { 3141 if (!tracesDir.exists()) tracesFile.mkdirs(); 3142 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3143 3144 if (tracesFile.exists()) { 3145 tracesTmp.delete(); 3146 tracesFile.renameTo(tracesTmp); 3147 } 3148 StringBuilder sb = new StringBuilder(); 3149 Time tobj = new Time(); 3150 tobj.set(System.currentTimeMillis()); 3151 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3152 sb.append(": "); 3153 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3154 sb.append(" since "); 3155 sb.append(msg); 3156 FileOutputStream fos = new FileOutputStream(tracesFile); 3157 fos.write(sb.toString().getBytes()); 3158 if (app == null) { 3159 fos.write("\n*** No application process!".getBytes()); 3160 } 3161 fos.close(); 3162 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3163 } catch (IOException e) { 3164 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3165 return; 3166 } 3167 3168 if (app != null) { 3169 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3170 firstPids.add(app.pid); 3171 dumpStackTraces(tracesPath, firstPids, null, null, null); 3172 } 3173 3174 File lastTracesFile = null; 3175 File curTracesFile = null; 3176 for (int i=9; i>=0; i--) { 3177 String name = String.format("slow%02d.txt", i); 3178 curTracesFile = new File(tracesDir, name); 3179 if (curTracesFile.exists()) { 3180 if (lastTracesFile != null) { 3181 curTracesFile.renameTo(lastTracesFile); 3182 } else { 3183 curTracesFile.delete(); 3184 } 3185 } 3186 lastTracesFile = curTracesFile; 3187 } 3188 tracesFile.renameTo(curTracesFile); 3189 if (tracesTmp.exists()) { 3190 tracesTmp.renameTo(tracesFile); 3191 } 3192 } finally { 3193 StrictMode.setThreadPolicy(oldPolicy); 3194 } 3195 } 3196 3197 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3198 ActivityRecord parent, final String annotation) { 3199 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3200 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3201 3202 if (mController != null) { 3203 try { 3204 // 0 == continue, -1 = kill process immediately 3205 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3206 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3207 } catch (RemoteException e) { 3208 mController = null; 3209 } 3210 } 3211 3212 long anrTime = SystemClock.uptimeMillis(); 3213 if (MONITOR_CPU_USAGE) { 3214 updateCpuStatsNow(); 3215 } 3216 3217 synchronized (this) { 3218 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3219 if (mShuttingDown) { 3220 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3221 return; 3222 } else if (app.notResponding) { 3223 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3224 return; 3225 } else if (app.crashing) { 3226 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3227 return; 3228 } 3229 3230 // In case we come through here for the same app before completing 3231 // this one, mark as anring now so we will bail out. 3232 app.notResponding = true; 3233 3234 // Log the ANR to the event log. 3235 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3236 annotation); 3237 3238 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3239 firstPids.add(app.pid); 3240 3241 int parentPid = app.pid; 3242 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3243 if (parentPid != app.pid) firstPids.add(parentPid); 3244 3245 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3246 3247 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3248 ProcessRecord r = mLruProcesses.get(i); 3249 if (r != null && r.thread != null) { 3250 int pid = r.pid; 3251 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3252 if (r.persistent) { 3253 firstPids.add(pid); 3254 } else { 3255 lastPids.put(pid, Boolean.TRUE); 3256 } 3257 } 3258 } 3259 } 3260 } 3261 3262 // Log the ANR to the main log. 3263 StringBuilder info = new StringBuilder(); 3264 info.setLength(0); 3265 info.append("ANR in ").append(app.processName); 3266 if (activity != null && activity.shortComponentName != null) { 3267 info.append(" (").append(activity.shortComponentName).append(")"); 3268 } 3269 info.append("\n"); 3270 if (annotation != null) { 3271 info.append("Reason: ").append(annotation).append("\n"); 3272 } 3273 if (parent != null && parent != activity) { 3274 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3275 } 3276 3277 final ProcessStats processStats = new ProcessStats(true); 3278 3279 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3280 3281 String cpuInfo = null; 3282 if (MONITOR_CPU_USAGE) { 3283 updateCpuStatsNow(); 3284 synchronized (mProcessStatsThread) { 3285 cpuInfo = mProcessStats.printCurrentState(anrTime); 3286 } 3287 info.append(processStats.printCurrentLoad()); 3288 info.append(cpuInfo); 3289 } 3290 3291 info.append(processStats.printCurrentState(anrTime)); 3292 3293 Slog.e(TAG, info.toString()); 3294 if (tracesFile == null) { 3295 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3296 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3297 } 3298 3299 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3300 cpuInfo, tracesFile, null); 3301 3302 if (mController != null) { 3303 try { 3304 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3305 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3306 if (res != 0) { 3307 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3308 return; 3309 } 3310 } catch (RemoteException e) { 3311 mController = null; 3312 } 3313 } 3314 3315 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3316 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3317 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3318 3319 synchronized (this) { 3320 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3321 Slog.w(TAG, "Killing " + app + ": background ANR"); 3322 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3323 app.processName, app.setAdj, "background ANR"); 3324 Process.killProcessQuiet(app.pid); 3325 return; 3326 } 3327 3328 // Set the app's notResponding state, and look up the errorReportReceiver 3329 makeAppNotRespondingLocked(app, 3330 activity != null ? activity.shortComponentName : null, 3331 annotation != null ? "ANR " + annotation : "ANR", 3332 info.toString()); 3333 3334 // Bring up the infamous App Not Responding dialog 3335 Message msg = Message.obtain(); 3336 HashMap map = new HashMap(); 3337 msg.what = SHOW_NOT_RESPONDING_MSG; 3338 msg.obj = map; 3339 map.put("app", app); 3340 if (activity != null) { 3341 map.put("activity", activity); 3342 } 3343 3344 mHandler.sendMessage(msg); 3345 } 3346 } 3347 3348 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3349 if (!mLaunchWarningShown) { 3350 mLaunchWarningShown = true; 3351 mHandler.post(new Runnable() { 3352 @Override 3353 public void run() { 3354 synchronized (ActivityManagerService.this) { 3355 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3356 d.show(); 3357 mHandler.postDelayed(new Runnable() { 3358 @Override 3359 public void run() { 3360 synchronized (ActivityManagerService.this) { 3361 d.dismiss(); 3362 mLaunchWarningShown = false; 3363 } 3364 } 3365 }, 4000); 3366 } 3367 } 3368 }); 3369 } 3370 } 3371 3372 public boolean clearApplicationUserData(final String packageName, 3373 final IPackageDataObserver observer, final int userId) { 3374 enforceNotIsolatedCaller("clearApplicationUserData"); 3375 int uid = Binder.getCallingUid(); 3376 int pid = Binder.getCallingPid(); 3377 long callingId = Binder.clearCallingIdentity(); 3378 try { 3379 IPackageManager pm = AppGlobals.getPackageManager(); 3380 int pkgUid = -1; 3381 synchronized(this) { 3382 try { 3383 pkgUid = pm.getPackageUid(packageName, userId); 3384 } catch (RemoteException e) { 3385 } 3386 if (pkgUid == -1) { 3387 Slog.w(TAG, "Invalid packageName:" + packageName); 3388 return false; 3389 } 3390 if (uid == pkgUid || checkComponentPermission( 3391 android.Manifest.permission.CLEAR_APP_USER_DATA, 3392 pid, uid, -1, true) 3393 == PackageManager.PERMISSION_GRANTED) { 3394 forceStopPackageLocked(packageName, pkgUid); 3395 } else { 3396 throw new SecurityException(pid+" does not have permission:"+ 3397 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3398 "for process:"+packageName); 3399 } 3400 } 3401 3402 try { 3403 //clear application user data 3404 pm.clearApplicationUserData(packageName, observer, userId); 3405 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3406 Uri.fromParts("package", packageName, null)); 3407 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3408 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3409 null, null, 0, null, null, null, false, false, userId); 3410 } catch (RemoteException e) { 3411 } 3412 } finally { 3413 Binder.restoreCallingIdentity(callingId); 3414 } 3415 return true; 3416 } 3417 3418 public void killBackgroundProcesses(final String packageName) { 3419 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3420 != PackageManager.PERMISSION_GRANTED && 3421 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3422 != PackageManager.PERMISSION_GRANTED) { 3423 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3424 + Binder.getCallingPid() 3425 + ", uid=" + Binder.getCallingUid() 3426 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3427 Slog.w(TAG, msg); 3428 throw new SecurityException(msg); 3429 } 3430 3431 int userId = UserHandle.getCallingUserId(); 3432 long callingId = Binder.clearCallingIdentity(); 3433 try { 3434 IPackageManager pm = AppGlobals.getPackageManager(); 3435 int pkgUid = -1; 3436 synchronized(this) { 3437 try { 3438 pkgUid = pm.getPackageUid(packageName, userId); 3439 } catch (RemoteException e) { 3440 } 3441 if (pkgUid == -1) { 3442 Slog.w(TAG, "Invalid packageName: " + packageName); 3443 return; 3444 } 3445 killPackageProcessesLocked(packageName, pkgUid, 3446 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3447 } 3448 } finally { 3449 Binder.restoreCallingIdentity(callingId); 3450 } 3451 } 3452 3453 public void killAllBackgroundProcesses() { 3454 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3455 != PackageManager.PERMISSION_GRANTED) { 3456 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3457 + Binder.getCallingPid() 3458 + ", uid=" + Binder.getCallingUid() 3459 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3460 Slog.w(TAG, msg); 3461 throw new SecurityException(msg); 3462 } 3463 3464 long callingId = Binder.clearCallingIdentity(); 3465 try { 3466 synchronized(this) { 3467 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3468 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3469 final int NA = apps.size(); 3470 for (int ia=0; ia<NA; ia++) { 3471 ProcessRecord app = apps.valueAt(ia); 3472 if (app.persistent) { 3473 // we don't kill persistent processes 3474 continue; 3475 } 3476 if (app.removed) { 3477 procs.add(app); 3478 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3479 app.removed = true; 3480 procs.add(app); 3481 } 3482 } 3483 } 3484 3485 int N = procs.size(); 3486 for (int i=0; i<N; i++) { 3487 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3488 } 3489 } 3490 } finally { 3491 Binder.restoreCallingIdentity(callingId); 3492 } 3493 } 3494 3495 public void forceStopPackage(final String packageName) { 3496 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3497 != PackageManager.PERMISSION_GRANTED) { 3498 String msg = "Permission Denial: forceStopPackage() from pid=" 3499 + Binder.getCallingPid() 3500 + ", uid=" + Binder.getCallingUid() 3501 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3502 Slog.w(TAG, msg); 3503 throw new SecurityException(msg); 3504 } 3505 final int userId = UserHandle.getCallingUserId(); 3506 long callingId = Binder.clearCallingIdentity(); 3507 try { 3508 IPackageManager pm = AppGlobals.getPackageManager(); 3509 int pkgUid = -1; 3510 synchronized(this) { 3511 try { 3512 pkgUid = pm.getPackageUid(packageName, userId); 3513 } catch (RemoteException e) { 3514 } 3515 if (pkgUid == -1) { 3516 Slog.w(TAG, "Invalid packageName: " + packageName); 3517 return; 3518 } 3519 forceStopPackageLocked(packageName, pkgUid); 3520 try { 3521 pm.setPackageStoppedState(packageName, true, userId); 3522 } catch (RemoteException e) { 3523 } catch (IllegalArgumentException e) { 3524 Slog.w(TAG, "Failed trying to unstop package " 3525 + packageName + ": " + e); 3526 } 3527 } 3528 } finally { 3529 Binder.restoreCallingIdentity(callingId); 3530 } 3531 } 3532 3533 /* 3534 * The pkg name and uid have to be specified. 3535 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3536 */ 3537 public void killApplicationWithUid(String pkg, int uid) { 3538 if (pkg == null) { 3539 return; 3540 } 3541 // Make sure the uid is valid. 3542 if (uid < 0) { 3543 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3544 return; 3545 } 3546 int callerUid = Binder.getCallingUid(); 3547 // Only the system server can kill an application 3548 if (callerUid == Process.SYSTEM_UID) { 3549 // Post an aysnc message to kill the application 3550 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3551 msg.arg1 = uid; 3552 msg.arg2 = 0; 3553 msg.obj = pkg; 3554 mHandler.sendMessage(msg); 3555 } else { 3556 throw new SecurityException(callerUid + " cannot kill pkg: " + 3557 pkg); 3558 } 3559 } 3560 3561 public void closeSystemDialogs(String reason) { 3562 enforceNotIsolatedCaller("closeSystemDialogs"); 3563 3564 final int uid = Binder.getCallingUid(); 3565 final long origId = Binder.clearCallingIdentity(); 3566 synchronized (this) { 3567 closeSystemDialogsLocked(uid, reason); 3568 } 3569 Binder.restoreCallingIdentity(origId); 3570 } 3571 3572 void closeSystemDialogsLocked(int callingUid, String reason) { 3573 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3574 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3575 if (reason != null) { 3576 intent.putExtra("reason", reason); 3577 } 3578 mWindowManager.closeSystemDialogs(reason); 3579 3580 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3581 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3582 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3583 r.stack.finishActivityLocked(r, i, 3584 Activity.RESULT_CANCELED, null, "close-sys"); 3585 } 3586 } 3587 3588 broadcastIntentLocked(null, null, intent, null, 3589 null, 0, null, null, null, false, false, -1, 3590 callingUid, 0 /* TODO: Verify */); 3591 } 3592 3593 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3594 throws RemoteException { 3595 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3596 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3597 for (int i=pids.length-1; i>=0; i--) { 3598 infos[i] = new Debug.MemoryInfo(); 3599 Debug.getMemoryInfo(pids[i], infos[i]); 3600 } 3601 return infos; 3602 } 3603 3604 public long[] getProcessPss(int[] pids) throws RemoteException { 3605 enforceNotIsolatedCaller("getProcessPss"); 3606 long[] pss = new long[pids.length]; 3607 for (int i=pids.length-1; i>=0; i--) { 3608 pss[i] = Debug.getPss(pids[i]); 3609 } 3610 return pss; 3611 } 3612 3613 public void killApplicationProcess(String processName, int uid) { 3614 if (processName == null) { 3615 return; 3616 } 3617 3618 int callerUid = Binder.getCallingUid(); 3619 // Only the system server can kill an application 3620 if (callerUid == Process.SYSTEM_UID) { 3621 synchronized (this) { 3622 ProcessRecord app = getProcessRecordLocked(processName, uid); 3623 if (app != null && app.thread != null) { 3624 try { 3625 app.thread.scheduleSuicide(); 3626 } catch (RemoteException e) { 3627 // If the other end already died, then our work here is done. 3628 } 3629 } else { 3630 Slog.w(TAG, "Process/uid not found attempting kill of " 3631 + processName + " / " + uid); 3632 } 3633 } 3634 } else { 3635 throw new SecurityException(callerUid + " cannot kill app process: " + 3636 processName); 3637 } 3638 } 3639 3640 private void forceStopPackageLocked(final String packageName, int uid) { 3641 forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid)); 3642 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3643 Uri.fromParts("package", packageName, null)); 3644 if (!mProcessesReady) { 3645 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3646 } 3647 intent.putExtra(Intent.EXTRA_UID, uid); 3648 broadcastIntentLocked(null, null, intent, 3649 null, null, 0, null, null, null, 3650 false, false, 3651 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3652 } 3653 3654 private final boolean killPackageProcessesLocked(String packageName, int uid, 3655 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3656 boolean evenPersistent, String reason) { 3657 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3658 3659 // Remove all processes this package may have touched: all with the 3660 // same UID (except for the system or root user), and all whose name 3661 // matches the package name. 3662 final String procNamePrefix = packageName + ":"; 3663 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3664 final int NA = apps.size(); 3665 for (int ia=0; ia<NA; ia++) { 3666 ProcessRecord app = apps.valueAt(ia); 3667 if (app.persistent && !evenPersistent) { 3668 // we don't kill persistent processes 3669 continue; 3670 } 3671 if (app.removed) { 3672 if (doit) { 3673 procs.add(app); 3674 } 3675 // If uid is specified and the uid and process name match 3676 // Or, the uid is not specified and the process name matches 3677 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3678 || ((app.processName.equals(packageName) 3679 || app.processName.startsWith(procNamePrefix)) 3680 && uid < 0))) { 3681 if (app.setAdj >= minOomAdj) { 3682 if (!doit) { 3683 return true; 3684 } 3685 app.removed = true; 3686 procs.add(app); 3687 } 3688 } 3689 } 3690 } 3691 3692 int N = procs.size(); 3693 for (int i=0; i<N; i++) { 3694 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3695 } 3696 return N > 0; 3697 } 3698 3699 private final boolean forceStopPackageLocked(String name, int uid, 3700 boolean callerWillRestart, boolean purgeCache, boolean doit, 3701 boolean evenPersistent, int userId) { 3702 int i; 3703 int N; 3704 3705 if (uid < 0) { 3706 try { 3707 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3708 } catch (RemoteException e) { 3709 } 3710 } 3711 3712 if (doit) { 3713 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3714 3715 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3716 while (badApps.hasNext()) { 3717 SparseArray<Long> ba = badApps.next(); 3718 if (ba.get(uid) != null) { 3719 badApps.remove(); 3720 } 3721 } 3722 } 3723 3724 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3725 callerWillRestart, false, doit, evenPersistent, "force stop"); 3726 3727 TaskRecord lastTask = null; 3728 for (i=0; i<mMainStack.mHistory.size(); i++) { 3729 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3730 final boolean samePackage = r.packageName.equals(name); 3731 if (r.userId == userId 3732 && (samePackage || r.task == lastTask) 3733 && (r.app == null || evenPersistent || !r.app.persistent)) { 3734 if (!doit) { 3735 if (r.finishing) { 3736 // If this activity is just finishing, then it is not 3737 // interesting as far as something to stop. 3738 continue; 3739 } 3740 return true; 3741 } 3742 didSomething = true; 3743 Slog.i(TAG, " Force finishing activity " + r); 3744 if (samePackage) { 3745 if (r.app != null) { 3746 r.app.removed = true; 3747 } 3748 r.app = null; 3749 } 3750 lastTask = r.task; 3751 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3752 null, "force-stop", true)) { 3753 i--; 3754 } 3755 } 3756 } 3757 3758 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3759 if (!doit) { 3760 return true; 3761 } 3762 didSomething = true; 3763 } 3764 3765 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3766 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3767 if (provider.info.packageName.equals(name) 3768 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3769 if (!doit) { 3770 return true; 3771 } 3772 didSomething = true; 3773 providers.add(provider); 3774 } 3775 } 3776 3777 N = providers.size(); 3778 for (i=0; i<N; i++) { 3779 removeDyingProviderLocked(null, providers.get(i), true); 3780 } 3781 3782 if (doit) { 3783 if (purgeCache) { 3784 AttributeCache ac = AttributeCache.instance(); 3785 if (ac != null) { 3786 ac.removePackage(name); 3787 } 3788 } 3789 if (mBooted) { 3790 mMainStack.resumeTopActivityLocked(null); 3791 mMainStack.scheduleIdleLocked(); 3792 } 3793 } 3794 3795 return didSomething; 3796 } 3797 3798 private final boolean removeProcessLocked(ProcessRecord app, 3799 boolean callerWillRestart, boolean allowRestart, String reason) { 3800 final String name = app.processName; 3801 final int uid = app.uid; 3802 if (DEBUG_PROCESSES) Slog.d( 3803 TAG, "Force removing proc " + app.toShortString() + " (" + name 3804 + "/" + uid + ")"); 3805 3806 mProcessNames.remove(name, uid); 3807 mIsolatedProcesses.remove(app.uid); 3808 if (mHeavyWeightProcess == app) { 3809 mHeavyWeightProcess = null; 3810 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3811 } 3812 boolean needRestart = false; 3813 if (app.pid > 0 && app.pid != MY_PID) { 3814 int pid = app.pid; 3815 synchronized (mPidsSelfLocked) { 3816 mPidsSelfLocked.remove(pid); 3817 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3818 } 3819 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3820 handleAppDiedLocked(app, true, allowRestart); 3821 mLruProcesses.remove(app); 3822 Process.killProcessQuiet(pid); 3823 3824 if (app.persistent && !app.isolated) { 3825 if (!callerWillRestart) { 3826 addAppLocked(app.info, false); 3827 } else { 3828 needRestart = true; 3829 } 3830 } 3831 } else { 3832 mRemovedProcesses.add(app); 3833 } 3834 3835 return needRestart; 3836 } 3837 3838 private final void processStartTimedOutLocked(ProcessRecord app) { 3839 final int pid = app.pid; 3840 boolean gone = false; 3841 synchronized (mPidsSelfLocked) { 3842 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3843 if (knownApp != null && knownApp.thread == null) { 3844 mPidsSelfLocked.remove(pid); 3845 gone = true; 3846 } 3847 } 3848 3849 if (gone) { 3850 Slog.w(TAG, "Process " + app + " failed to attach"); 3851 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3852 app.processName); 3853 mProcessNames.remove(app.processName, app.uid); 3854 mIsolatedProcesses.remove(app.uid); 3855 if (mHeavyWeightProcess == app) { 3856 mHeavyWeightProcess = null; 3857 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3858 } 3859 // Take care of any launching providers waiting for this process. 3860 checkAppInLaunchingProvidersLocked(app, true); 3861 // Take care of any services that are waiting for the process. 3862 mServices.processStartTimedOutLocked(app); 3863 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3864 app.processName, app.setAdj, "start timeout"); 3865 Process.killProcessQuiet(pid); 3866 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3867 Slog.w(TAG, "Unattached app died before backup, skipping"); 3868 try { 3869 IBackupManager bm = IBackupManager.Stub.asInterface( 3870 ServiceManager.getService(Context.BACKUP_SERVICE)); 3871 bm.agentDisconnected(app.info.packageName); 3872 } catch (RemoteException e) { 3873 // Can't happen; the backup manager is local 3874 } 3875 } 3876 if (isPendingBroadcastProcessLocked(pid)) { 3877 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3878 skipPendingBroadcastLocked(pid); 3879 } 3880 } else { 3881 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3882 } 3883 } 3884 3885 private final boolean attachApplicationLocked(IApplicationThread thread, 3886 int pid) { 3887 3888 // Find the application record that is being attached... either via 3889 // the pid if we are running in multiple processes, or just pull the 3890 // next app record if we are emulating process with anonymous threads. 3891 ProcessRecord app; 3892 if (pid != MY_PID && pid >= 0) { 3893 synchronized (mPidsSelfLocked) { 3894 app = mPidsSelfLocked.get(pid); 3895 } 3896 } else { 3897 app = null; 3898 } 3899 3900 if (app == null) { 3901 Slog.w(TAG, "No pending application record for pid " + pid 3902 + " (IApplicationThread " + thread + "); dropping process"); 3903 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3904 if (pid > 0 && pid != MY_PID) { 3905 Process.killProcessQuiet(pid); 3906 } else { 3907 try { 3908 thread.scheduleExit(); 3909 } catch (Exception e) { 3910 // Ignore exceptions. 3911 } 3912 } 3913 return false; 3914 } 3915 3916 // If this application record is still attached to a previous 3917 // process, clean it up now. 3918 if (app.thread != null) { 3919 handleAppDiedLocked(app, true, true); 3920 } 3921 3922 // Tell the process all about itself. 3923 3924 if (localLOGV) Slog.v( 3925 TAG, "Binding process pid " + pid + " to record " + app); 3926 3927 String processName = app.processName; 3928 try { 3929 AppDeathRecipient adr = new AppDeathRecipient( 3930 app, pid, thread); 3931 thread.asBinder().linkToDeath(adr, 0); 3932 app.deathRecipient = adr; 3933 } catch (RemoteException e) { 3934 app.resetPackageList(); 3935 startProcessLocked(app, "link fail", processName); 3936 return false; 3937 } 3938 3939 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3940 3941 app.thread = thread; 3942 app.curAdj = app.setAdj = -100; 3943 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3944 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3945 app.forcingToForeground = null; 3946 app.foregroundServices = false; 3947 app.hasShownUi = false; 3948 app.debugging = false; 3949 3950 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3951 3952 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3953 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3954 3955 if (!normalMode) { 3956 Slog.i(TAG, "Launching preboot mode app: " + app); 3957 } 3958 3959 if (localLOGV) Slog.v( 3960 TAG, "New app record " + app 3961 + " thread=" + thread.asBinder() + " pid=" + pid); 3962 try { 3963 int testMode = IApplicationThread.DEBUG_OFF; 3964 if (mDebugApp != null && mDebugApp.equals(processName)) { 3965 testMode = mWaitForDebugger 3966 ? IApplicationThread.DEBUG_WAIT 3967 : IApplicationThread.DEBUG_ON; 3968 app.debugging = true; 3969 if (mDebugTransient) { 3970 mDebugApp = mOrigDebugApp; 3971 mWaitForDebugger = mOrigWaitForDebugger; 3972 } 3973 } 3974 String profileFile = app.instrumentationProfileFile; 3975 ParcelFileDescriptor profileFd = null; 3976 boolean profileAutoStop = false; 3977 if (mProfileApp != null && mProfileApp.equals(processName)) { 3978 mProfileProc = app; 3979 profileFile = mProfileFile; 3980 profileFd = mProfileFd; 3981 profileAutoStop = mAutoStopProfiler; 3982 } 3983 boolean enableOpenGlTrace = false; 3984 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3985 enableOpenGlTrace = true; 3986 mOpenGlTraceApp = null; 3987 } 3988 3989 // If the app is being launched for restore or full backup, set it up specially 3990 boolean isRestrictedBackupMode = false; 3991 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 3992 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 3993 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 3994 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 3995 } 3996 3997 ensurePackageDexOpt(app.instrumentationInfo != null 3998 ? app.instrumentationInfo.packageName 3999 : app.info.packageName); 4000 if (app.instrumentationClass != null) { 4001 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4002 } 4003 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4004 + processName + " with config " + mConfiguration); 4005 ApplicationInfo appInfo = app.instrumentationInfo != null 4006 ? app.instrumentationInfo : app.info; 4007 app.compat = compatibilityInfoForPackageLocked(appInfo); 4008 if (profileFd != null) { 4009 profileFd = profileFd.dup(); 4010 } 4011 thread.bindApplication(processName, appInfo, providers, 4012 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4013 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4014 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4015 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4016 mCoreSettingsObserver.getCoreSettingsLocked()); 4017 updateLruProcessLocked(app, false, true); 4018 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4019 } catch (Exception e) { 4020 // todo: Yikes! What should we do? For now we will try to 4021 // start another process, but that could easily get us in 4022 // an infinite loop of restarting processes... 4023 Slog.w(TAG, "Exception thrown during bind!", e); 4024 4025 app.resetPackageList(); 4026 app.unlinkDeathRecipient(); 4027 startProcessLocked(app, "bind fail", processName); 4028 return false; 4029 } 4030 4031 // Remove this record from the list of starting applications. 4032 mPersistentStartingProcesses.remove(app); 4033 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4034 "Attach application locked removing on hold: " + app); 4035 mProcessesOnHold.remove(app); 4036 4037 boolean badApp = false; 4038 boolean didSomething = false; 4039 4040 // See if the top visible activity is waiting to run in this process... 4041 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4042 if (hr != null && normalMode) { 4043 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4044 && processName.equals(hr.processName)) { 4045 try { 4046 if (mHeadless) { 4047 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4048 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4049 didSomething = true; 4050 } 4051 } catch (Exception e) { 4052 Slog.w(TAG, "Exception in new application when starting activity " 4053 + hr.intent.getComponent().flattenToShortString(), e); 4054 badApp = true; 4055 } 4056 } else { 4057 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4058 } 4059 } 4060 4061 // Find any services that should be running in this process... 4062 if (!badApp) { 4063 try { 4064 didSomething |= mServices.attachApplicationLocked(app, processName); 4065 } catch (Exception e) { 4066 badApp = true; 4067 } 4068 } 4069 4070 // Check if a next-broadcast receiver is in this process... 4071 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4072 try { 4073 didSomething = sendPendingBroadcastsLocked(app); 4074 } catch (Exception e) { 4075 // If the app died trying to launch the receiver we declare it 'bad' 4076 badApp = true; 4077 } 4078 } 4079 4080 // Check whether the next backup agent is in this process... 4081 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4082 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4083 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4084 try { 4085 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4086 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4087 mBackupTarget.backupMode); 4088 } catch (Exception e) { 4089 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4090 e.printStackTrace(); 4091 } 4092 } 4093 4094 if (badApp) { 4095 // todo: Also need to kill application to deal with all 4096 // kinds of exceptions. 4097 handleAppDiedLocked(app, false, true); 4098 return false; 4099 } 4100 4101 if (!didSomething) { 4102 updateOomAdjLocked(); 4103 } 4104 4105 return true; 4106 } 4107 4108 public final void attachApplication(IApplicationThread thread) { 4109 synchronized (this) { 4110 int callingPid = Binder.getCallingPid(); 4111 final long origId = Binder.clearCallingIdentity(); 4112 attachApplicationLocked(thread, callingPid); 4113 Binder.restoreCallingIdentity(origId); 4114 } 4115 } 4116 4117 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4118 final long origId = Binder.clearCallingIdentity(); 4119 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4120 if (stopProfiling) { 4121 synchronized (this) { 4122 if (mProfileProc == r.app) { 4123 if (mProfileFd != null) { 4124 try { 4125 mProfileFd.close(); 4126 } catch (IOException e) { 4127 } 4128 clearProfilerLocked(); 4129 } 4130 } 4131 } 4132 } 4133 Binder.restoreCallingIdentity(origId); 4134 } 4135 4136 void enableScreenAfterBoot() { 4137 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4138 SystemClock.uptimeMillis()); 4139 mWindowManager.enableScreenAfterBoot(); 4140 4141 synchronized (this) { 4142 updateEventDispatchingLocked(); 4143 } 4144 } 4145 4146 public void showBootMessage(final CharSequence msg, final boolean always) { 4147 enforceNotIsolatedCaller("showBootMessage"); 4148 mWindowManager.showBootMessage(msg, always); 4149 } 4150 4151 public void dismissKeyguardOnNextActivity() { 4152 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4153 final long token = Binder.clearCallingIdentity(); 4154 try { 4155 synchronized (this) { 4156 if (mLockScreenShown) { 4157 mLockScreenShown = false; 4158 comeOutOfSleepIfNeededLocked(); 4159 } 4160 mMainStack.dismissKeyguardOnNextActivityLocked(); 4161 } 4162 } finally { 4163 Binder.restoreCallingIdentity(token); 4164 } 4165 } 4166 4167 final void finishBooting() { 4168 IntentFilter pkgFilter = new IntentFilter(); 4169 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4170 pkgFilter.addDataScheme("package"); 4171 mContext.registerReceiver(new BroadcastReceiver() { 4172 @Override 4173 public void onReceive(Context context, Intent intent) { 4174 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4175 if (pkgs != null) { 4176 for (String pkg : pkgs) { 4177 synchronized (ActivityManagerService.this) { 4178 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4179 setResultCode(Activity.RESULT_OK); 4180 return; 4181 } 4182 } 4183 } 4184 } 4185 } 4186 }, pkgFilter); 4187 4188 IntentFilter userFilter = new IntentFilter(); 4189 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4190 mContext.registerReceiver(new BroadcastReceiver() { 4191 @Override 4192 public void onReceive(Context context, Intent intent) { 4193 onUserRemoved(intent); 4194 } 4195 }, userFilter); 4196 4197 synchronized (this) { 4198 // Ensure that any processes we had put on hold are now started 4199 // up. 4200 final int NP = mProcessesOnHold.size(); 4201 if (NP > 0) { 4202 ArrayList<ProcessRecord> procs = 4203 new ArrayList<ProcessRecord>(mProcessesOnHold); 4204 for (int ip=0; ip<NP; ip++) { 4205 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4206 + procs.get(ip)); 4207 startProcessLocked(procs.get(ip), "on-hold", null); 4208 } 4209 } 4210 4211 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4212 // Start looking for apps that are abusing wake locks. 4213 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4214 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4215 // Tell anyone interested that we are done booting! 4216 SystemProperties.set("sys.boot_completed", "1"); 4217 SystemProperties.set("dev.bootcomplete", "1"); 4218 List<UserInfo> users = getUserManager().getUsers(); 4219 for (UserInfo user : users) { 4220 broadcastIntentLocked(null, null, 4221 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4222 null, null, 0, null, null, 4223 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4224 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4225 } 4226 } 4227 } 4228 } 4229 4230 final void ensureBootCompleted() { 4231 boolean booting; 4232 boolean enableScreen; 4233 synchronized (this) { 4234 booting = mBooting; 4235 mBooting = false; 4236 enableScreen = !mBooted; 4237 mBooted = true; 4238 } 4239 4240 if (booting) { 4241 finishBooting(); 4242 } 4243 4244 if (enableScreen) { 4245 enableScreenAfterBoot(); 4246 } 4247 } 4248 4249 public final void activityPaused(IBinder token) { 4250 final long origId = Binder.clearCallingIdentity(); 4251 mMainStack.activityPaused(token, false); 4252 Binder.restoreCallingIdentity(origId); 4253 } 4254 4255 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4256 CharSequence description) { 4257 if (localLOGV) Slog.v( 4258 TAG, "Activity stopped: token=" + token); 4259 4260 // Refuse possible leaked file descriptors 4261 if (icicle != null && icicle.hasFileDescriptors()) { 4262 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4263 } 4264 4265 ActivityRecord r = null; 4266 4267 final long origId = Binder.clearCallingIdentity(); 4268 4269 synchronized (this) { 4270 r = mMainStack.isInStackLocked(token); 4271 if (r != null) { 4272 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4273 } 4274 } 4275 4276 if (r != null) { 4277 sendPendingThumbnail(r, null, null, null, false); 4278 } 4279 4280 trimApplications(); 4281 4282 Binder.restoreCallingIdentity(origId); 4283 } 4284 4285 public final void activityDestroyed(IBinder token) { 4286 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4287 mMainStack.activityDestroyed(token); 4288 } 4289 4290 public String getCallingPackage(IBinder token) { 4291 synchronized (this) { 4292 ActivityRecord r = getCallingRecordLocked(token); 4293 return r != null && r.app != null ? r.info.packageName : null; 4294 } 4295 } 4296 4297 public ComponentName getCallingActivity(IBinder token) { 4298 synchronized (this) { 4299 ActivityRecord r = getCallingRecordLocked(token); 4300 return r != null ? r.intent.getComponent() : null; 4301 } 4302 } 4303 4304 private ActivityRecord getCallingRecordLocked(IBinder token) { 4305 ActivityRecord r = mMainStack.isInStackLocked(token); 4306 if (r == null) { 4307 return null; 4308 } 4309 return r.resultTo; 4310 } 4311 4312 public ComponentName getActivityClassForToken(IBinder token) { 4313 synchronized(this) { 4314 ActivityRecord r = mMainStack.isInStackLocked(token); 4315 if (r == null) { 4316 return null; 4317 } 4318 return r.intent.getComponent(); 4319 } 4320 } 4321 4322 public String getPackageForToken(IBinder token) { 4323 synchronized(this) { 4324 ActivityRecord r = mMainStack.isInStackLocked(token); 4325 if (r == null) { 4326 return null; 4327 } 4328 return r.packageName; 4329 } 4330 } 4331 4332 public IIntentSender getIntentSender(int type, 4333 String packageName, IBinder token, String resultWho, 4334 int requestCode, Intent[] intents, String[] resolvedTypes, 4335 int flags, Bundle options) { 4336 enforceNotIsolatedCaller("getIntentSender"); 4337 // Refuse possible leaked file descriptors 4338 if (intents != null) { 4339 if (intents.length < 1) { 4340 throw new IllegalArgumentException("Intents array length must be >= 1"); 4341 } 4342 for (int i=0; i<intents.length; i++) { 4343 Intent intent = intents[i]; 4344 if (intent != null) { 4345 if (intent.hasFileDescriptors()) { 4346 throw new IllegalArgumentException("File descriptors passed in Intent"); 4347 } 4348 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4349 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4350 throw new IllegalArgumentException( 4351 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4352 } 4353 intents[i] = new Intent(intent); 4354 } 4355 } 4356 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4357 throw new IllegalArgumentException( 4358 "Intent array length does not match resolvedTypes length"); 4359 } 4360 } 4361 if (options != null) { 4362 if (options.hasFileDescriptors()) { 4363 throw new IllegalArgumentException("File descriptors passed in options"); 4364 } 4365 } 4366 4367 synchronized(this) { 4368 int callingUid = Binder.getCallingUid(); 4369 try { 4370 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4371 int uid = AppGlobals.getPackageManager() 4372 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4373 if (!UserHandle.isSameApp(callingUid, uid)) { 4374 String msg = "Permission Denial: getIntentSender() from pid=" 4375 + Binder.getCallingPid() 4376 + ", uid=" + Binder.getCallingUid() 4377 + ", (need uid=" + uid + ")" 4378 + " is not allowed to send as package " + packageName; 4379 Slog.w(TAG, msg); 4380 throw new SecurityException(msg); 4381 } 4382 } 4383 4384 if (DEBUG_MU) 4385 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4386 + Binder.getOrigCallingUid()); 4387 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4388 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4389 4390 } catch (RemoteException e) { 4391 throw new SecurityException(e); 4392 } 4393 } 4394 } 4395 4396 IIntentSender getIntentSenderLocked(int type, 4397 String packageName, int callingUid, IBinder token, String resultWho, 4398 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4399 Bundle options) { 4400 if (DEBUG_MU) 4401 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4402 ActivityRecord activity = null; 4403 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4404 activity = mMainStack.isInStackLocked(token); 4405 if (activity == null) { 4406 return null; 4407 } 4408 if (activity.finishing) { 4409 return null; 4410 } 4411 } 4412 4413 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4414 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4415 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4416 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4417 |PendingIntent.FLAG_UPDATE_CURRENT); 4418 4419 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4420 type, packageName, activity, resultWho, 4421 requestCode, intents, resolvedTypes, flags, options); 4422 WeakReference<PendingIntentRecord> ref; 4423 ref = mIntentSenderRecords.get(key); 4424 PendingIntentRecord rec = ref != null ? ref.get() : null; 4425 if (rec != null) { 4426 if (!cancelCurrent) { 4427 if (updateCurrent) { 4428 if (rec.key.requestIntent != null) { 4429 rec.key.requestIntent.replaceExtras(intents != null ? 4430 intents[intents.length - 1] : null); 4431 } 4432 if (intents != null) { 4433 intents[intents.length-1] = rec.key.requestIntent; 4434 rec.key.allIntents = intents; 4435 rec.key.allResolvedTypes = resolvedTypes; 4436 } else { 4437 rec.key.allIntents = null; 4438 rec.key.allResolvedTypes = null; 4439 } 4440 } 4441 return rec; 4442 } 4443 rec.canceled = true; 4444 mIntentSenderRecords.remove(key); 4445 } 4446 if (noCreate) { 4447 return rec; 4448 } 4449 rec = new PendingIntentRecord(this, key, callingUid); 4450 mIntentSenderRecords.put(key, rec.ref); 4451 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4452 if (activity.pendingResults == null) { 4453 activity.pendingResults 4454 = new HashSet<WeakReference<PendingIntentRecord>>(); 4455 } 4456 activity.pendingResults.add(rec.ref); 4457 } 4458 return rec; 4459 } 4460 4461 public void cancelIntentSender(IIntentSender sender) { 4462 if (!(sender instanceof PendingIntentRecord)) { 4463 return; 4464 } 4465 synchronized(this) { 4466 PendingIntentRecord rec = (PendingIntentRecord)sender; 4467 try { 4468 int uid = AppGlobals.getPackageManager() 4469 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4470 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4471 String msg = "Permission Denial: cancelIntentSender() from pid=" 4472 + Binder.getCallingPid() 4473 + ", uid=" + Binder.getCallingUid() 4474 + " is not allowed to cancel packges " 4475 + rec.key.packageName; 4476 Slog.w(TAG, msg); 4477 throw new SecurityException(msg); 4478 } 4479 } catch (RemoteException e) { 4480 throw new SecurityException(e); 4481 } 4482 cancelIntentSenderLocked(rec, true); 4483 } 4484 } 4485 4486 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4487 rec.canceled = true; 4488 mIntentSenderRecords.remove(rec.key); 4489 if (cleanActivity && rec.key.activity != null) { 4490 rec.key.activity.pendingResults.remove(rec.ref); 4491 } 4492 } 4493 4494 public String getPackageForIntentSender(IIntentSender pendingResult) { 4495 if (!(pendingResult instanceof PendingIntentRecord)) { 4496 return null; 4497 } 4498 try { 4499 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4500 return res.key.packageName; 4501 } catch (ClassCastException e) { 4502 } 4503 return null; 4504 } 4505 4506 public int getUidForIntentSender(IIntentSender sender) { 4507 if (sender instanceof PendingIntentRecord) { 4508 try { 4509 PendingIntentRecord res = (PendingIntentRecord)sender; 4510 return res.uid; 4511 } catch (ClassCastException e) { 4512 } 4513 } 4514 return -1; 4515 } 4516 4517 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4518 if (!(pendingResult instanceof PendingIntentRecord)) { 4519 return false; 4520 } 4521 try { 4522 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4523 if (res.key.allIntents == null) { 4524 return false; 4525 } 4526 for (int i=0; i<res.key.allIntents.length; i++) { 4527 Intent intent = res.key.allIntents[i]; 4528 if (intent.getPackage() != null && intent.getComponent() != null) { 4529 return false; 4530 } 4531 } 4532 return true; 4533 } catch (ClassCastException e) { 4534 } 4535 return false; 4536 } 4537 4538 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4539 if (!(pendingResult instanceof PendingIntentRecord)) { 4540 return false; 4541 } 4542 try { 4543 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4544 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4545 return true; 4546 } 4547 return false; 4548 } catch (ClassCastException e) { 4549 } 4550 return false; 4551 } 4552 4553 public void setProcessLimit(int max) { 4554 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4555 "setProcessLimit()"); 4556 synchronized (this) { 4557 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4558 mProcessLimitOverride = max; 4559 } 4560 trimApplications(); 4561 } 4562 4563 public int getProcessLimit() { 4564 synchronized (this) { 4565 return mProcessLimitOverride; 4566 } 4567 } 4568 4569 void foregroundTokenDied(ForegroundToken token) { 4570 synchronized (ActivityManagerService.this) { 4571 synchronized (mPidsSelfLocked) { 4572 ForegroundToken cur 4573 = mForegroundProcesses.get(token.pid); 4574 if (cur != token) { 4575 return; 4576 } 4577 mForegroundProcesses.remove(token.pid); 4578 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4579 if (pr == null) { 4580 return; 4581 } 4582 pr.forcingToForeground = null; 4583 pr.foregroundServices = false; 4584 } 4585 updateOomAdjLocked(); 4586 } 4587 } 4588 4589 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4590 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4591 "setProcessForeground()"); 4592 synchronized(this) { 4593 boolean changed = false; 4594 4595 synchronized (mPidsSelfLocked) { 4596 ProcessRecord pr = mPidsSelfLocked.get(pid); 4597 if (pr == null && isForeground) { 4598 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4599 return; 4600 } 4601 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4602 if (oldToken != null) { 4603 oldToken.token.unlinkToDeath(oldToken, 0); 4604 mForegroundProcesses.remove(pid); 4605 if (pr != null) { 4606 pr.forcingToForeground = null; 4607 } 4608 changed = true; 4609 } 4610 if (isForeground && token != null) { 4611 ForegroundToken newToken = new ForegroundToken() { 4612 public void binderDied() { 4613 foregroundTokenDied(this); 4614 } 4615 }; 4616 newToken.pid = pid; 4617 newToken.token = token; 4618 try { 4619 token.linkToDeath(newToken, 0); 4620 mForegroundProcesses.put(pid, newToken); 4621 pr.forcingToForeground = token; 4622 changed = true; 4623 } catch (RemoteException e) { 4624 // If the process died while doing this, we will later 4625 // do the cleanup with the process death link. 4626 } 4627 } 4628 } 4629 4630 if (changed) { 4631 updateOomAdjLocked(); 4632 } 4633 } 4634 } 4635 4636 // ========================================================= 4637 // PERMISSIONS 4638 // ========================================================= 4639 4640 static class PermissionController extends IPermissionController.Stub { 4641 ActivityManagerService mActivityManagerService; 4642 PermissionController(ActivityManagerService activityManagerService) { 4643 mActivityManagerService = activityManagerService; 4644 } 4645 4646 public boolean checkPermission(String permission, int pid, int uid) { 4647 return mActivityManagerService.checkPermission(permission, pid, 4648 uid) == PackageManager.PERMISSION_GRANTED; 4649 } 4650 } 4651 4652 /** 4653 * This can be called with or without the global lock held. 4654 */ 4655 int checkComponentPermission(String permission, int pid, int uid, 4656 int owningUid, boolean exported) { 4657 // We might be performing an operation on behalf of an indirect binder 4658 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4659 // client identity accordingly before proceeding. 4660 Identity tlsIdentity = sCallerIdentity.get(); 4661 if (tlsIdentity != null) { 4662 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4663 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4664 uid = tlsIdentity.uid; 4665 pid = tlsIdentity.pid; 4666 } 4667 4668 if (pid == MY_PID) { 4669 return PackageManager.PERMISSION_GRANTED; 4670 } 4671 4672 return ActivityManager.checkComponentPermission(permission, uid, 4673 owningUid, exported); 4674 } 4675 4676 /** 4677 * As the only public entry point for permissions checking, this method 4678 * can enforce the semantic that requesting a check on a null global 4679 * permission is automatically denied. (Internally a null permission 4680 * string is used when calling {@link #checkComponentPermission} in cases 4681 * when only uid-based security is needed.) 4682 * 4683 * This can be called with or without the global lock held. 4684 */ 4685 public int checkPermission(String permission, int pid, int uid) { 4686 if (permission == null) { 4687 return PackageManager.PERMISSION_DENIED; 4688 } 4689 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4690 } 4691 4692 /** 4693 * Binder IPC calls go through the public entry point. 4694 * This can be called with or without the global lock held. 4695 */ 4696 int checkCallingPermission(String permission) { 4697 return checkPermission(permission, 4698 Binder.getCallingPid(), 4699 UserHandle.getAppId(Binder.getCallingUid())); 4700 } 4701 4702 /** 4703 * This can be called with or without the global lock held. 4704 */ 4705 void enforceCallingPermission(String permission, String func) { 4706 if (checkCallingPermission(permission) 4707 == PackageManager.PERMISSION_GRANTED) { 4708 return; 4709 } 4710 4711 String msg = "Permission Denial: " + func + " from pid=" 4712 + Binder.getCallingPid() 4713 + ", uid=" + Binder.getCallingUid() 4714 + " requires " + permission; 4715 Slog.w(TAG, msg); 4716 throw new SecurityException(msg); 4717 } 4718 4719 /** 4720 * Determine if UID is holding permissions required to access {@link Uri} in 4721 * the given {@link ProviderInfo}. Final permission checking is always done 4722 * in {@link ContentProvider}. 4723 */ 4724 private final boolean checkHoldingPermissionsLocked( 4725 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4726 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4727 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4728 4729 if (pi.applicationInfo.uid == uid) { 4730 return true; 4731 } else if (!pi.exported) { 4732 return false; 4733 } 4734 4735 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4736 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4737 try { 4738 // check if target holds top-level <provider> permissions 4739 if (!readMet && pi.readPermission != null 4740 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4741 readMet = true; 4742 } 4743 if (!writeMet && pi.writePermission != null 4744 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4745 writeMet = true; 4746 } 4747 4748 // track if unprotected read/write is allowed; any denied 4749 // <path-permission> below removes this ability 4750 boolean allowDefaultRead = pi.readPermission == null; 4751 boolean allowDefaultWrite = pi.writePermission == null; 4752 4753 // check if target holds any <path-permission> that match uri 4754 final PathPermission[] pps = pi.pathPermissions; 4755 if (pps != null) { 4756 final String path = uri.getPath(); 4757 int i = pps.length; 4758 while (i > 0 && (!readMet || !writeMet)) { 4759 i--; 4760 PathPermission pp = pps[i]; 4761 if (pp.match(path)) { 4762 if (!readMet) { 4763 final String pprperm = pp.getReadPermission(); 4764 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4765 + pprperm + " for " + pp.getPath() 4766 + ": match=" + pp.match(path) 4767 + " check=" + pm.checkUidPermission(pprperm, uid)); 4768 if (pprperm != null) { 4769 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4770 readMet = true; 4771 } else { 4772 allowDefaultRead = false; 4773 } 4774 } 4775 } 4776 if (!writeMet) { 4777 final String ppwperm = pp.getWritePermission(); 4778 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4779 + ppwperm + " for " + pp.getPath() 4780 + ": match=" + pp.match(path) 4781 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4782 if (ppwperm != null) { 4783 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4784 writeMet = true; 4785 } else { 4786 allowDefaultWrite = false; 4787 } 4788 } 4789 } 4790 } 4791 } 4792 } 4793 4794 // grant unprotected <provider> read/write, if not blocked by 4795 // <path-permission> above 4796 if (allowDefaultRead) readMet = true; 4797 if (allowDefaultWrite) writeMet = true; 4798 4799 } catch (RemoteException e) { 4800 return false; 4801 } 4802 4803 return readMet && writeMet; 4804 } 4805 4806 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4807 int modeFlags) { 4808 // Root gets to do everything. 4809 if (uid == 0) { 4810 return true; 4811 } 4812 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4813 if (perms == null) return false; 4814 UriPermission perm = perms.get(uri); 4815 if (perm == null) return false; 4816 return (modeFlags&perm.modeFlags) == modeFlags; 4817 } 4818 4819 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4820 enforceNotIsolatedCaller("checkUriPermission"); 4821 4822 // Another redirected-binder-call permissions check as in 4823 // {@link checkComponentPermission}. 4824 Identity tlsIdentity = sCallerIdentity.get(); 4825 if (tlsIdentity != null) { 4826 uid = tlsIdentity.uid; 4827 pid = tlsIdentity.pid; 4828 } 4829 4830 uid = UserHandle.getAppId(uid); 4831 // Our own process gets to do everything. 4832 if (pid == MY_PID) { 4833 return PackageManager.PERMISSION_GRANTED; 4834 } 4835 synchronized(this) { 4836 return checkUriPermissionLocked(uri, uid, modeFlags) 4837 ? PackageManager.PERMISSION_GRANTED 4838 : PackageManager.PERMISSION_DENIED; 4839 } 4840 } 4841 4842 /** 4843 * Check if the targetPkg can be granted permission to access uri by 4844 * the callingUid using the given modeFlags. Throws a security exception 4845 * if callingUid is not allowed to do this. Returns the uid of the target 4846 * if the URI permission grant should be performed; returns -1 if it is not 4847 * needed (for example targetPkg already has permission to access the URI). 4848 * If you already know the uid of the target, you can supply it in 4849 * lastTargetUid else set that to -1. 4850 */ 4851 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4852 Uri uri, int modeFlags, int lastTargetUid) { 4853 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4854 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4855 if (modeFlags == 0) { 4856 return -1; 4857 } 4858 4859 if (targetPkg != null) { 4860 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4861 "Checking grant " + targetPkg + " permission to " + uri); 4862 } 4863 4864 final IPackageManager pm = AppGlobals.getPackageManager(); 4865 4866 // If this is not a content: uri, we can't do anything with it. 4867 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4868 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4869 "Can't grant URI permission for non-content URI: " + uri); 4870 return -1; 4871 } 4872 4873 String name = uri.getAuthority(); 4874 ProviderInfo pi = null; 4875 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4876 UserHandle.getUserId(callingUid)); 4877 if (cpr != null) { 4878 pi = cpr.info; 4879 } else { 4880 try { 4881 pi = pm.resolveContentProvider(name, 4882 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4883 } catch (RemoteException ex) { 4884 } 4885 } 4886 if (pi == null) { 4887 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4888 return -1; 4889 } 4890 4891 int targetUid = lastTargetUid; 4892 if (targetUid < 0 && targetPkg != null) { 4893 try { 4894 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4895 if (targetUid < 0) { 4896 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4897 "Can't grant URI permission no uid for: " + targetPkg); 4898 return -1; 4899 } 4900 } catch (RemoteException ex) { 4901 return -1; 4902 } 4903 } 4904 4905 if (targetUid >= 0) { 4906 // First... does the target actually need this permission? 4907 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4908 // No need to grant the target this permission. 4909 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4910 "Target " + targetPkg + " already has full permission to " + uri); 4911 return -1; 4912 } 4913 } else { 4914 // First... there is no target package, so can anyone access it? 4915 boolean allowed = pi.exported; 4916 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4917 if (pi.readPermission != null) { 4918 allowed = false; 4919 } 4920 } 4921 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4922 if (pi.writePermission != null) { 4923 allowed = false; 4924 } 4925 } 4926 if (allowed) { 4927 return -1; 4928 } 4929 } 4930 4931 // Second... is the provider allowing granting of URI permissions? 4932 if (!pi.grantUriPermissions) { 4933 throw new SecurityException("Provider " + pi.packageName 4934 + "/" + pi.name 4935 + " does not allow granting of Uri permissions (uri " 4936 + uri + ")"); 4937 } 4938 if (pi.uriPermissionPatterns != null) { 4939 final int N = pi.uriPermissionPatterns.length; 4940 boolean allowed = false; 4941 for (int i=0; i<N; i++) { 4942 if (pi.uriPermissionPatterns[i] != null 4943 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4944 allowed = true; 4945 break; 4946 } 4947 } 4948 if (!allowed) { 4949 throw new SecurityException("Provider " + pi.packageName 4950 + "/" + pi.name 4951 + " does not allow granting of permission to path of Uri " 4952 + uri); 4953 } 4954 } 4955 4956 // Third... does the caller itself have permission to access 4957 // this uri? 4958 if (callingUid != Process.myUid()) { 4959 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4960 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4961 throw new SecurityException("Uid " + callingUid 4962 + " does not have permission to uri " + uri); 4963 } 4964 } 4965 } 4966 4967 return targetUid; 4968 } 4969 4970 public int checkGrantUriPermission(int callingUid, String targetPkg, 4971 Uri uri, int modeFlags) { 4972 enforceNotIsolatedCaller("checkGrantUriPermission"); 4973 synchronized(this) { 4974 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4975 } 4976 } 4977 4978 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4979 Uri uri, int modeFlags, UriPermissionOwner owner) { 4980 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4981 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4982 if (modeFlags == 0) { 4983 return; 4984 } 4985 4986 // So here we are: the caller has the assumed permission 4987 // to the uri, and the target doesn't. Let's now give this to 4988 // the target. 4989 4990 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4991 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 4992 4993 HashMap<Uri, UriPermission> targetUris 4994 = mGrantedUriPermissions.get(targetUid); 4995 if (targetUris == null) { 4996 targetUris = new HashMap<Uri, UriPermission>(); 4997 mGrantedUriPermissions.put(targetUid, targetUris); 4998 } 4999 5000 UriPermission perm = targetUris.get(uri); 5001 if (perm == null) { 5002 perm = new UriPermission(targetUid, uri); 5003 targetUris.put(uri, perm); 5004 } 5005 5006 perm.modeFlags |= modeFlags; 5007 if (owner == null) { 5008 perm.globalModeFlags |= modeFlags; 5009 } else { 5010 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5011 perm.readOwners.add(owner); 5012 owner.addReadPermission(perm); 5013 } 5014 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5015 perm.writeOwners.add(owner); 5016 owner.addWritePermission(perm); 5017 } 5018 } 5019 } 5020 5021 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5022 int modeFlags, UriPermissionOwner owner) { 5023 if (targetPkg == null) { 5024 throw new NullPointerException("targetPkg"); 5025 } 5026 5027 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5028 if (targetUid < 0) { 5029 return; 5030 } 5031 5032 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5033 } 5034 5035 static class NeededUriGrants extends ArrayList<Uri> { 5036 final String targetPkg; 5037 final int targetUid; 5038 final int flags; 5039 5040 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5041 targetPkg = _targetPkg; 5042 targetUid = _targetUid; 5043 flags = _flags; 5044 } 5045 } 5046 5047 /** 5048 * Like checkGrantUriPermissionLocked, but takes an Intent. 5049 */ 5050 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5051 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5052 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5053 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5054 + " clip=" + (intent != null ? intent.getClipData() : null) 5055 + " from " + intent + "; flags=0x" 5056 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5057 5058 if (targetPkg == null) { 5059 throw new NullPointerException("targetPkg"); 5060 } 5061 5062 if (intent == null) { 5063 return null; 5064 } 5065 Uri data = intent.getData(); 5066 ClipData clip = intent.getClipData(); 5067 if (data == null && clip == null) { 5068 return null; 5069 } 5070 if (data != null) { 5071 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5072 mode, needed != null ? needed.targetUid : -1); 5073 if (target > 0) { 5074 if (needed == null) { 5075 needed = new NeededUriGrants(targetPkg, target, mode); 5076 } 5077 needed.add(data); 5078 } 5079 } 5080 if (clip != null) { 5081 for (int i=0; i<clip.getItemCount(); i++) { 5082 Uri uri = clip.getItemAt(i).getUri(); 5083 if (uri != null) { 5084 int target = -1; 5085 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5086 mode, needed != null ? needed.targetUid : -1); 5087 if (target > 0) { 5088 if (needed == null) { 5089 needed = new NeededUriGrants(targetPkg, target, mode); 5090 } 5091 needed.add(uri); 5092 } 5093 } else { 5094 Intent clipIntent = clip.getItemAt(i).getIntent(); 5095 if (clipIntent != null) { 5096 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5097 callingUid, targetPkg, clipIntent, mode, needed); 5098 if (newNeeded != null) { 5099 needed = newNeeded; 5100 } 5101 } 5102 } 5103 } 5104 } 5105 5106 return needed; 5107 } 5108 5109 /** 5110 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5111 */ 5112 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5113 UriPermissionOwner owner) { 5114 if (needed != null) { 5115 for (int i=0; i<needed.size(); i++) { 5116 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5117 needed.get(i), needed.flags, owner); 5118 } 5119 } 5120 } 5121 5122 void grantUriPermissionFromIntentLocked(int callingUid, 5123 String targetPkg, Intent intent, UriPermissionOwner owner) { 5124 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5125 intent, intent != null ? intent.getFlags() : 0, null); 5126 if (needed == null) { 5127 return; 5128 } 5129 5130 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5131 } 5132 5133 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5134 Uri uri, int modeFlags) { 5135 enforceNotIsolatedCaller("grantUriPermission"); 5136 synchronized(this) { 5137 final ProcessRecord r = getRecordForAppLocked(caller); 5138 if (r == null) { 5139 throw new SecurityException("Unable to find app for caller " 5140 + caller 5141 + " when granting permission to uri " + uri); 5142 } 5143 if (targetPkg == null) { 5144 throw new IllegalArgumentException("null target"); 5145 } 5146 if (uri == null) { 5147 throw new IllegalArgumentException("null uri"); 5148 } 5149 5150 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5151 null); 5152 } 5153 } 5154 5155 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5156 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5157 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5158 HashMap<Uri, UriPermission> perms 5159 = mGrantedUriPermissions.get(perm.uid); 5160 if (perms != null) { 5161 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5162 "Removing " + perm.uid + " permission to " + perm.uri); 5163 perms.remove(perm.uri); 5164 if (perms.size() == 0) { 5165 mGrantedUriPermissions.remove(perm.uid); 5166 } 5167 } 5168 } 5169 } 5170 5171 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5172 int modeFlags) { 5173 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5174 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5175 if (modeFlags == 0) { 5176 return; 5177 } 5178 5179 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5180 "Revoking all granted permissions to " + uri); 5181 5182 final IPackageManager pm = AppGlobals.getPackageManager(); 5183 5184 final String authority = uri.getAuthority(); 5185 ProviderInfo pi = null; 5186 int userId = UserHandle.getUserId(callingUid); 5187 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5188 if (cpr != null) { 5189 pi = cpr.info; 5190 } else { 5191 try { 5192 pi = pm.resolveContentProvider(authority, 5193 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5194 } catch (RemoteException ex) { 5195 } 5196 } 5197 if (pi == null) { 5198 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5199 return; 5200 } 5201 5202 // Does the caller have this permission on the URI? 5203 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5204 // Right now, if you are not the original owner of the permission, 5205 // you are not allowed to revoke it. 5206 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5207 throw new SecurityException("Uid " + callingUid 5208 + " does not have permission to uri " + uri); 5209 //} 5210 } 5211 5212 // Go through all of the permissions and remove any that match. 5213 final List<String> SEGMENTS = uri.getPathSegments(); 5214 if (SEGMENTS != null) { 5215 final int NS = SEGMENTS.size(); 5216 int N = mGrantedUriPermissions.size(); 5217 for (int i=0; i<N; i++) { 5218 HashMap<Uri, UriPermission> perms 5219 = mGrantedUriPermissions.valueAt(i); 5220 Iterator<UriPermission> it = perms.values().iterator(); 5221 toploop: 5222 while (it.hasNext()) { 5223 UriPermission perm = it.next(); 5224 Uri targetUri = perm.uri; 5225 if (!authority.equals(targetUri.getAuthority())) { 5226 continue; 5227 } 5228 List<String> targetSegments = targetUri.getPathSegments(); 5229 if (targetSegments == null) { 5230 continue; 5231 } 5232 if (targetSegments.size() < NS) { 5233 continue; 5234 } 5235 for (int j=0; j<NS; j++) { 5236 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5237 continue toploop; 5238 } 5239 } 5240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5241 "Revoking " + perm.uid + " permission to " + perm.uri); 5242 perm.clearModes(modeFlags); 5243 if (perm.modeFlags == 0) { 5244 it.remove(); 5245 } 5246 } 5247 if (perms.size() == 0) { 5248 mGrantedUriPermissions.remove( 5249 mGrantedUriPermissions.keyAt(i)); 5250 N--; 5251 i--; 5252 } 5253 } 5254 } 5255 } 5256 5257 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5258 int modeFlags) { 5259 enforceNotIsolatedCaller("revokeUriPermission"); 5260 synchronized(this) { 5261 final ProcessRecord r = getRecordForAppLocked(caller); 5262 if (r == null) { 5263 throw new SecurityException("Unable to find app for caller " 5264 + caller 5265 + " when revoking permission to uri " + uri); 5266 } 5267 if (uri == null) { 5268 Slog.w(TAG, "revokeUriPermission: null uri"); 5269 return; 5270 } 5271 5272 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5273 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5274 if (modeFlags == 0) { 5275 return; 5276 } 5277 5278 final IPackageManager pm = AppGlobals.getPackageManager(); 5279 5280 final String authority = uri.getAuthority(); 5281 ProviderInfo pi = null; 5282 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5283 if (cpr != null) { 5284 pi = cpr.info; 5285 } else { 5286 try { 5287 pi = pm.resolveContentProvider(authority, 5288 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5289 } catch (RemoteException ex) { 5290 } 5291 } 5292 if (pi == null) { 5293 Slog.w(TAG, "No content provider found for permission revoke: " 5294 + uri.toSafeString()); 5295 return; 5296 } 5297 5298 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5299 } 5300 } 5301 5302 @Override 5303 public IBinder newUriPermissionOwner(String name) { 5304 enforceNotIsolatedCaller("newUriPermissionOwner"); 5305 synchronized(this) { 5306 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5307 return owner.getExternalTokenLocked(); 5308 } 5309 } 5310 5311 @Override 5312 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5313 Uri uri, int modeFlags) { 5314 synchronized(this) { 5315 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5316 if (owner == null) { 5317 throw new IllegalArgumentException("Unknown owner: " + token); 5318 } 5319 if (fromUid != Binder.getCallingUid()) { 5320 if (Binder.getCallingUid() != Process.myUid()) { 5321 // Only system code can grant URI permissions on behalf 5322 // of other users. 5323 throw new SecurityException("nice try"); 5324 } 5325 } 5326 if (targetPkg == null) { 5327 throw new IllegalArgumentException("null target"); 5328 } 5329 if (uri == null) { 5330 throw new IllegalArgumentException("null uri"); 5331 } 5332 5333 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5334 } 5335 } 5336 5337 @Override 5338 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5339 synchronized(this) { 5340 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5341 if (owner == null) { 5342 throw new IllegalArgumentException("Unknown owner: " + token); 5343 } 5344 5345 if (uri == null) { 5346 owner.removeUriPermissionsLocked(mode); 5347 } else { 5348 owner.removeUriPermissionLocked(uri, mode); 5349 } 5350 } 5351 } 5352 5353 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5354 synchronized (this) { 5355 ProcessRecord app = 5356 who != null ? getRecordForAppLocked(who) : null; 5357 if (app == null) return; 5358 5359 Message msg = Message.obtain(); 5360 msg.what = WAIT_FOR_DEBUGGER_MSG; 5361 msg.obj = app; 5362 msg.arg1 = waiting ? 1 : 0; 5363 mHandler.sendMessage(msg); 5364 } 5365 } 5366 5367 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5368 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5369 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5370 outInfo.availMem = Process.getFreeMemory(); 5371 outInfo.totalMem = Process.getTotalMemory(); 5372 outInfo.threshold = homeAppMem; 5373 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5374 outInfo.hiddenAppThreshold = hiddenAppMem; 5375 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5376 ProcessList.SERVICE_ADJ); 5377 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5378 ProcessList.VISIBLE_APP_ADJ); 5379 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5380 ProcessList.FOREGROUND_APP_ADJ); 5381 } 5382 5383 // ========================================================= 5384 // TASK MANAGEMENT 5385 // ========================================================= 5386 5387 public List getTasks(int maxNum, int flags, 5388 IThumbnailReceiver receiver) { 5389 ArrayList list = new ArrayList(); 5390 5391 PendingThumbnailsRecord pending = null; 5392 IApplicationThread topThumbnail = null; 5393 ActivityRecord topRecord = null; 5394 5395 synchronized(this) { 5396 if (localLOGV) Slog.v( 5397 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5398 + ", receiver=" + receiver); 5399 5400 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5401 != PackageManager.PERMISSION_GRANTED) { 5402 if (receiver != null) { 5403 // If the caller wants to wait for pending thumbnails, 5404 // it ain't gonna get them. 5405 try { 5406 receiver.finished(); 5407 } catch (RemoteException ex) { 5408 } 5409 } 5410 String msg = "Permission Denial: getTasks() from pid=" 5411 + Binder.getCallingPid() 5412 + ", uid=" + Binder.getCallingUid() 5413 + " requires " + android.Manifest.permission.GET_TASKS; 5414 Slog.w(TAG, msg); 5415 throw new SecurityException(msg); 5416 } 5417 5418 int pos = mMainStack.mHistory.size()-1; 5419 ActivityRecord next = 5420 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5421 ActivityRecord top = null; 5422 TaskRecord curTask = null; 5423 int numActivities = 0; 5424 int numRunning = 0; 5425 while (pos >= 0 && maxNum > 0) { 5426 final ActivityRecord r = next; 5427 pos--; 5428 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5429 5430 // Initialize state for next task if needed. 5431 if (top == null || 5432 (top.state == ActivityState.INITIALIZING 5433 && top.task == r.task)) { 5434 top = r; 5435 curTask = r.task; 5436 numActivities = numRunning = 0; 5437 } 5438 5439 // Add 'r' into the current task. 5440 numActivities++; 5441 if (r.app != null && r.app.thread != null) { 5442 numRunning++; 5443 } 5444 5445 if (localLOGV) Slog.v( 5446 TAG, r.intent.getComponent().flattenToShortString() 5447 + ": task=" + r.task); 5448 5449 // If the next one is a different task, generate a new 5450 // TaskInfo entry for what we have. 5451 if (next == null || next.task != curTask) { 5452 ActivityManager.RunningTaskInfo ci 5453 = new ActivityManager.RunningTaskInfo(); 5454 ci.id = curTask.taskId; 5455 ci.baseActivity = r.intent.getComponent(); 5456 ci.topActivity = top.intent.getComponent(); 5457 if (top.thumbHolder != null) { 5458 ci.description = top.thumbHolder.lastDescription; 5459 } 5460 ci.numActivities = numActivities; 5461 ci.numRunning = numRunning; 5462 //System.out.println( 5463 // "#" + maxNum + ": " + " descr=" + ci.description); 5464 if (ci.thumbnail == null && receiver != null) { 5465 if (localLOGV) Slog.v( 5466 TAG, "State=" + top.state + "Idle=" + top.idle 5467 + " app=" + top.app 5468 + " thr=" + (top.app != null ? top.app.thread : null)); 5469 if (top.state == ActivityState.RESUMED 5470 || top.state == ActivityState.PAUSING) { 5471 if (top.idle && top.app != null 5472 && top.app.thread != null) { 5473 topRecord = top; 5474 topThumbnail = top.app.thread; 5475 } else { 5476 top.thumbnailNeeded = true; 5477 } 5478 } 5479 if (pending == null) { 5480 pending = new PendingThumbnailsRecord(receiver); 5481 } 5482 pending.pendingRecords.add(top); 5483 } 5484 list.add(ci); 5485 maxNum--; 5486 top = null; 5487 } 5488 } 5489 5490 if (pending != null) { 5491 mPendingThumbnails.add(pending); 5492 } 5493 } 5494 5495 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5496 5497 if (topThumbnail != null) { 5498 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5499 try { 5500 topThumbnail.requestThumbnail(topRecord.appToken); 5501 } catch (Exception e) { 5502 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5503 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5504 } 5505 } 5506 5507 if (pending == null && receiver != null) { 5508 // In this case all thumbnails were available and the client 5509 // is being asked to be told when the remaining ones come in... 5510 // which is unusually, since the top-most currently running 5511 // activity should never have a canned thumbnail! Oh well. 5512 try { 5513 receiver.finished(); 5514 } catch (RemoteException ex) { 5515 } 5516 } 5517 5518 return list; 5519 } 5520 5521 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5522 int flags, int userId) { 5523 final int callingUid = Binder.getCallingUid(); 5524 if (userId != UserHandle.getCallingUserId()) { 5525 // Check if the caller is holding permissions for cross-user requests. 5526 if (checkComponentPermission( 5527 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5528 Binder.getCallingPid(), callingUid, -1, true) 5529 != PackageManager.PERMISSION_GRANTED) { 5530 String msg = "Permission Denial: " 5531 + "Request to get recent tasks for user " + userId 5532 + " but is calling from user " + UserHandle.getUserId(callingUid) 5533 + "; this requires " 5534 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5535 Slog.w(TAG, msg); 5536 throw new SecurityException(msg); 5537 } else { 5538 if (userId == UserHandle.USER_CURRENT) { 5539 userId = mCurrentUserId; 5540 } 5541 } 5542 } 5543 5544 synchronized (this) { 5545 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5546 "getRecentTasks()"); 5547 final boolean detailed = checkCallingPermission( 5548 android.Manifest.permission.GET_DETAILED_TASKS) 5549 == PackageManager.PERMISSION_GRANTED; 5550 5551 IPackageManager pm = AppGlobals.getPackageManager(); 5552 5553 final int N = mRecentTasks.size(); 5554 ArrayList<ActivityManager.RecentTaskInfo> res 5555 = new ArrayList<ActivityManager.RecentTaskInfo>( 5556 maxNum < N ? maxNum : N); 5557 for (int i=0; i<N && maxNum > 0; i++) { 5558 TaskRecord tr = mRecentTasks.get(i); 5559 // Only add calling user's recent tasks 5560 if (tr.userId != userId) continue; 5561 // Return the entry if desired by the caller. We always return 5562 // the first entry, because callers always expect this to be the 5563 // foreground app. We may filter others if the caller has 5564 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5565 // we should exclude the entry. 5566 5567 if (i == 0 5568 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5569 || (tr.intent == null) 5570 || ((tr.intent.getFlags() 5571 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5572 ActivityManager.RecentTaskInfo rti 5573 = new ActivityManager.RecentTaskInfo(); 5574 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5575 rti.persistentId = tr.taskId; 5576 rti.baseIntent = new Intent( 5577 tr.intent != null ? tr.intent : tr.affinityIntent); 5578 if (!detailed) { 5579 rti.baseIntent.replaceExtras((Bundle)null); 5580 } 5581 rti.origActivity = tr.origActivity; 5582 rti.description = tr.lastDescription; 5583 5584 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5585 // Check whether this activity is currently available. 5586 try { 5587 if (rti.origActivity != null) { 5588 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5589 == null) { 5590 continue; 5591 } 5592 } else if (rti.baseIntent != null) { 5593 if (pm.queryIntentActivities(rti.baseIntent, 5594 null, 0, userId) == null) { 5595 continue; 5596 } 5597 } 5598 } catch (RemoteException e) { 5599 // Will never happen. 5600 } 5601 } 5602 5603 res.add(rti); 5604 maxNum--; 5605 } 5606 } 5607 return res; 5608 } 5609 } 5610 5611 private TaskRecord taskForIdLocked(int id) { 5612 final int N = mRecentTasks.size(); 5613 for (int i=0; i<N; i++) { 5614 TaskRecord tr = mRecentTasks.get(i); 5615 if (tr.taskId == id) { 5616 return tr; 5617 } 5618 } 5619 return null; 5620 } 5621 5622 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5623 synchronized (this) { 5624 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5625 "getTaskThumbnails()"); 5626 TaskRecord tr = taskForIdLocked(id); 5627 if (tr != null) { 5628 return mMainStack.getTaskThumbnailsLocked(tr); 5629 } 5630 } 5631 return null; 5632 } 5633 5634 public boolean removeSubTask(int taskId, int subTaskIndex) { 5635 synchronized (this) { 5636 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5637 "removeSubTask()"); 5638 long ident = Binder.clearCallingIdentity(); 5639 try { 5640 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5641 true) != null; 5642 } finally { 5643 Binder.restoreCallingIdentity(ident); 5644 } 5645 } 5646 } 5647 5648 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5649 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5650 Intent baseIntent = new Intent( 5651 tr.intent != null ? tr.intent : tr.affinityIntent); 5652 ComponentName component = baseIntent.getComponent(); 5653 if (component == null) { 5654 Slog.w(TAG, "Now component for base intent of task: " + tr); 5655 return; 5656 } 5657 5658 // Find any running services associated with this app. 5659 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5660 5661 if (killProcesses) { 5662 // Find any running processes associated with this app. 5663 final String pkg = component.getPackageName(); 5664 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5665 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5666 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5667 for (int i=0; i<uids.size(); i++) { 5668 ProcessRecord proc = uids.valueAt(i); 5669 if (proc.userId != tr.userId) { 5670 continue; 5671 } 5672 if (!proc.pkgList.contains(pkg)) { 5673 continue; 5674 } 5675 procs.add(proc); 5676 } 5677 } 5678 5679 // Kill the running processes. 5680 for (int i=0; i<procs.size(); i++) { 5681 ProcessRecord pr = procs.get(i); 5682 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5683 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5684 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5685 pr.processName, pr.setAdj, "remove task"); 5686 pr.killedBackground = true; 5687 Process.killProcessQuiet(pr.pid); 5688 } else { 5689 pr.waitingToKill = "remove task"; 5690 } 5691 } 5692 } 5693 } 5694 5695 public boolean removeTask(int taskId, int flags) { 5696 synchronized (this) { 5697 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5698 "removeTask()"); 5699 long ident = Binder.clearCallingIdentity(); 5700 try { 5701 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5702 false); 5703 if (r != null) { 5704 mRecentTasks.remove(r.task); 5705 cleanUpRemovedTaskLocked(r.task, flags); 5706 return true; 5707 } else { 5708 TaskRecord tr = null; 5709 int i=0; 5710 while (i < mRecentTasks.size()) { 5711 TaskRecord t = mRecentTasks.get(i); 5712 if (t.taskId == taskId) { 5713 tr = t; 5714 break; 5715 } 5716 i++; 5717 } 5718 if (tr != null) { 5719 if (tr.numActivities <= 0) { 5720 // Caller is just removing a recent task that is 5721 // not actively running. That is easy! 5722 mRecentTasks.remove(i); 5723 cleanUpRemovedTaskLocked(tr, flags); 5724 return true; 5725 } else { 5726 Slog.w(TAG, "removeTask: task " + taskId 5727 + " does not have activities to remove, " 5728 + " but numActivities=" + tr.numActivities 5729 + ": " + tr); 5730 } 5731 } 5732 } 5733 } finally { 5734 Binder.restoreCallingIdentity(ident); 5735 } 5736 } 5737 return false; 5738 } 5739 5740 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5741 int j; 5742 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5743 TaskRecord jt = startTask; 5744 5745 // First look backwards 5746 for (j=startIndex-1; j>=0; j--) { 5747 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5748 if (r.task != jt) { 5749 jt = r.task; 5750 if (affinity.equals(jt.affinity)) { 5751 return j; 5752 } 5753 } 5754 } 5755 5756 // Now look forwards 5757 final int N = mMainStack.mHistory.size(); 5758 jt = startTask; 5759 for (j=startIndex+1; j<N; j++) { 5760 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5761 if (r.task != jt) { 5762 if (affinity.equals(jt.affinity)) { 5763 return j; 5764 } 5765 jt = r.task; 5766 } 5767 } 5768 5769 // Might it be at the top? 5770 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5771 return N-1; 5772 } 5773 5774 return -1; 5775 } 5776 5777 /** 5778 * TODO: Add mController hook 5779 */ 5780 public void moveTaskToFront(int task, int flags, Bundle options) { 5781 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5782 "moveTaskToFront()"); 5783 5784 synchronized(this) { 5785 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5786 Binder.getCallingUid(), "Task to front")) { 5787 ActivityOptions.abort(options); 5788 return; 5789 } 5790 final long origId = Binder.clearCallingIdentity(); 5791 try { 5792 TaskRecord tr = taskForIdLocked(task); 5793 if (tr != null) { 5794 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5795 mMainStack.mUserLeaving = true; 5796 } 5797 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5798 // Caller wants the home activity moved with it. To accomplish this, 5799 // we'll just move the home task to the top first. 5800 mMainStack.moveHomeToFrontLocked(); 5801 } 5802 mMainStack.moveTaskToFrontLocked(tr, null, options); 5803 return; 5804 } 5805 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5806 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5807 if (hr.task.taskId == task) { 5808 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5809 mMainStack.mUserLeaving = true; 5810 } 5811 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5812 // Caller wants the home activity moved with it. To accomplish this, 5813 // we'll just move the home task to the top first. 5814 mMainStack.moveHomeToFrontLocked(); 5815 } 5816 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5817 return; 5818 } 5819 } 5820 } finally { 5821 Binder.restoreCallingIdentity(origId); 5822 } 5823 ActivityOptions.abort(options); 5824 } 5825 } 5826 5827 public void moveTaskToBack(int task) { 5828 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5829 "moveTaskToBack()"); 5830 5831 synchronized(this) { 5832 if (mMainStack.mResumedActivity != null 5833 && mMainStack.mResumedActivity.task.taskId == task) { 5834 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5835 Binder.getCallingUid(), "Task to back")) { 5836 return; 5837 } 5838 } 5839 final long origId = Binder.clearCallingIdentity(); 5840 mMainStack.moveTaskToBackLocked(task, null); 5841 Binder.restoreCallingIdentity(origId); 5842 } 5843 } 5844 5845 /** 5846 * Moves an activity, and all of the other activities within the same task, to the bottom 5847 * of the history stack. The activity's order within the task is unchanged. 5848 * 5849 * @param token A reference to the activity we wish to move 5850 * @param nonRoot If false then this only works if the activity is the root 5851 * of a task; if true it will work for any activity in a task. 5852 * @return Returns true if the move completed, false if not. 5853 */ 5854 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5855 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5856 synchronized(this) { 5857 final long origId = Binder.clearCallingIdentity(); 5858 int taskId = getTaskForActivityLocked(token, !nonRoot); 5859 if (taskId >= 0) { 5860 return mMainStack.moveTaskToBackLocked(taskId, null); 5861 } 5862 Binder.restoreCallingIdentity(origId); 5863 } 5864 return false; 5865 } 5866 5867 public void moveTaskBackwards(int task) { 5868 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5869 "moveTaskBackwards()"); 5870 5871 synchronized(this) { 5872 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5873 Binder.getCallingUid(), "Task backwards")) { 5874 return; 5875 } 5876 final long origId = Binder.clearCallingIdentity(); 5877 moveTaskBackwardsLocked(task); 5878 Binder.restoreCallingIdentity(origId); 5879 } 5880 } 5881 5882 private final void moveTaskBackwardsLocked(int task) { 5883 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5884 } 5885 5886 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5887 synchronized(this) { 5888 return getTaskForActivityLocked(token, onlyRoot); 5889 } 5890 } 5891 5892 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5893 final int N = mMainStack.mHistory.size(); 5894 TaskRecord lastTask = null; 5895 for (int i=0; i<N; i++) { 5896 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5897 if (r.appToken == token) { 5898 if (!onlyRoot || lastTask != r.task) { 5899 return r.task.taskId; 5900 } 5901 return -1; 5902 } 5903 lastTask = r.task; 5904 } 5905 5906 return -1; 5907 } 5908 5909 // ========================================================= 5910 // THUMBNAILS 5911 // ========================================================= 5912 5913 public void reportThumbnail(IBinder token, 5914 Bitmap thumbnail, CharSequence description) { 5915 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5916 final long origId = Binder.clearCallingIdentity(); 5917 sendPendingThumbnail(null, token, thumbnail, description, true); 5918 Binder.restoreCallingIdentity(origId); 5919 } 5920 5921 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5922 Bitmap thumbnail, CharSequence description, boolean always) { 5923 TaskRecord task = null; 5924 ArrayList receivers = null; 5925 5926 //System.out.println("Send pending thumbnail: " + r); 5927 5928 synchronized(this) { 5929 if (r == null) { 5930 r = mMainStack.isInStackLocked(token); 5931 if (r == null) { 5932 return; 5933 } 5934 } 5935 if (thumbnail == null && r.thumbHolder != null) { 5936 thumbnail = r.thumbHolder.lastThumbnail; 5937 description = r.thumbHolder.lastDescription; 5938 } 5939 if (thumbnail == null && !always) { 5940 // If there is no thumbnail, and this entry is not actually 5941 // going away, then abort for now and pick up the next 5942 // thumbnail we get. 5943 return; 5944 } 5945 task = r.task; 5946 5947 int N = mPendingThumbnails.size(); 5948 int i=0; 5949 while (i<N) { 5950 PendingThumbnailsRecord pr = 5951 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5952 //System.out.println("Looking in " + pr.pendingRecords); 5953 if (pr.pendingRecords.remove(r)) { 5954 if (receivers == null) { 5955 receivers = new ArrayList(); 5956 } 5957 receivers.add(pr); 5958 if (pr.pendingRecords.size() == 0) { 5959 pr.finished = true; 5960 mPendingThumbnails.remove(i); 5961 N--; 5962 continue; 5963 } 5964 } 5965 i++; 5966 } 5967 } 5968 5969 if (receivers != null) { 5970 final int N = receivers.size(); 5971 for (int i=0; i<N; i++) { 5972 try { 5973 PendingThumbnailsRecord pr = 5974 (PendingThumbnailsRecord)receivers.get(i); 5975 pr.receiver.newThumbnail( 5976 task != null ? task.taskId : -1, thumbnail, description); 5977 if (pr.finished) { 5978 pr.receiver.finished(); 5979 } 5980 } catch (Exception e) { 5981 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5982 } 5983 } 5984 } 5985 } 5986 5987 // ========================================================= 5988 // CONTENT PROVIDERS 5989 // ========================================================= 5990 5991 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 5992 List<ProviderInfo> providers = null; 5993 try { 5994 providers = AppGlobals.getPackageManager(). 5995 queryContentProviders(app.processName, app.uid, 5996 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 5997 } catch (RemoteException ex) { 5998 } 5999 if (DEBUG_MU) 6000 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6001 int userId = app.userId; 6002 if (providers != null) { 6003 int N = providers.size(); 6004 for (int i=0; i<N; i++) { 6005 ProviderInfo cpi = 6006 (ProviderInfo)providers.get(i); 6007 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6008 cpi.name, cpi.flags); 6009 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6010 // This is a singleton provider, but a user besides the 6011 // default user is asking to initialize a process it runs 6012 // in... well, no, it doesn't actually run in this process, 6013 // it runs in the process of the default user. Get rid of it. 6014 providers.remove(i); 6015 N--; 6016 continue; 6017 } 6018 6019 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6020 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6021 if (cpr == null) { 6022 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6023 mProviderMap.putProviderByClass(comp, cpr); 6024 } 6025 if (DEBUG_MU) 6026 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6027 app.pubProviders.put(cpi.name, cpr); 6028 app.addPackage(cpi.applicationInfo.packageName); 6029 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6030 } 6031 } 6032 return providers; 6033 } 6034 6035 /** 6036 * Check if {@link ProcessRecord} has a possible chance at accessing the 6037 * given {@link ProviderInfo}. Final permission checking is always done 6038 * in {@link ContentProvider}. 6039 */ 6040 private final String checkContentProviderPermissionLocked( 6041 ProviderInfo cpi, ProcessRecord r) { 6042 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6043 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6044 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6045 cpi.applicationInfo.uid, cpi.exported) 6046 == PackageManager.PERMISSION_GRANTED) { 6047 return null; 6048 } 6049 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6050 cpi.applicationInfo.uid, cpi.exported) 6051 == PackageManager.PERMISSION_GRANTED) { 6052 return null; 6053 } 6054 6055 PathPermission[] pps = cpi.pathPermissions; 6056 if (pps != null) { 6057 int i = pps.length; 6058 while (i > 0) { 6059 i--; 6060 PathPermission pp = pps[i]; 6061 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6062 cpi.applicationInfo.uid, cpi.exported) 6063 == PackageManager.PERMISSION_GRANTED) { 6064 return null; 6065 } 6066 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6067 cpi.applicationInfo.uid, cpi.exported) 6068 == PackageManager.PERMISSION_GRANTED) { 6069 return null; 6070 } 6071 } 6072 } 6073 6074 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6075 if (perms != null) { 6076 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6077 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6078 return null; 6079 } 6080 } 6081 } 6082 6083 String msg; 6084 if (!cpi.exported) { 6085 msg = "Permission Denial: opening provider " + cpi.name 6086 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6087 + ", uid=" + callingUid + ") that is not exported from uid " 6088 + cpi.applicationInfo.uid; 6089 } else { 6090 msg = "Permission Denial: opening provider " + cpi.name 6091 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6092 + ", uid=" + callingUid + ") requires " 6093 + cpi.readPermission + " or " + cpi.writePermission; 6094 } 6095 Slog.w(TAG, msg); 6096 return msg; 6097 } 6098 6099 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6100 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6101 if (r != null) { 6102 for (int i=0; i<r.conProviders.size(); i++) { 6103 ContentProviderConnection conn = r.conProviders.get(i); 6104 if (conn.provider == cpr) { 6105 if (DEBUG_PROVIDER) Slog.v(TAG, 6106 "Adding provider requested by " 6107 + r.processName + " from process " 6108 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6109 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6110 if (stable) { 6111 conn.stableCount++; 6112 conn.numStableIncs++; 6113 } else { 6114 conn.unstableCount++; 6115 conn.numUnstableIncs++; 6116 } 6117 return conn; 6118 } 6119 } 6120 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6121 if (stable) { 6122 conn.stableCount = 1; 6123 conn.numStableIncs = 1; 6124 } else { 6125 conn.unstableCount = 1; 6126 conn.numUnstableIncs = 1; 6127 } 6128 cpr.connections.add(conn); 6129 r.conProviders.add(conn); 6130 return conn; 6131 } 6132 cpr.addExternalProcessHandleLocked(externalProcessToken); 6133 return null; 6134 } 6135 6136 boolean decProviderCountLocked(ContentProviderConnection conn, 6137 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6138 if (conn != null) { 6139 cpr = conn.provider; 6140 if (DEBUG_PROVIDER) Slog.v(TAG, 6141 "Removing provider requested by " 6142 + conn.client.processName + " from process " 6143 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6144 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6145 if (stable) { 6146 conn.stableCount--; 6147 } else { 6148 conn.unstableCount--; 6149 } 6150 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6151 cpr.connections.remove(conn); 6152 conn.client.conProviders.remove(conn); 6153 return true; 6154 } 6155 return false; 6156 } 6157 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6158 return false; 6159 } 6160 6161 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6162 String name, IBinder token, boolean stable) { 6163 ContentProviderRecord cpr; 6164 ContentProviderConnection conn = null; 6165 ProviderInfo cpi = null; 6166 6167 synchronized(this) { 6168 ProcessRecord r = null; 6169 if (caller != null) { 6170 r = getRecordForAppLocked(caller); 6171 if (r == null) { 6172 throw new SecurityException( 6173 "Unable to find app for caller " + caller 6174 + " (pid=" + Binder.getCallingPid() 6175 + ") when getting content provider " + name); 6176 } 6177 } 6178 6179 // First check if this content provider has been published... 6180 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6181 cpr = mProviderMap.getProviderByName(name, userId); 6182 boolean providerRunning = cpr != null; 6183 if (providerRunning) { 6184 cpi = cpr.info; 6185 String msg; 6186 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6187 throw new SecurityException(msg); 6188 } 6189 6190 if (r != null && cpr.canRunHere(r)) { 6191 // This provider has been published or is in the process 6192 // of being published... but it is also allowed to run 6193 // in the caller's process, so don't make a connection 6194 // and just let the caller instantiate its own instance. 6195 ContentProviderHolder holder = cpr.newHolder(null); 6196 // don't give caller the provider object, it needs 6197 // to make its own. 6198 holder.provider = null; 6199 return holder; 6200 } 6201 6202 final long origId = Binder.clearCallingIdentity(); 6203 6204 // In this case the provider instance already exists, so we can 6205 // return it right away. 6206 conn = incProviderCountLocked(r, cpr, token, stable); 6207 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6208 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6209 // If this is a perceptible app accessing the provider, 6210 // make sure to count it as being accessed and thus 6211 // back up on the LRU list. This is good because 6212 // content providers are often expensive to start. 6213 updateLruProcessLocked(cpr.proc, false, true); 6214 } 6215 } 6216 6217 if (cpr.proc != null) { 6218 if (false) { 6219 if (cpr.name.flattenToShortString().equals( 6220 "com.android.providers.calendar/.CalendarProvider2")) { 6221 Slog.v(TAG, "****************** KILLING " 6222 + cpr.name.flattenToShortString()); 6223 Process.killProcess(cpr.proc.pid); 6224 } 6225 } 6226 boolean success = updateOomAdjLocked(cpr.proc); 6227 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6228 // NOTE: there is still a race here where a signal could be 6229 // pending on the process even though we managed to update its 6230 // adj level. Not sure what to do about this, but at least 6231 // the race is now smaller. 6232 if (!success) { 6233 // Uh oh... it looks like the provider's process 6234 // has been killed on us. We need to wait for a new 6235 // process to be started, and make sure its death 6236 // doesn't kill our process. 6237 Slog.i(TAG, 6238 "Existing provider " + cpr.name.flattenToShortString() 6239 + " is crashing; detaching " + r); 6240 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6241 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6242 if (!lastRef) { 6243 // This wasn't the last ref our process had on 6244 // the provider... we have now been killed, bail. 6245 return null; 6246 } 6247 providerRunning = false; 6248 conn = null; 6249 } 6250 } 6251 6252 Binder.restoreCallingIdentity(origId); 6253 } 6254 6255 boolean singleton; 6256 if (!providerRunning) { 6257 try { 6258 cpi = AppGlobals.getPackageManager(). 6259 resolveContentProvider(name, 6260 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6261 } catch (RemoteException ex) { 6262 } 6263 if (cpi == null) { 6264 return null; 6265 } 6266 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6267 cpi.name, cpi.flags); 6268 if (singleton) { 6269 userId = 0; 6270 } 6271 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6272 6273 String msg; 6274 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6275 throw new SecurityException(msg); 6276 } 6277 6278 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6279 && !cpi.processName.equals("system")) { 6280 // If this content provider does not run in the system 6281 // process, and the system is not yet ready to run other 6282 // processes, then fail fast instead of hanging. 6283 throw new IllegalArgumentException( 6284 "Attempt to launch content provider before system ready"); 6285 } 6286 6287 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6288 cpr = mProviderMap.getProviderByClass(comp, userId); 6289 final boolean firstClass = cpr == null; 6290 if (firstClass) { 6291 try { 6292 ApplicationInfo ai = 6293 AppGlobals.getPackageManager(). 6294 getApplicationInfo( 6295 cpi.applicationInfo.packageName, 6296 STOCK_PM_FLAGS, userId); 6297 if (ai == null) { 6298 Slog.w(TAG, "No package info for content provider " 6299 + cpi.name); 6300 return null; 6301 } 6302 ai = getAppInfoForUser(ai, userId); 6303 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6304 } catch (RemoteException ex) { 6305 // pm is in same process, this will never happen. 6306 } 6307 } 6308 6309 if (r != null && cpr.canRunHere(r)) { 6310 // If this is a multiprocess provider, then just return its 6311 // info and allow the caller to instantiate it. Only do 6312 // this if the provider is the same user as the caller's 6313 // process, or can run as root (so can be in any process). 6314 return cpr.newHolder(null); 6315 } 6316 6317 if (DEBUG_PROVIDER) { 6318 RuntimeException e = new RuntimeException("here"); 6319 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6320 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6321 } 6322 6323 // This is single process, and our app is now connecting to it. 6324 // See if we are already in the process of launching this 6325 // provider. 6326 final int N = mLaunchingProviders.size(); 6327 int i; 6328 for (i=0; i<N; i++) { 6329 if (mLaunchingProviders.get(i) == cpr) { 6330 break; 6331 } 6332 } 6333 6334 // If the provider is not already being launched, then get it 6335 // started. 6336 if (i >= N) { 6337 final long origId = Binder.clearCallingIdentity(); 6338 6339 try { 6340 // Content provider is now in use, its package can't be stopped. 6341 try { 6342 AppGlobals.getPackageManager().setPackageStoppedState( 6343 cpr.appInfo.packageName, false, userId); 6344 } catch (RemoteException e) { 6345 } catch (IllegalArgumentException e) { 6346 Slog.w(TAG, "Failed trying to unstop package " 6347 + cpr.appInfo.packageName + ": " + e); 6348 } 6349 6350 ProcessRecord proc = startProcessLocked(cpi.processName, 6351 cpr.appInfo, false, 0, "content provider", 6352 new ComponentName(cpi.applicationInfo.packageName, 6353 cpi.name), false, false); 6354 if (proc == null) { 6355 Slog.w(TAG, "Unable to launch app " 6356 + cpi.applicationInfo.packageName + "/" 6357 + cpi.applicationInfo.uid + " for provider " 6358 + name + ": process is bad"); 6359 return null; 6360 } 6361 cpr.launchingApp = proc; 6362 mLaunchingProviders.add(cpr); 6363 } finally { 6364 Binder.restoreCallingIdentity(origId); 6365 } 6366 } 6367 6368 // Make sure the provider is published (the same provider class 6369 // may be published under multiple names). 6370 if (firstClass) { 6371 mProviderMap.putProviderByClass(comp, cpr); 6372 } 6373 6374 mProviderMap.putProviderByName(name, cpr); 6375 conn = incProviderCountLocked(r, cpr, token, stable); 6376 if (conn != null) { 6377 conn.waiting = true; 6378 } 6379 } 6380 } 6381 6382 // Wait for the provider to be published... 6383 synchronized (cpr) { 6384 while (cpr.provider == null) { 6385 if (cpr.launchingApp == null) { 6386 Slog.w(TAG, "Unable to launch app " 6387 + cpi.applicationInfo.packageName + "/" 6388 + cpi.applicationInfo.uid + " for provider " 6389 + name + ": launching app became null"); 6390 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6391 cpi.applicationInfo.packageName, 6392 cpi.applicationInfo.uid, name); 6393 return null; 6394 } 6395 try { 6396 if (DEBUG_MU) { 6397 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6398 + cpr.launchingApp); 6399 } 6400 if (conn != null) { 6401 conn.waiting = true; 6402 } 6403 cpr.wait(); 6404 } catch (InterruptedException ex) { 6405 } finally { 6406 if (conn != null) { 6407 conn.waiting = false; 6408 } 6409 } 6410 } 6411 } 6412 return cpr != null ? cpr.newHolder(conn) : null; 6413 } 6414 6415 public final ContentProviderHolder getContentProvider( 6416 IApplicationThread caller, String name, boolean stable) { 6417 enforceNotIsolatedCaller("getContentProvider"); 6418 if (caller == null) { 6419 String msg = "null IApplicationThread when getting content provider " 6420 + name; 6421 Slog.w(TAG, msg); 6422 throw new SecurityException(msg); 6423 } 6424 6425 return getContentProviderImpl(caller, name, null, stable); 6426 } 6427 6428 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6429 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6430 "Do not have permission in call getContentProviderExternal()"); 6431 return getContentProviderExternalUnchecked(name, token); 6432 } 6433 6434 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6435 return getContentProviderImpl(null, name, token, true); 6436 } 6437 6438 /** 6439 * Drop a content provider from a ProcessRecord's bookkeeping 6440 * @param cpr 6441 */ 6442 public void removeContentProvider(IBinder connection, boolean stable) { 6443 enforceNotIsolatedCaller("removeContentProvider"); 6444 synchronized (this) { 6445 ContentProviderConnection conn; 6446 try { 6447 conn = (ContentProviderConnection)connection; 6448 } catch (ClassCastException e) { 6449 String msg ="removeContentProvider: " + connection 6450 + " not a ContentProviderConnection"; 6451 Slog.w(TAG, msg); 6452 throw new IllegalArgumentException(msg); 6453 } 6454 if (conn == null) { 6455 throw new NullPointerException("connection is null"); 6456 } 6457 if (decProviderCountLocked(conn, null, null, stable)) { 6458 updateOomAdjLocked(); 6459 } 6460 } 6461 } 6462 6463 public void removeContentProviderExternal(String name, IBinder token) { 6464 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6465 "Do not have permission in call removeContentProviderExternal()"); 6466 removeContentProviderExternalUnchecked(name, token); 6467 } 6468 6469 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6470 synchronized (this) { 6471 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6472 Binder.getOrigCallingUser()); 6473 if(cpr == null) { 6474 //remove from mProvidersByClass 6475 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6476 return; 6477 } 6478 6479 //update content provider record entry info 6480 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6481 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6482 Binder.getOrigCallingUser()); 6483 if (localCpr.hasExternalProcessHandles()) { 6484 if (localCpr.removeExternalProcessHandleLocked(token)) { 6485 updateOomAdjLocked(); 6486 } else { 6487 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6488 + " with no external reference for token: " 6489 + token + "."); 6490 } 6491 } else { 6492 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6493 + " with no external references."); 6494 } 6495 } 6496 } 6497 6498 public final void publishContentProviders(IApplicationThread caller, 6499 List<ContentProviderHolder> providers) { 6500 if (providers == null) { 6501 return; 6502 } 6503 6504 enforceNotIsolatedCaller("publishContentProviders"); 6505 synchronized (this) { 6506 final ProcessRecord r = getRecordForAppLocked(caller); 6507 if (DEBUG_MU) 6508 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6509 if (r == null) { 6510 throw new SecurityException( 6511 "Unable to find app for caller " + caller 6512 + " (pid=" + Binder.getCallingPid() 6513 + ") when publishing content providers"); 6514 } 6515 6516 final long origId = Binder.clearCallingIdentity(); 6517 6518 final int N = providers.size(); 6519 for (int i=0; i<N; i++) { 6520 ContentProviderHolder src = providers.get(i); 6521 if (src == null || src.info == null || src.provider == null) { 6522 continue; 6523 } 6524 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6525 if (DEBUG_MU) 6526 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6527 if (dst != null) { 6528 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6529 mProviderMap.putProviderByClass(comp, dst); 6530 String names[] = dst.info.authority.split(";"); 6531 for (int j = 0; j < names.length; j++) { 6532 mProviderMap.putProviderByName(names[j], dst); 6533 } 6534 6535 int NL = mLaunchingProviders.size(); 6536 int j; 6537 for (j=0; j<NL; j++) { 6538 if (mLaunchingProviders.get(j) == dst) { 6539 mLaunchingProviders.remove(j); 6540 j--; 6541 NL--; 6542 } 6543 } 6544 synchronized (dst) { 6545 dst.provider = src.provider; 6546 dst.proc = r; 6547 dst.notifyAll(); 6548 } 6549 updateOomAdjLocked(r); 6550 } 6551 } 6552 6553 Binder.restoreCallingIdentity(origId); 6554 } 6555 } 6556 6557 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6558 ContentProviderConnection conn; 6559 try { 6560 conn = (ContentProviderConnection)connection; 6561 } catch (ClassCastException e) { 6562 String msg ="refContentProvider: " + connection 6563 + " not a ContentProviderConnection"; 6564 Slog.w(TAG, msg); 6565 throw new IllegalArgumentException(msg); 6566 } 6567 if (conn == null) { 6568 throw new NullPointerException("connection is null"); 6569 } 6570 6571 synchronized (this) { 6572 if (stable > 0) { 6573 conn.numStableIncs += stable; 6574 } 6575 stable = conn.stableCount + stable; 6576 if (stable < 0) { 6577 throw new IllegalStateException("stableCount < 0: " + stable); 6578 } 6579 6580 if (unstable > 0) { 6581 conn.numUnstableIncs += unstable; 6582 } 6583 unstable = conn.unstableCount + unstable; 6584 if (unstable < 0) { 6585 throw new IllegalStateException("unstableCount < 0: " + unstable); 6586 } 6587 6588 if ((stable+unstable) <= 0) { 6589 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6590 + stable + " unstable=" + unstable); 6591 } 6592 conn.stableCount = stable; 6593 conn.unstableCount = unstable; 6594 return !conn.dead; 6595 } 6596 } 6597 6598 public void unstableProviderDied(IBinder connection) { 6599 ContentProviderConnection conn; 6600 try { 6601 conn = (ContentProviderConnection)connection; 6602 } catch (ClassCastException e) { 6603 String msg ="refContentProvider: " + connection 6604 + " not a ContentProviderConnection"; 6605 Slog.w(TAG, msg); 6606 throw new IllegalArgumentException(msg); 6607 } 6608 if (conn == null) { 6609 throw new NullPointerException("connection is null"); 6610 } 6611 6612 // Safely retrieve the content provider associated with the connection. 6613 IContentProvider provider; 6614 synchronized (this) { 6615 provider = conn.provider.provider; 6616 } 6617 6618 if (provider == null) { 6619 // Um, yeah, we're way ahead of you. 6620 return; 6621 } 6622 6623 // Make sure the caller is being honest with us. 6624 if (provider.asBinder().pingBinder()) { 6625 // Er, no, still looks good to us. 6626 synchronized (this) { 6627 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6628 + " says " + conn + " died, but we don't agree"); 6629 return; 6630 } 6631 } 6632 6633 // Well look at that! It's dead! 6634 synchronized (this) { 6635 if (conn.provider.provider != provider) { 6636 // But something changed... good enough. 6637 return; 6638 } 6639 6640 ProcessRecord proc = conn.provider.proc; 6641 if (proc == null || proc.thread == null) { 6642 // Seems like the process is already cleaned up. 6643 return; 6644 } 6645 6646 // As far as we're concerned, this is just like receiving a 6647 // death notification... just a bit prematurely. 6648 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6649 + ") early provider death"); 6650 final long ident = Binder.clearCallingIdentity(); 6651 try { 6652 appDiedLocked(proc, proc.pid, proc.thread); 6653 } finally { 6654 Binder.restoreCallingIdentity(ident); 6655 } 6656 } 6657 } 6658 6659 public static final void installSystemProviders() { 6660 List<ProviderInfo> providers; 6661 synchronized (mSelf) { 6662 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6663 providers = mSelf.generateApplicationProvidersLocked(app); 6664 if (providers != null) { 6665 for (int i=providers.size()-1; i>=0; i--) { 6666 ProviderInfo pi = (ProviderInfo)providers.get(i); 6667 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6668 Slog.w(TAG, "Not installing system proc provider " + pi.name 6669 + ": not system .apk"); 6670 providers.remove(i); 6671 } 6672 } 6673 } 6674 } 6675 if (providers != null) { 6676 mSystemThread.installSystemProviders(providers); 6677 } 6678 6679 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6680 6681 mSelf.mUsageStatsService.monitorPackages(); 6682 } 6683 6684 /** 6685 * Allows app to retrieve the MIME type of a URI without having permission 6686 * to access its content provider. 6687 * 6688 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6689 * 6690 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6691 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6692 */ 6693 public String getProviderMimeType(Uri uri) { 6694 enforceNotIsolatedCaller("getProviderMimeType"); 6695 final String name = uri.getAuthority(); 6696 final long ident = Binder.clearCallingIdentity(); 6697 ContentProviderHolder holder = null; 6698 6699 try { 6700 holder = getContentProviderExternalUnchecked(name, null); 6701 if (holder != null) { 6702 return holder.provider.getType(uri); 6703 } 6704 } catch (RemoteException e) { 6705 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6706 return null; 6707 } finally { 6708 if (holder != null) { 6709 removeContentProviderExternalUnchecked(name, null); 6710 } 6711 Binder.restoreCallingIdentity(ident); 6712 } 6713 6714 return null; 6715 } 6716 6717 // ========================================================= 6718 // GLOBAL MANAGEMENT 6719 // ========================================================= 6720 6721 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6722 ApplicationInfo info, String customProcess, boolean isolated) { 6723 String proc = customProcess != null ? customProcess : info.processName; 6724 BatteryStatsImpl.Uid.Proc ps = null; 6725 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6726 int uid = info.uid; 6727 if (isolated) { 6728 int userId = UserHandle.getUserId(uid); 6729 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6730 uid = 0; 6731 while (true) { 6732 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6733 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6734 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6735 } 6736 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6737 mNextIsolatedProcessUid++; 6738 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6739 // No process for this uid, use it. 6740 break; 6741 } 6742 stepsLeft--; 6743 if (stepsLeft <= 0) { 6744 return null; 6745 } 6746 } 6747 } 6748 synchronized (stats) { 6749 ps = stats.getProcessStatsLocked(info.uid, proc); 6750 } 6751 return new ProcessRecord(ps, thread, info, proc, uid); 6752 } 6753 6754 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6755 ProcessRecord app; 6756 if (!isolated) { 6757 app = getProcessRecordLocked(info.processName, info.uid); 6758 } else { 6759 app = null; 6760 } 6761 6762 if (app == null) { 6763 app = newProcessRecordLocked(null, info, null, isolated); 6764 mProcessNames.put(info.processName, app.uid, app); 6765 if (isolated) { 6766 mIsolatedProcesses.put(app.uid, app); 6767 } 6768 updateLruProcessLocked(app, true, true); 6769 } 6770 6771 // This package really, really can not be stopped. 6772 try { 6773 AppGlobals.getPackageManager().setPackageStoppedState( 6774 info.packageName, false, UserHandle.getUserId(app.uid)); 6775 } catch (RemoteException e) { 6776 } catch (IllegalArgumentException e) { 6777 Slog.w(TAG, "Failed trying to unstop package " 6778 + info.packageName + ": " + e); 6779 } 6780 6781 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6782 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6783 app.persistent = true; 6784 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6785 } 6786 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6787 mPersistentStartingProcesses.add(app); 6788 startProcessLocked(app, "added application", app.processName); 6789 } 6790 6791 return app; 6792 } 6793 6794 public void unhandledBack() { 6795 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6796 "unhandledBack()"); 6797 6798 synchronized(this) { 6799 int count = mMainStack.mHistory.size(); 6800 if (DEBUG_SWITCH) Slog.d( 6801 TAG, "Performing unhandledBack(): stack size = " + count); 6802 if (count > 1) { 6803 final long origId = Binder.clearCallingIdentity(); 6804 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6805 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6806 Binder.restoreCallingIdentity(origId); 6807 } 6808 } 6809 } 6810 6811 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6812 enforceNotIsolatedCaller("openContentUri"); 6813 String name = uri.getAuthority(); 6814 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6815 ParcelFileDescriptor pfd = null; 6816 if (cph != null) { 6817 // We record the binder invoker's uid in thread-local storage before 6818 // going to the content provider to open the file. Later, in the code 6819 // that handles all permissions checks, we look for this uid and use 6820 // that rather than the Activity Manager's own uid. The effect is that 6821 // we do the check against the caller's permissions even though it looks 6822 // to the content provider like the Activity Manager itself is making 6823 // the request. 6824 sCallerIdentity.set(new Identity( 6825 Binder.getCallingPid(), Binder.getCallingUid())); 6826 try { 6827 pfd = cph.provider.openFile(uri, "r"); 6828 } catch (FileNotFoundException e) { 6829 // do nothing; pfd will be returned null 6830 } finally { 6831 // Ensure that whatever happens, we clean up the identity state 6832 sCallerIdentity.remove(); 6833 } 6834 6835 // We've got the fd now, so we're done with the provider. 6836 removeContentProviderExternalUnchecked(name, null); 6837 } else { 6838 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6839 } 6840 return pfd; 6841 } 6842 6843 // Actually is sleeping or shutting down or whatever else in the future 6844 // is an inactive state. 6845 public boolean isSleeping() { 6846 return mSleeping || mShuttingDown; 6847 } 6848 6849 public void goingToSleep() { 6850 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6851 != PackageManager.PERMISSION_GRANTED) { 6852 throw new SecurityException("Requires permission " 6853 + android.Manifest.permission.DEVICE_POWER); 6854 } 6855 6856 synchronized(this) { 6857 mWentToSleep = true; 6858 updateEventDispatchingLocked(); 6859 6860 if (!mSleeping) { 6861 mSleeping = true; 6862 mMainStack.stopIfSleepingLocked(); 6863 6864 // Initialize the wake times of all processes. 6865 checkExcessivePowerUsageLocked(false); 6866 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6867 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6868 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6869 } 6870 } 6871 } 6872 6873 public boolean shutdown(int timeout) { 6874 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6875 != PackageManager.PERMISSION_GRANTED) { 6876 throw new SecurityException("Requires permission " 6877 + android.Manifest.permission.SHUTDOWN); 6878 } 6879 6880 boolean timedout = false; 6881 6882 synchronized(this) { 6883 mShuttingDown = true; 6884 updateEventDispatchingLocked(); 6885 6886 if (mMainStack.mResumedActivity != null) { 6887 mMainStack.stopIfSleepingLocked(); 6888 final long endTime = System.currentTimeMillis() + timeout; 6889 while (mMainStack.mResumedActivity != null 6890 || mMainStack.mPausingActivity != null) { 6891 long delay = endTime - System.currentTimeMillis(); 6892 if (delay <= 0) { 6893 Slog.w(TAG, "Activity manager shutdown timed out"); 6894 timedout = true; 6895 break; 6896 } 6897 try { 6898 this.wait(); 6899 } catch (InterruptedException e) { 6900 } 6901 } 6902 } 6903 } 6904 6905 mUsageStatsService.shutdown(); 6906 mBatteryStatsService.shutdown(); 6907 6908 return timedout; 6909 } 6910 6911 public final void activitySlept(IBinder token) { 6912 if (localLOGV) Slog.v( 6913 TAG, "Activity slept: token=" + token); 6914 6915 ActivityRecord r = null; 6916 6917 final long origId = Binder.clearCallingIdentity(); 6918 6919 synchronized (this) { 6920 r = mMainStack.isInStackLocked(token); 6921 if (r != null) { 6922 mMainStack.activitySleptLocked(r); 6923 } 6924 } 6925 6926 Binder.restoreCallingIdentity(origId); 6927 } 6928 6929 private void comeOutOfSleepIfNeededLocked() { 6930 if (!mWentToSleep && !mLockScreenShown) { 6931 if (mSleeping) { 6932 mSleeping = false; 6933 mMainStack.awakeFromSleepingLocked(); 6934 mMainStack.resumeTopActivityLocked(null); 6935 } 6936 } 6937 } 6938 6939 public void wakingUp() { 6940 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6941 != PackageManager.PERMISSION_GRANTED) { 6942 throw new SecurityException("Requires permission " 6943 + android.Manifest.permission.DEVICE_POWER); 6944 } 6945 6946 synchronized(this) { 6947 mWentToSleep = false; 6948 updateEventDispatchingLocked(); 6949 comeOutOfSleepIfNeededLocked(); 6950 } 6951 } 6952 6953 private void updateEventDispatchingLocked() { 6954 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6955 } 6956 6957 public void setLockScreenShown(boolean shown) { 6958 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6959 != PackageManager.PERMISSION_GRANTED) { 6960 throw new SecurityException("Requires permission " 6961 + android.Manifest.permission.DEVICE_POWER); 6962 } 6963 6964 synchronized(this) { 6965 mLockScreenShown = shown; 6966 comeOutOfSleepIfNeededLocked(); 6967 } 6968 } 6969 6970 public void stopAppSwitches() { 6971 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6972 != PackageManager.PERMISSION_GRANTED) { 6973 throw new SecurityException("Requires permission " 6974 + android.Manifest.permission.STOP_APP_SWITCHES); 6975 } 6976 6977 synchronized(this) { 6978 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6979 + APP_SWITCH_DELAY_TIME; 6980 mDidAppSwitch = false; 6981 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6982 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6983 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6984 } 6985 } 6986 6987 public void resumeAppSwitches() { 6988 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6989 != PackageManager.PERMISSION_GRANTED) { 6990 throw new SecurityException("Requires permission " 6991 + android.Manifest.permission.STOP_APP_SWITCHES); 6992 } 6993 6994 synchronized(this) { 6995 // Note that we don't execute any pending app switches... we will 6996 // let those wait until either the timeout, or the next start 6997 // activity request. 6998 mAppSwitchesAllowedTime = 0; 6999 } 7000 } 7001 7002 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7003 String name) { 7004 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7005 return true; 7006 } 7007 7008 final int perm = checkComponentPermission( 7009 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7010 callingUid, -1, true); 7011 if (perm == PackageManager.PERMISSION_GRANTED) { 7012 return true; 7013 } 7014 7015 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7016 return false; 7017 } 7018 7019 public void setDebugApp(String packageName, boolean waitForDebugger, 7020 boolean persistent) { 7021 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7022 "setDebugApp()"); 7023 7024 // Note that this is not really thread safe if there are multiple 7025 // callers into it at the same time, but that's not a situation we 7026 // care about. 7027 if (persistent) { 7028 final ContentResolver resolver = mContext.getContentResolver(); 7029 Settings.System.putString( 7030 resolver, Settings.System.DEBUG_APP, 7031 packageName); 7032 Settings.System.putInt( 7033 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7034 waitForDebugger ? 1 : 0); 7035 } 7036 7037 synchronized (this) { 7038 if (!persistent) { 7039 mOrigDebugApp = mDebugApp; 7040 mOrigWaitForDebugger = mWaitForDebugger; 7041 } 7042 mDebugApp = packageName; 7043 mWaitForDebugger = waitForDebugger; 7044 mDebugTransient = !persistent; 7045 if (packageName != null) { 7046 final long origId = Binder.clearCallingIdentity(); 7047 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7048 Binder.restoreCallingIdentity(origId); 7049 } 7050 } 7051 } 7052 7053 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7054 synchronized (this) { 7055 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7056 if (!isDebuggable) { 7057 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7058 throw new SecurityException("Process not debuggable: " + app.packageName); 7059 } 7060 } 7061 7062 mOpenGlTraceApp = processName; 7063 } 7064 } 7065 7066 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7067 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7068 synchronized (this) { 7069 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7070 if (!isDebuggable) { 7071 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7072 throw new SecurityException("Process not debuggable: " + app.packageName); 7073 } 7074 } 7075 mProfileApp = processName; 7076 mProfileFile = profileFile; 7077 if (mProfileFd != null) { 7078 try { 7079 mProfileFd.close(); 7080 } catch (IOException e) { 7081 } 7082 mProfileFd = null; 7083 } 7084 mProfileFd = profileFd; 7085 mProfileType = 0; 7086 mAutoStopProfiler = autoStopProfiler; 7087 } 7088 } 7089 7090 public void setAlwaysFinish(boolean enabled) { 7091 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7092 "setAlwaysFinish()"); 7093 7094 Settings.System.putInt( 7095 mContext.getContentResolver(), 7096 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7097 7098 synchronized (this) { 7099 mAlwaysFinishActivities = enabled; 7100 } 7101 } 7102 7103 public void setActivityController(IActivityController controller) { 7104 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7105 "setActivityController()"); 7106 synchronized (this) { 7107 mController = controller; 7108 } 7109 } 7110 7111 public boolean isUserAMonkey() { 7112 // For now the fact that there is a controller implies 7113 // we have a monkey. 7114 synchronized (this) { 7115 return mController != null; 7116 } 7117 } 7118 7119 public void registerProcessObserver(IProcessObserver observer) { 7120 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7121 "registerProcessObserver()"); 7122 synchronized (this) { 7123 mProcessObservers.register(observer); 7124 } 7125 } 7126 7127 public void unregisterProcessObserver(IProcessObserver observer) { 7128 synchronized (this) { 7129 mProcessObservers.unregister(observer); 7130 } 7131 } 7132 7133 public void setImmersive(IBinder token, boolean immersive) { 7134 synchronized(this) { 7135 ActivityRecord r = mMainStack.isInStackLocked(token); 7136 if (r == null) { 7137 throw new IllegalArgumentException(); 7138 } 7139 r.immersive = immersive; 7140 } 7141 } 7142 7143 public boolean isImmersive(IBinder token) { 7144 synchronized (this) { 7145 ActivityRecord r = mMainStack.isInStackLocked(token); 7146 if (r == null) { 7147 throw new IllegalArgumentException(); 7148 } 7149 return r.immersive; 7150 } 7151 } 7152 7153 public boolean isTopActivityImmersive() { 7154 enforceNotIsolatedCaller("startActivity"); 7155 synchronized (this) { 7156 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7157 return (r != null) ? r.immersive : false; 7158 } 7159 } 7160 7161 public final void enterSafeMode() { 7162 synchronized(this) { 7163 // It only makes sense to do this before the system is ready 7164 // and started launching other packages. 7165 if (!mSystemReady) { 7166 try { 7167 AppGlobals.getPackageManager().enterSafeMode(); 7168 } catch (RemoteException e) { 7169 } 7170 } 7171 } 7172 } 7173 7174 public final void showSafeModeOverlay() { 7175 View v = LayoutInflater.from(mContext).inflate( 7176 com.android.internal.R.layout.safe_mode, null); 7177 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7178 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7179 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7180 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7181 lp.gravity = Gravity.BOTTOM | Gravity.START; 7182 lp.format = v.getBackground().getOpacity(); 7183 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7184 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7185 ((WindowManager)mContext.getSystemService( 7186 Context.WINDOW_SERVICE)).addView(v, lp); 7187 } 7188 7189 public void noteWakeupAlarm(IIntentSender sender) { 7190 if (!(sender instanceof PendingIntentRecord)) { 7191 return; 7192 } 7193 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7194 synchronized (stats) { 7195 if (mBatteryStatsService.isOnBattery()) { 7196 mBatteryStatsService.enforceCallingPermission(); 7197 PendingIntentRecord rec = (PendingIntentRecord)sender; 7198 int MY_UID = Binder.getCallingUid(); 7199 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7200 BatteryStatsImpl.Uid.Pkg pkg = 7201 stats.getPackageStatsLocked(uid, rec.key.packageName); 7202 pkg.incWakeupsLocked(); 7203 } 7204 } 7205 } 7206 7207 public boolean killPids(int[] pids, String pReason, boolean secure) { 7208 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7209 throw new SecurityException("killPids only available to the system"); 7210 } 7211 String reason = (pReason == null) ? "Unknown" : pReason; 7212 // XXX Note: don't acquire main activity lock here, because the window 7213 // manager calls in with its locks held. 7214 7215 boolean killed = false; 7216 synchronized (mPidsSelfLocked) { 7217 int[] types = new int[pids.length]; 7218 int worstType = 0; 7219 for (int i=0; i<pids.length; i++) { 7220 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7221 if (proc != null) { 7222 int type = proc.setAdj; 7223 types[i] = type; 7224 if (type > worstType) { 7225 worstType = type; 7226 } 7227 } 7228 } 7229 7230 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7231 // then constrain it so we will kill all hidden procs. 7232 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7233 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7234 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7235 } 7236 7237 // If this is not a secure call, don't let it kill processes that 7238 // are important. 7239 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7240 worstType = ProcessList.SERVICE_ADJ; 7241 } 7242 7243 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7244 for (int i=0; i<pids.length; i++) { 7245 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7246 if (proc == null) { 7247 continue; 7248 } 7249 int adj = proc.setAdj; 7250 if (adj >= worstType && !proc.killedBackground) { 7251 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7252 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7253 proc.processName, adj, reason); 7254 killed = true; 7255 proc.killedBackground = true; 7256 Process.killProcessQuiet(pids[i]); 7257 } 7258 } 7259 } 7260 return killed; 7261 } 7262 7263 @Override 7264 public boolean killProcessesBelowForeground(String reason) { 7265 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7266 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7267 } 7268 7269 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7270 } 7271 7272 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7273 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7274 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7275 } 7276 7277 boolean killed = false; 7278 synchronized (mPidsSelfLocked) { 7279 final int size = mPidsSelfLocked.size(); 7280 for (int i = 0; i < size; i++) { 7281 final int pid = mPidsSelfLocked.keyAt(i); 7282 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7283 if (proc == null) continue; 7284 7285 final int adj = proc.setAdj; 7286 if (adj > belowAdj && !proc.killedBackground) { 7287 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7288 EventLog.writeEvent( 7289 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7290 killed = true; 7291 proc.killedBackground = true; 7292 Process.killProcessQuiet(pid); 7293 } 7294 } 7295 } 7296 return killed; 7297 } 7298 7299 public final void startRunning(String pkg, String cls, String action, 7300 String data) { 7301 synchronized(this) { 7302 if (mStartRunning) { 7303 return; 7304 } 7305 mStartRunning = true; 7306 mTopComponent = pkg != null && cls != null 7307 ? new ComponentName(pkg, cls) : null; 7308 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7309 mTopData = data; 7310 if (!mSystemReady) { 7311 return; 7312 } 7313 } 7314 7315 systemReady(null); 7316 } 7317 7318 private void retrieveSettings() { 7319 final ContentResolver resolver = mContext.getContentResolver(); 7320 String debugApp = Settings.System.getString( 7321 resolver, Settings.System.DEBUG_APP); 7322 boolean waitForDebugger = Settings.System.getInt( 7323 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7324 boolean alwaysFinishActivities = Settings.System.getInt( 7325 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7326 7327 Configuration configuration = new Configuration(); 7328 Settings.System.getConfiguration(resolver, configuration); 7329 7330 synchronized (this) { 7331 mDebugApp = mOrigDebugApp = debugApp; 7332 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7333 mAlwaysFinishActivities = alwaysFinishActivities; 7334 // This happens before any activities are started, so we can 7335 // change mConfiguration in-place. 7336 updateConfigurationLocked(configuration, null, false, true); 7337 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7338 } 7339 } 7340 7341 public boolean testIsSystemReady() { 7342 // no need to synchronize(this) just to read & return the value 7343 return mSystemReady; 7344 } 7345 7346 private static File getCalledPreBootReceiversFile() { 7347 File dataDir = Environment.getDataDirectory(); 7348 File systemDir = new File(dataDir, "system"); 7349 File fname = new File(systemDir, "called_pre_boots.dat"); 7350 return fname; 7351 } 7352 7353 static final int LAST_DONE_VERSION = 10000; 7354 7355 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7356 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7357 File file = getCalledPreBootReceiversFile(); 7358 FileInputStream fis = null; 7359 try { 7360 fis = new FileInputStream(file); 7361 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7362 int fvers = dis.readInt(); 7363 if (fvers == LAST_DONE_VERSION) { 7364 String vers = dis.readUTF(); 7365 String codename = dis.readUTF(); 7366 String build = dis.readUTF(); 7367 if (android.os.Build.VERSION.RELEASE.equals(vers) 7368 && android.os.Build.VERSION.CODENAME.equals(codename) 7369 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7370 int num = dis.readInt(); 7371 while (num > 0) { 7372 num--; 7373 String pkg = dis.readUTF(); 7374 String cls = dis.readUTF(); 7375 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7376 } 7377 } 7378 } 7379 } catch (FileNotFoundException e) { 7380 } catch (IOException e) { 7381 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7382 } finally { 7383 if (fis != null) { 7384 try { 7385 fis.close(); 7386 } catch (IOException e) { 7387 } 7388 } 7389 } 7390 return lastDoneReceivers; 7391 } 7392 7393 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7394 File file = getCalledPreBootReceiversFile(); 7395 FileOutputStream fos = null; 7396 DataOutputStream dos = null; 7397 try { 7398 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7399 fos = new FileOutputStream(file); 7400 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7401 dos.writeInt(LAST_DONE_VERSION); 7402 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7403 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7404 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7405 dos.writeInt(list.size()); 7406 for (int i=0; i<list.size(); i++) { 7407 dos.writeUTF(list.get(i).getPackageName()); 7408 dos.writeUTF(list.get(i).getClassName()); 7409 } 7410 } catch (IOException e) { 7411 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7412 file.delete(); 7413 } finally { 7414 FileUtils.sync(fos); 7415 if (dos != null) { 7416 try { 7417 dos.close(); 7418 } catch (IOException e) { 7419 // TODO Auto-generated catch block 7420 e.printStackTrace(); 7421 } 7422 } 7423 } 7424 } 7425 7426 public void systemReady(final Runnable goingCallback) { 7427 synchronized(this) { 7428 if (mSystemReady) { 7429 if (goingCallback != null) goingCallback.run(); 7430 return; 7431 } 7432 7433 // Check to see if there are any update receivers to run. 7434 if (!mDidUpdate) { 7435 if (mWaitingUpdate) { 7436 return; 7437 } 7438 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7439 List<ResolveInfo> ris = null; 7440 try { 7441 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7442 intent, null, 0, 0); 7443 } catch (RemoteException e) { 7444 } 7445 if (ris != null) { 7446 for (int i=ris.size()-1; i>=0; i--) { 7447 if ((ris.get(i).activityInfo.applicationInfo.flags 7448 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7449 ris.remove(i); 7450 } 7451 } 7452 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7453 7454 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7455 7456 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7457 for (int i=0; i<ris.size(); i++) { 7458 ActivityInfo ai = ris.get(i).activityInfo; 7459 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7460 if (lastDoneReceivers.contains(comp)) { 7461 ris.remove(i); 7462 i--; 7463 } 7464 } 7465 7466 for (int i=0; i<ris.size(); i++) { 7467 ActivityInfo ai = ris.get(i).activityInfo; 7468 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7469 doneReceivers.add(comp); 7470 intent.setComponent(comp); 7471 IIntentReceiver finisher = null; 7472 if (i == ris.size()-1) { 7473 finisher = new IIntentReceiver.Stub() { 7474 public void performReceive(Intent intent, int resultCode, 7475 String data, Bundle extras, boolean ordered, 7476 boolean sticky) { 7477 // The raw IIntentReceiver interface is called 7478 // with the AM lock held, so redispatch to 7479 // execute our code without the lock. 7480 mHandler.post(new Runnable() { 7481 public void run() { 7482 synchronized (ActivityManagerService.this) { 7483 mDidUpdate = true; 7484 } 7485 writeLastDonePreBootReceivers(doneReceivers); 7486 showBootMessage(mContext.getText( 7487 R.string.android_upgrading_complete), 7488 false); 7489 systemReady(goingCallback); 7490 } 7491 }); 7492 } 7493 }; 7494 } 7495 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7496 /* TODO: Send this to all users */ 7497 broadcastIntentLocked(null, null, intent, null, finisher, 7498 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7499 0 /* UserId zero */); 7500 if (finisher != null) { 7501 mWaitingUpdate = true; 7502 } 7503 } 7504 } 7505 if (mWaitingUpdate) { 7506 return; 7507 } 7508 mDidUpdate = true; 7509 } 7510 7511 mSystemReady = true; 7512 if (!mStartRunning) { 7513 return; 7514 } 7515 } 7516 7517 ArrayList<ProcessRecord> procsToKill = null; 7518 synchronized(mPidsSelfLocked) { 7519 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7520 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7521 if (!isAllowedWhileBooting(proc.info)){ 7522 if (procsToKill == null) { 7523 procsToKill = new ArrayList<ProcessRecord>(); 7524 } 7525 procsToKill.add(proc); 7526 } 7527 } 7528 } 7529 7530 synchronized(this) { 7531 if (procsToKill != null) { 7532 for (int i=procsToKill.size()-1; i>=0; i--) { 7533 ProcessRecord proc = procsToKill.get(i); 7534 Slog.i(TAG, "Removing system update proc: " + proc); 7535 removeProcessLocked(proc, true, false, "system update done"); 7536 } 7537 } 7538 7539 // Now that we have cleaned up any update processes, we 7540 // are ready to start launching real processes and know that 7541 // we won't trample on them any more. 7542 mProcessesReady = true; 7543 } 7544 7545 Slog.i(TAG, "System now ready"); 7546 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7547 SystemClock.uptimeMillis()); 7548 7549 synchronized(this) { 7550 // Make sure we have no pre-ready processes sitting around. 7551 7552 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7553 ResolveInfo ri = mContext.getPackageManager() 7554 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7555 STOCK_PM_FLAGS); 7556 CharSequence errorMsg = null; 7557 if (ri != null) { 7558 ActivityInfo ai = ri.activityInfo; 7559 ApplicationInfo app = ai.applicationInfo; 7560 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7561 mTopAction = Intent.ACTION_FACTORY_TEST; 7562 mTopData = null; 7563 mTopComponent = new ComponentName(app.packageName, 7564 ai.name); 7565 } else { 7566 errorMsg = mContext.getResources().getText( 7567 com.android.internal.R.string.factorytest_not_system); 7568 } 7569 } else { 7570 errorMsg = mContext.getResources().getText( 7571 com.android.internal.R.string.factorytest_no_action); 7572 } 7573 if (errorMsg != null) { 7574 mTopAction = null; 7575 mTopData = null; 7576 mTopComponent = null; 7577 Message msg = Message.obtain(); 7578 msg.what = SHOW_FACTORY_ERROR_MSG; 7579 msg.getData().putCharSequence("msg", errorMsg); 7580 mHandler.sendMessage(msg); 7581 } 7582 } 7583 } 7584 7585 retrieveSettings(); 7586 7587 if (goingCallback != null) goingCallback.run(); 7588 7589 synchronized (this) { 7590 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7591 try { 7592 List apps = AppGlobals.getPackageManager(). 7593 getPersistentApplications(STOCK_PM_FLAGS); 7594 if (apps != null) { 7595 int N = apps.size(); 7596 int i; 7597 for (i=0; i<N; i++) { 7598 ApplicationInfo info 7599 = (ApplicationInfo)apps.get(i); 7600 if (info != null && 7601 !info.packageName.equals("android")) { 7602 addAppLocked(info, false); 7603 } 7604 } 7605 } 7606 } catch (RemoteException ex) { 7607 // pm is in same process, this will never happen. 7608 } 7609 } 7610 7611 // Start up initial activity. 7612 mBooting = true; 7613 7614 try { 7615 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7616 Message msg = Message.obtain(); 7617 msg.what = SHOW_UID_ERROR_MSG; 7618 mHandler.sendMessage(msg); 7619 } 7620 } catch (RemoteException e) { 7621 } 7622 7623 mMainStack.resumeTopActivityLocked(null); 7624 } 7625 } 7626 7627 private boolean makeAppCrashingLocked(ProcessRecord app, 7628 String shortMsg, String longMsg, String stackTrace) { 7629 app.crashing = true; 7630 app.crashingReport = generateProcessError(app, 7631 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7632 startAppProblemLocked(app); 7633 app.stopFreezingAllLocked(); 7634 return handleAppCrashLocked(app); 7635 } 7636 7637 private void makeAppNotRespondingLocked(ProcessRecord app, 7638 String activity, String shortMsg, String longMsg) { 7639 app.notResponding = true; 7640 app.notRespondingReport = generateProcessError(app, 7641 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7642 activity, shortMsg, longMsg, null); 7643 startAppProblemLocked(app); 7644 app.stopFreezingAllLocked(); 7645 } 7646 7647 /** 7648 * Generate a process error record, suitable for attachment to a ProcessRecord. 7649 * 7650 * @param app The ProcessRecord in which the error occurred. 7651 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7652 * ActivityManager.AppErrorStateInfo 7653 * @param activity The activity associated with the crash, if known. 7654 * @param shortMsg Short message describing the crash. 7655 * @param longMsg Long message describing the crash. 7656 * @param stackTrace Full crash stack trace, may be null. 7657 * 7658 * @return Returns a fully-formed AppErrorStateInfo record. 7659 */ 7660 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7661 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7662 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7663 7664 report.condition = condition; 7665 report.processName = app.processName; 7666 report.pid = app.pid; 7667 report.uid = app.info.uid; 7668 report.tag = activity; 7669 report.shortMsg = shortMsg; 7670 report.longMsg = longMsg; 7671 report.stackTrace = stackTrace; 7672 7673 return report; 7674 } 7675 7676 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7677 synchronized (this) { 7678 app.crashing = false; 7679 app.crashingReport = null; 7680 app.notResponding = false; 7681 app.notRespondingReport = null; 7682 if (app.anrDialog == fromDialog) { 7683 app.anrDialog = null; 7684 } 7685 if (app.waitDialog == fromDialog) { 7686 app.waitDialog = null; 7687 } 7688 if (app.pid > 0 && app.pid != MY_PID) { 7689 handleAppCrashLocked(app); 7690 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7691 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7692 app.processName, app.setAdj, "user's request after error"); 7693 Process.killProcessQuiet(app.pid); 7694 } 7695 } 7696 } 7697 7698 private boolean handleAppCrashLocked(ProcessRecord app) { 7699 if (mHeadless) { 7700 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7701 return false; 7702 } 7703 long now = SystemClock.uptimeMillis(); 7704 7705 Long crashTime; 7706 if (!app.isolated) { 7707 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7708 } else { 7709 crashTime = null; 7710 } 7711 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7712 // This process loses! 7713 Slog.w(TAG, "Process " + app.info.processName 7714 + " has crashed too many times: killing!"); 7715 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7716 app.info.processName, app.uid); 7717 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7718 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7719 if (r.app == app) { 7720 Slog.w(TAG, " Force finishing activity " 7721 + r.intent.getComponent().flattenToShortString()); 7722 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7723 } 7724 } 7725 if (!app.persistent) { 7726 // We don't want to start this process again until the user 7727 // explicitly does so... but for persistent process, we really 7728 // need to keep it running. If a persistent process is actually 7729 // repeatedly crashing, then badness for everyone. 7730 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7731 app.info.processName); 7732 if (!app.isolated) { 7733 // XXX We don't have a way to mark isolated processes 7734 // as bad, since they don't have a peristent identity. 7735 mBadProcesses.put(app.info.processName, app.uid, now); 7736 mProcessCrashTimes.remove(app.info.processName, app.uid); 7737 } 7738 app.bad = true; 7739 app.removed = true; 7740 // Don't let services in this process be restarted and potentially 7741 // annoy the user repeatedly. Unless it is persistent, since those 7742 // processes run critical code. 7743 removeProcessLocked(app, false, false, "crash"); 7744 mMainStack.resumeTopActivityLocked(null); 7745 return false; 7746 } 7747 mMainStack.resumeTopActivityLocked(null); 7748 } else { 7749 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7750 if (r != null && r.app == app) { 7751 // If the top running activity is from this crashing 7752 // process, then terminate it to avoid getting in a loop. 7753 Slog.w(TAG, " Force finishing activity " 7754 + r.intent.getComponent().flattenToShortString()); 7755 int index = mMainStack.indexOfActivityLocked(r); 7756 r.stack.finishActivityLocked(r, index, 7757 Activity.RESULT_CANCELED, null, "crashed"); 7758 // Also terminate any activities below it that aren't yet 7759 // stopped, to avoid a situation where one will get 7760 // re-start our crashing activity once it gets resumed again. 7761 index--; 7762 if (index >= 0) { 7763 r = (ActivityRecord)mMainStack.mHistory.get(index); 7764 if (r.state == ActivityState.RESUMED 7765 || r.state == ActivityState.PAUSING 7766 || r.state == ActivityState.PAUSED) { 7767 if (!r.isHomeActivity || mHomeProcess != r.app) { 7768 Slog.w(TAG, " Force finishing activity " 7769 + r.intent.getComponent().flattenToShortString()); 7770 r.stack.finishActivityLocked(r, index, 7771 Activity.RESULT_CANCELED, null, "crashed"); 7772 } 7773 } 7774 } 7775 } 7776 } 7777 7778 // Bump up the crash count of any services currently running in the proc. 7779 if (app.services.size() != 0) { 7780 // Any services running in the application need to be placed 7781 // back in the pending list. 7782 Iterator<ServiceRecord> it = app.services.iterator(); 7783 while (it.hasNext()) { 7784 ServiceRecord sr = it.next(); 7785 sr.crashCount++; 7786 } 7787 } 7788 7789 // If the crashing process is what we consider to be the "home process" and it has been 7790 // replaced by a third-party app, clear the package preferred activities from packages 7791 // with a home activity running in the process to prevent a repeatedly crashing app 7792 // from blocking the user to manually clear the list. 7793 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7794 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7795 Iterator it = mHomeProcess.activities.iterator(); 7796 while (it.hasNext()) { 7797 ActivityRecord r = (ActivityRecord)it.next(); 7798 if (r.isHomeActivity) { 7799 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7800 try { 7801 ActivityThread.getPackageManager() 7802 .clearPackagePreferredActivities(r.packageName); 7803 } catch (RemoteException c) { 7804 // pm is in same process, this will never happen. 7805 } 7806 } 7807 } 7808 } 7809 7810 if (!app.isolated) { 7811 // XXX Can't keep track of crash times for isolated processes, 7812 // because they don't have a perisistent identity. 7813 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7814 } 7815 7816 return true; 7817 } 7818 7819 void startAppProblemLocked(ProcessRecord app) { 7820 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7821 mContext, app.info.packageName, app.info.flags); 7822 skipCurrentReceiverLocked(app); 7823 } 7824 7825 void skipCurrentReceiverLocked(ProcessRecord app) { 7826 for (BroadcastQueue queue : mBroadcastQueues) { 7827 queue.skipCurrentReceiverLocked(app); 7828 } 7829 } 7830 7831 /** 7832 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7833 * The application process will exit immediately after this call returns. 7834 * @param app object of the crashing app, null for the system server 7835 * @param crashInfo describing the exception 7836 */ 7837 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7838 ProcessRecord r = findAppProcess(app, "Crash"); 7839 final String processName = app == null ? "system_server" 7840 : (r == null ? "unknown" : r.processName); 7841 7842 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7843 processName, 7844 r == null ? -1 : r.info.flags, 7845 crashInfo.exceptionClassName, 7846 crashInfo.exceptionMessage, 7847 crashInfo.throwFileName, 7848 crashInfo.throwLineNumber); 7849 7850 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7851 7852 crashApplication(r, crashInfo); 7853 } 7854 7855 public void handleApplicationStrictModeViolation( 7856 IBinder app, 7857 int violationMask, 7858 StrictMode.ViolationInfo info) { 7859 ProcessRecord r = findAppProcess(app, "StrictMode"); 7860 if (r == null) { 7861 return; 7862 } 7863 7864 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7865 Integer stackFingerprint = info.hashCode(); 7866 boolean logIt = true; 7867 synchronized (mAlreadyLoggedViolatedStacks) { 7868 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7869 logIt = false; 7870 // TODO: sub-sample into EventLog for these, with 7871 // the info.durationMillis? Then we'd get 7872 // the relative pain numbers, without logging all 7873 // the stack traces repeatedly. We'd want to do 7874 // likewise in the client code, which also does 7875 // dup suppression, before the Binder call. 7876 } else { 7877 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7878 mAlreadyLoggedViolatedStacks.clear(); 7879 } 7880 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7881 } 7882 } 7883 if (logIt) { 7884 logStrictModeViolationToDropBox(r, info); 7885 } 7886 } 7887 7888 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7889 AppErrorResult result = new AppErrorResult(); 7890 synchronized (this) { 7891 final long origId = Binder.clearCallingIdentity(); 7892 7893 Message msg = Message.obtain(); 7894 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7895 HashMap<String, Object> data = new HashMap<String, Object>(); 7896 data.put("result", result); 7897 data.put("app", r); 7898 data.put("violationMask", violationMask); 7899 data.put("info", info); 7900 msg.obj = data; 7901 mHandler.sendMessage(msg); 7902 7903 Binder.restoreCallingIdentity(origId); 7904 } 7905 int res = result.get(); 7906 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7907 } 7908 } 7909 7910 // Depending on the policy in effect, there could be a bunch of 7911 // these in quick succession so we try to batch these together to 7912 // minimize disk writes, number of dropbox entries, and maximize 7913 // compression, by having more fewer, larger records. 7914 private void logStrictModeViolationToDropBox( 7915 ProcessRecord process, 7916 StrictMode.ViolationInfo info) { 7917 if (info == null) { 7918 return; 7919 } 7920 final boolean isSystemApp = process == null || 7921 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7922 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7923 final String processName = process == null ? "unknown" : process.processName; 7924 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7925 final DropBoxManager dbox = (DropBoxManager) 7926 mContext.getSystemService(Context.DROPBOX_SERVICE); 7927 7928 // Exit early if the dropbox isn't configured to accept this report type. 7929 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7930 7931 boolean bufferWasEmpty; 7932 boolean needsFlush; 7933 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7934 synchronized (sb) { 7935 bufferWasEmpty = sb.length() == 0; 7936 appendDropBoxProcessHeaders(process, processName, sb); 7937 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7938 sb.append("System-App: ").append(isSystemApp).append("\n"); 7939 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7940 if (info.violationNumThisLoop != 0) { 7941 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7942 } 7943 if (info.numAnimationsRunning != 0) { 7944 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7945 } 7946 if (info.broadcastIntentAction != null) { 7947 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7948 } 7949 if (info.durationMillis != -1) { 7950 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7951 } 7952 if (info.numInstances != -1) { 7953 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7954 } 7955 if (info.tags != null) { 7956 for (String tag : info.tags) { 7957 sb.append("Span-Tag: ").append(tag).append("\n"); 7958 } 7959 } 7960 sb.append("\n"); 7961 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7962 sb.append(info.crashInfo.stackTrace); 7963 } 7964 sb.append("\n"); 7965 7966 // Only buffer up to ~64k. Various logging bits truncate 7967 // things at 128k. 7968 needsFlush = (sb.length() > 64 * 1024); 7969 } 7970 7971 // Flush immediately if the buffer's grown too large, or this 7972 // is a non-system app. Non-system apps are isolated with a 7973 // different tag & policy and not batched. 7974 // 7975 // Batching is useful during internal testing with 7976 // StrictMode settings turned up high. Without batching, 7977 // thousands of separate files could be created on boot. 7978 if (!isSystemApp || needsFlush) { 7979 new Thread("Error dump: " + dropboxTag) { 7980 @Override 7981 public void run() { 7982 String report; 7983 synchronized (sb) { 7984 report = sb.toString(); 7985 sb.delete(0, sb.length()); 7986 sb.trimToSize(); 7987 } 7988 if (report.length() != 0) { 7989 dbox.addText(dropboxTag, report); 7990 } 7991 } 7992 }.start(); 7993 return; 7994 } 7995 7996 // System app batching: 7997 if (!bufferWasEmpty) { 7998 // An existing dropbox-writing thread is outstanding, so 7999 // we don't need to start it up. The existing thread will 8000 // catch the buffer appends we just did. 8001 return; 8002 } 8003 8004 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8005 // (After this point, we shouldn't access AMS internal data structures.) 8006 new Thread("Error dump: " + dropboxTag) { 8007 @Override 8008 public void run() { 8009 // 5 second sleep to let stacks arrive and be batched together 8010 try { 8011 Thread.sleep(5000); // 5 seconds 8012 } catch (InterruptedException e) {} 8013 8014 String errorReport; 8015 synchronized (mStrictModeBuffer) { 8016 errorReport = mStrictModeBuffer.toString(); 8017 if (errorReport.length() == 0) { 8018 return; 8019 } 8020 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8021 mStrictModeBuffer.trimToSize(); 8022 } 8023 dbox.addText(dropboxTag, errorReport); 8024 } 8025 }.start(); 8026 } 8027 8028 /** 8029 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8030 * @param app object of the crashing app, null for the system server 8031 * @param tag reported by the caller 8032 * @param crashInfo describing the context of the error 8033 * @return true if the process should exit immediately (WTF is fatal) 8034 */ 8035 public boolean handleApplicationWtf(IBinder app, String tag, 8036 ApplicationErrorReport.CrashInfo crashInfo) { 8037 ProcessRecord r = findAppProcess(app, "WTF"); 8038 final String processName = app == null ? "system_server" 8039 : (r == null ? "unknown" : r.processName); 8040 8041 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8042 processName, 8043 r == null ? -1 : r.info.flags, 8044 tag, crashInfo.exceptionMessage); 8045 8046 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8047 8048 if (r != null && r.pid != Process.myPid() && 8049 Settings.Secure.getInt(mContext.getContentResolver(), 8050 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8051 crashApplication(r, crashInfo); 8052 return true; 8053 } else { 8054 return false; 8055 } 8056 } 8057 8058 /** 8059 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8060 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8061 */ 8062 private ProcessRecord findAppProcess(IBinder app, String reason) { 8063 if (app == null) { 8064 return null; 8065 } 8066 8067 synchronized (this) { 8068 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8069 final int NA = apps.size(); 8070 for (int ia=0; ia<NA; ia++) { 8071 ProcessRecord p = apps.valueAt(ia); 8072 if (p.thread != null && p.thread.asBinder() == app) { 8073 return p; 8074 } 8075 } 8076 } 8077 8078 Slog.w(TAG, "Can't find mystery application for " + reason 8079 + " from pid=" + Binder.getCallingPid() 8080 + " uid=" + Binder.getCallingUid() + ": " + app); 8081 return null; 8082 } 8083 } 8084 8085 /** 8086 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8087 * to append various headers to the dropbox log text. 8088 */ 8089 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8090 StringBuilder sb) { 8091 // Watchdog thread ends up invoking this function (with 8092 // a null ProcessRecord) to add the stack file to dropbox. 8093 // Do not acquire a lock on this (am) in such cases, as it 8094 // could cause a potential deadlock, if and when watchdog 8095 // is invoked due to unavailability of lock on am and it 8096 // would prevent watchdog from killing system_server. 8097 if (process == null) { 8098 sb.append("Process: ").append(processName).append("\n"); 8099 return; 8100 } 8101 // Note: ProcessRecord 'process' is guarded by the service 8102 // instance. (notably process.pkgList, which could otherwise change 8103 // concurrently during execution of this method) 8104 synchronized (this) { 8105 sb.append("Process: ").append(processName).append("\n"); 8106 int flags = process.info.flags; 8107 IPackageManager pm = AppGlobals.getPackageManager(); 8108 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8109 for (String pkg : process.pkgList) { 8110 sb.append("Package: ").append(pkg); 8111 try { 8112 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8113 if (pi != null) { 8114 sb.append(" v").append(pi.versionCode); 8115 if (pi.versionName != null) { 8116 sb.append(" (").append(pi.versionName).append(")"); 8117 } 8118 } 8119 } catch (RemoteException e) { 8120 Slog.e(TAG, "Error getting package info: " + pkg, e); 8121 } 8122 sb.append("\n"); 8123 } 8124 } 8125 } 8126 8127 private static String processClass(ProcessRecord process) { 8128 if (process == null || process.pid == MY_PID) { 8129 return "system_server"; 8130 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8131 return "system_app"; 8132 } else { 8133 return "data_app"; 8134 } 8135 } 8136 8137 /** 8138 * Write a description of an error (crash, WTF, ANR) to the drop box. 8139 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8140 * @param process which caused the error, null means the system server 8141 * @param activity which triggered the error, null if unknown 8142 * @param parent activity related to the error, null if unknown 8143 * @param subject line related to the error, null if absent 8144 * @param report in long form describing the error, null if absent 8145 * @param logFile to include in the report, null if none 8146 * @param crashInfo giving an application stack trace, null if absent 8147 */ 8148 public void addErrorToDropBox(String eventType, 8149 ProcessRecord process, String processName, ActivityRecord activity, 8150 ActivityRecord parent, String subject, 8151 final String report, final File logFile, 8152 final ApplicationErrorReport.CrashInfo crashInfo) { 8153 // NOTE -- this must never acquire the ActivityManagerService lock, 8154 // otherwise the watchdog may be prevented from resetting the system. 8155 8156 final String dropboxTag = processClass(process) + "_" + eventType; 8157 final DropBoxManager dbox = (DropBoxManager) 8158 mContext.getSystemService(Context.DROPBOX_SERVICE); 8159 8160 // Exit early if the dropbox isn't configured to accept this report type. 8161 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8162 8163 final StringBuilder sb = new StringBuilder(1024); 8164 appendDropBoxProcessHeaders(process, processName, sb); 8165 if (activity != null) { 8166 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8167 } 8168 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8169 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8170 } 8171 if (parent != null && parent != activity) { 8172 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8173 } 8174 if (subject != null) { 8175 sb.append("Subject: ").append(subject).append("\n"); 8176 } 8177 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8178 if (Debug.isDebuggerConnected()) { 8179 sb.append("Debugger: Connected\n"); 8180 } 8181 sb.append("\n"); 8182 8183 // Do the rest in a worker thread to avoid blocking the caller on I/O 8184 // (After this point, we shouldn't access AMS internal data structures.) 8185 Thread worker = new Thread("Error dump: " + dropboxTag) { 8186 @Override 8187 public void run() { 8188 if (report != null) { 8189 sb.append(report); 8190 } 8191 if (logFile != null) { 8192 try { 8193 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8194 } catch (IOException e) { 8195 Slog.e(TAG, "Error reading " + logFile, e); 8196 } 8197 } 8198 if (crashInfo != null && crashInfo.stackTrace != null) { 8199 sb.append(crashInfo.stackTrace); 8200 } 8201 8202 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8203 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8204 if (lines > 0) { 8205 sb.append("\n"); 8206 8207 // Merge several logcat streams, and take the last N lines 8208 InputStreamReader input = null; 8209 try { 8210 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8211 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8212 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8213 8214 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8215 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8216 input = new InputStreamReader(logcat.getInputStream()); 8217 8218 int num; 8219 char[] buf = new char[8192]; 8220 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8221 } catch (IOException e) { 8222 Slog.e(TAG, "Error running logcat", e); 8223 } finally { 8224 if (input != null) try { input.close(); } catch (IOException e) {} 8225 } 8226 } 8227 8228 dbox.addText(dropboxTag, sb.toString()); 8229 } 8230 }; 8231 8232 if (process == null) { 8233 // If process is null, we are being called from some internal code 8234 // and may be about to die -- run this synchronously. 8235 worker.run(); 8236 } else { 8237 worker.start(); 8238 } 8239 } 8240 8241 /** 8242 * Bring up the "unexpected error" dialog box for a crashing app. 8243 * Deal with edge cases (intercepts from instrumented applications, 8244 * ActivityController, error intent receivers, that sort of thing). 8245 * @param r the application crashing 8246 * @param crashInfo describing the failure 8247 */ 8248 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8249 long timeMillis = System.currentTimeMillis(); 8250 String shortMsg = crashInfo.exceptionClassName; 8251 String longMsg = crashInfo.exceptionMessage; 8252 String stackTrace = crashInfo.stackTrace; 8253 if (shortMsg != null && longMsg != null) { 8254 longMsg = shortMsg + ": " + longMsg; 8255 } else if (shortMsg != null) { 8256 longMsg = shortMsg; 8257 } 8258 8259 AppErrorResult result = new AppErrorResult(); 8260 synchronized (this) { 8261 if (mController != null) { 8262 try { 8263 String name = r != null ? r.processName : null; 8264 int pid = r != null ? r.pid : Binder.getCallingPid(); 8265 if (!mController.appCrashed(name, pid, 8266 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8267 Slog.w(TAG, "Force-killing crashed app " + name 8268 + " at watcher's request"); 8269 Process.killProcess(pid); 8270 return; 8271 } 8272 } catch (RemoteException e) { 8273 mController = null; 8274 } 8275 } 8276 8277 final long origId = Binder.clearCallingIdentity(); 8278 8279 // If this process is running instrumentation, finish it. 8280 if (r != null && r.instrumentationClass != null) { 8281 Slog.w(TAG, "Error in app " + r.processName 8282 + " running instrumentation " + r.instrumentationClass + ":"); 8283 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8284 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8285 Bundle info = new Bundle(); 8286 info.putString("shortMsg", shortMsg); 8287 info.putString("longMsg", longMsg); 8288 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8289 Binder.restoreCallingIdentity(origId); 8290 return; 8291 } 8292 8293 // If we can't identify the process or it's already exceeded its crash quota, 8294 // quit right away without showing a crash dialog. 8295 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8296 Binder.restoreCallingIdentity(origId); 8297 return; 8298 } 8299 8300 Message msg = Message.obtain(); 8301 msg.what = SHOW_ERROR_MSG; 8302 HashMap data = new HashMap(); 8303 data.put("result", result); 8304 data.put("app", r); 8305 msg.obj = data; 8306 mHandler.sendMessage(msg); 8307 8308 Binder.restoreCallingIdentity(origId); 8309 } 8310 8311 int res = result.get(); 8312 8313 Intent appErrorIntent = null; 8314 synchronized (this) { 8315 if (r != null && !r.isolated) { 8316 // XXX Can't keep track of crash time for isolated processes, 8317 // since they don't have a persistent identity. 8318 mProcessCrashTimes.put(r.info.processName, r.uid, 8319 SystemClock.uptimeMillis()); 8320 } 8321 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8322 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8323 } 8324 } 8325 8326 if (appErrorIntent != null) { 8327 try { 8328 mContext.startActivity(appErrorIntent); 8329 } catch (ActivityNotFoundException e) { 8330 Slog.w(TAG, "bug report receiver dissappeared", e); 8331 } 8332 } 8333 } 8334 8335 Intent createAppErrorIntentLocked(ProcessRecord r, 8336 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8337 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8338 if (report == null) { 8339 return null; 8340 } 8341 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8342 result.setComponent(r.errorReportReceiver); 8343 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8344 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8345 return result; 8346 } 8347 8348 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8349 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8350 if (r.errorReportReceiver == null) { 8351 return null; 8352 } 8353 8354 if (!r.crashing && !r.notResponding) { 8355 return null; 8356 } 8357 8358 ApplicationErrorReport report = new ApplicationErrorReport(); 8359 report.packageName = r.info.packageName; 8360 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8361 report.processName = r.processName; 8362 report.time = timeMillis; 8363 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8364 8365 if (r.crashing) { 8366 report.type = ApplicationErrorReport.TYPE_CRASH; 8367 report.crashInfo = crashInfo; 8368 } else if (r.notResponding) { 8369 report.type = ApplicationErrorReport.TYPE_ANR; 8370 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8371 8372 report.anrInfo.activity = r.notRespondingReport.tag; 8373 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8374 report.anrInfo.info = r.notRespondingReport.longMsg; 8375 } 8376 8377 return report; 8378 } 8379 8380 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8381 enforceNotIsolatedCaller("getProcessesInErrorState"); 8382 // assume our apps are happy - lazy create the list 8383 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8384 8385 synchronized (this) { 8386 8387 // iterate across all processes 8388 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8389 ProcessRecord app = mLruProcesses.get(i); 8390 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8391 // This one's in trouble, so we'll generate a report for it 8392 // crashes are higher priority (in case there's a crash *and* an anr) 8393 ActivityManager.ProcessErrorStateInfo report = null; 8394 if (app.crashing) { 8395 report = app.crashingReport; 8396 } else if (app.notResponding) { 8397 report = app.notRespondingReport; 8398 } 8399 8400 if (report != null) { 8401 if (errList == null) { 8402 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8403 } 8404 errList.add(report); 8405 } else { 8406 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8407 " crashing = " + app.crashing + 8408 " notResponding = " + app.notResponding); 8409 } 8410 } 8411 } 8412 } 8413 8414 return errList; 8415 } 8416 8417 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8418 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8419 if (currApp != null) { 8420 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8421 } 8422 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8423 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8424 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8425 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8426 if (currApp != null) { 8427 currApp.lru = 0; 8428 } 8429 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8430 } else if (adj >= ProcessList.SERVICE_ADJ) { 8431 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8432 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8433 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8434 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8435 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8436 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8437 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8438 } else { 8439 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8440 } 8441 } 8442 8443 private void fillInProcMemInfo(ProcessRecord app, 8444 ActivityManager.RunningAppProcessInfo outInfo) { 8445 outInfo.pid = app.pid; 8446 outInfo.uid = app.info.uid; 8447 if (mHeavyWeightProcess == app) { 8448 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8449 } 8450 if (app.persistent) { 8451 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8452 } 8453 outInfo.lastTrimLevel = app.trimMemoryLevel; 8454 int adj = app.curAdj; 8455 outInfo.importance = oomAdjToImportance(adj, outInfo); 8456 outInfo.importanceReasonCode = app.adjTypeCode; 8457 } 8458 8459 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8460 enforceNotIsolatedCaller("getRunningAppProcesses"); 8461 // Lazy instantiation of list 8462 List<ActivityManager.RunningAppProcessInfo> runList = null; 8463 synchronized (this) { 8464 // Iterate across all processes 8465 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8466 ProcessRecord app = mLruProcesses.get(i); 8467 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8468 // Generate process state info for running application 8469 ActivityManager.RunningAppProcessInfo currApp = 8470 new ActivityManager.RunningAppProcessInfo(app.processName, 8471 app.pid, app.getPackageList()); 8472 fillInProcMemInfo(app, currApp); 8473 if (app.adjSource instanceof ProcessRecord) { 8474 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8475 currApp.importanceReasonImportance = oomAdjToImportance( 8476 app.adjSourceOom, null); 8477 } else if (app.adjSource instanceof ActivityRecord) { 8478 ActivityRecord r = (ActivityRecord)app.adjSource; 8479 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8480 } 8481 if (app.adjTarget instanceof ComponentName) { 8482 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8483 } 8484 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8485 // + " lru=" + currApp.lru); 8486 if (runList == null) { 8487 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8488 } 8489 runList.add(currApp); 8490 } 8491 } 8492 } 8493 return runList; 8494 } 8495 8496 public List<ApplicationInfo> getRunningExternalApplications() { 8497 enforceNotIsolatedCaller("getRunningExternalApplications"); 8498 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8499 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8500 if (runningApps != null && runningApps.size() > 0) { 8501 Set<String> extList = new HashSet<String>(); 8502 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8503 if (app.pkgList != null) { 8504 for (String pkg : app.pkgList) { 8505 extList.add(pkg); 8506 } 8507 } 8508 } 8509 IPackageManager pm = AppGlobals.getPackageManager(); 8510 for (String pkg : extList) { 8511 try { 8512 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8513 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8514 retList.add(info); 8515 } 8516 } catch (RemoteException e) { 8517 } 8518 } 8519 } 8520 return retList; 8521 } 8522 8523 @Override 8524 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8525 enforceNotIsolatedCaller("getMyMemoryState"); 8526 synchronized (this) { 8527 ProcessRecord proc; 8528 synchronized (mPidsSelfLocked) { 8529 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8530 } 8531 fillInProcMemInfo(proc, outInfo); 8532 } 8533 } 8534 8535 @Override 8536 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8537 if (checkCallingPermission(android.Manifest.permission.DUMP) 8538 != PackageManager.PERMISSION_GRANTED) { 8539 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8540 + Binder.getCallingPid() 8541 + ", uid=" + Binder.getCallingUid() 8542 + " without permission " 8543 + android.Manifest.permission.DUMP); 8544 return; 8545 } 8546 8547 boolean dumpAll = false; 8548 boolean dumpClient = false; 8549 String dumpPackage = null; 8550 8551 int opti = 0; 8552 while (opti < args.length) { 8553 String opt = args[opti]; 8554 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8555 break; 8556 } 8557 opti++; 8558 if ("-a".equals(opt)) { 8559 dumpAll = true; 8560 } else if ("-c".equals(opt)) { 8561 dumpClient = true; 8562 } else if ("-h".equals(opt)) { 8563 pw.println("Activity manager dump options:"); 8564 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8565 pw.println(" cmd may be one of:"); 8566 pw.println(" a[ctivities]: activity stack state"); 8567 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8568 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8569 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8570 pw.println(" o[om]: out of memory management"); 8571 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8572 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8573 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8574 pw.println(" service [COMP_SPEC]: service client-side state"); 8575 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8576 pw.println(" all: dump all activities"); 8577 pw.println(" top: dump the top activity"); 8578 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8579 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8580 pw.println(" a partial substring in a component name, a"); 8581 pw.println(" hex object identifier."); 8582 pw.println(" -a: include all available server state."); 8583 pw.println(" -c: include client state."); 8584 return; 8585 } else { 8586 pw.println("Unknown argument: " + opt + "; use -h for help"); 8587 } 8588 } 8589 8590 long origId = Binder.clearCallingIdentity(); 8591 boolean more = false; 8592 // Is the caller requesting to dump a particular piece of data? 8593 if (opti < args.length) { 8594 String cmd = args[opti]; 8595 opti++; 8596 if ("activities".equals(cmd) || "a".equals(cmd)) { 8597 synchronized (this) { 8598 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8599 } 8600 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8601 String[] newArgs; 8602 String name; 8603 if (opti >= args.length) { 8604 name = null; 8605 newArgs = EMPTY_STRING_ARRAY; 8606 } else { 8607 name = args[opti]; 8608 opti++; 8609 newArgs = new String[args.length - opti]; 8610 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8611 args.length - opti); 8612 } 8613 synchronized (this) { 8614 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8615 } 8616 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8617 String[] newArgs; 8618 String name; 8619 if (opti >= args.length) { 8620 name = null; 8621 newArgs = EMPTY_STRING_ARRAY; 8622 } else { 8623 name = args[opti]; 8624 opti++; 8625 newArgs = new String[args.length - opti]; 8626 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8627 args.length - opti); 8628 } 8629 synchronized (this) { 8630 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8631 } 8632 } else if ("processes".equals(cmd) || "p".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, 8643 args.length - opti); 8644 } 8645 synchronized (this) { 8646 dumpProcessesLocked(fd, pw, args, opti, true, name); 8647 } 8648 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8649 synchronized (this) { 8650 dumpOomLocked(fd, pw, args, opti, true); 8651 } 8652 } else if ("provider".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, args.length - opti); 8663 } 8664 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8665 pw.println("No providers match: " + name); 8666 pw.println("Use -h for help."); 8667 } 8668 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8669 synchronized (this) { 8670 dumpProvidersLocked(fd, pw, args, opti, true, null); 8671 } 8672 } else if ("service".equals(cmd)) { 8673 String[] newArgs; 8674 String name; 8675 if (opti >= args.length) { 8676 name = null; 8677 newArgs = EMPTY_STRING_ARRAY; 8678 } else { 8679 name = args[opti]; 8680 opti++; 8681 newArgs = new String[args.length - opti]; 8682 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8683 args.length - opti); 8684 } 8685 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8686 pw.println("No services match: " + name); 8687 pw.println("Use -h for help."); 8688 } 8689 } else if ("package".equals(cmd)) { 8690 String[] newArgs; 8691 if (opti >= args.length) { 8692 pw.println("package: no package name specified"); 8693 pw.println("Use -h for help."); 8694 } else { 8695 dumpPackage = args[opti]; 8696 opti++; 8697 newArgs = new String[args.length - opti]; 8698 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8699 args.length - opti); 8700 args = newArgs; 8701 opti = 0; 8702 more = true; 8703 } 8704 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8705 synchronized (this) { 8706 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8707 } 8708 } else { 8709 // Dumping a single activity? 8710 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8711 pw.println("Bad activity command, or no activities match: " + cmd); 8712 pw.println("Use -h for help."); 8713 } 8714 } 8715 if (!more) { 8716 Binder.restoreCallingIdentity(origId); 8717 return; 8718 } 8719 } 8720 8721 // No piece of data specified, dump everything. 8722 synchronized (this) { 8723 boolean needSep; 8724 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8725 if (needSep) { 8726 pw.println(" "); 8727 } 8728 if (dumpAll) { 8729 pw.println("-------------------------------------------------------------------------------"); 8730 } 8731 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8732 if (needSep) { 8733 pw.println(" "); 8734 } 8735 if (dumpAll) { 8736 pw.println("-------------------------------------------------------------------------------"); 8737 } 8738 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8739 if (needSep) { 8740 pw.println(" "); 8741 } 8742 if (dumpAll) { 8743 pw.println("-------------------------------------------------------------------------------"); 8744 } 8745 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8746 if (needSep) { 8747 pw.println(" "); 8748 } 8749 if (dumpAll) { 8750 pw.println("-------------------------------------------------------------------------------"); 8751 } 8752 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8753 if (needSep) { 8754 pw.println(" "); 8755 } 8756 if (dumpAll) { 8757 pw.println("-------------------------------------------------------------------------------"); 8758 } 8759 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8760 } 8761 Binder.restoreCallingIdentity(origId); 8762 } 8763 8764 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8765 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8766 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8767 pw.println(" Main stack:"); 8768 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8769 dumpPackage); 8770 pw.println(" "); 8771 pw.println(" Running activities (most recent first):"); 8772 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8773 dumpPackage); 8774 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8775 pw.println(" "); 8776 pw.println(" Activities waiting for another to become visible:"); 8777 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8778 !dumpAll, false, dumpPackage); 8779 } 8780 if (mMainStack.mStoppingActivities.size() > 0) { 8781 pw.println(" "); 8782 pw.println(" Activities waiting to stop:"); 8783 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8784 !dumpAll, false, dumpPackage); 8785 } 8786 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8787 pw.println(" "); 8788 pw.println(" Activities waiting to sleep:"); 8789 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8790 !dumpAll, false, dumpPackage); 8791 } 8792 if (mMainStack.mFinishingActivities.size() > 0) { 8793 pw.println(" "); 8794 pw.println(" Activities waiting to finish:"); 8795 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8796 !dumpAll, false, dumpPackage); 8797 } 8798 8799 pw.println(" "); 8800 if (mMainStack.mPausingActivity != null) { 8801 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8802 } 8803 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8804 pw.println(" mFocusedActivity: " + mFocusedActivity); 8805 if (dumpAll) { 8806 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8807 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8808 pw.println(" mDismissKeyguardOnNextActivity: " 8809 + mMainStack.mDismissKeyguardOnNextActivity); 8810 } 8811 8812 if (mRecentTasks.size() > 0) { 8813 pw.println(); 8814 pw.println(" Recent tasks:"); 8815 8816 final int N = mRecentTasks.size(); 8817 for (int i=0; i<N; i++) { 8818 TaskRecord tr = mRecentTasks.get(i); 8819 if (dumpPackage != null) { 8820 if (tr.realActivity == null || 8821 !dumpPackage.equals(tr.realActivity)) { 8822 continue; 8823 } 8824 } 8825 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8826 pw.println(tr); 8827 if (dumpAll) { 8828 mRecentTasks.get(i).dump(pw, " "); 8829 } 8830 } 8831 } 8832 8833 if (dumpAll) { 8834 pw.println(" "); 8835 pw.println(" mCurTask: " + mCurTask); 8836 } 8837 8838 return true; 8839 } 8840 8841 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8842 int opti, boolean dumpAll, String dumpPackage) { 8843 boolean needSep = false; 8844 int numPers = 0; 8845 8846 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8847 8848 if (dumpAll) { 8849 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8850 final int NA = procs.size(); 8851 for (int ia=0; ia<NA; ia++) { 8852 ProcessRecord r = procs.valueAt(ia); 8853 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8854 continue; 8855 } 8856 if (!needSep) { 8857 pw.println(" All known processes:"); 8858 needSep = true; 8859 } 8860 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8861 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8862 pw.print(" "); pw.println(r); 8863 r.dump(pw, " "); 8864 if (r.persistent) { 8865 numPers++; 8866 } 8867 } 8868 } 8869 } 8870 8871 if (mIsolatedProcesses.size() > 0) { 8872 if (needSep) pw.println(" "); 8873 needSep = true; 8874 pw.println(" Isolated process list (sorted by uid):"); 8875 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8876 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8877 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8878 continue; 8879 } 8880 pw.println(String.format("%sIsolated #%2d: %s", 8881 " ", i, r.toString())); 8882 } 8883 } 8884 8885 if (mLruProcesses.size() > 0) { 8886 if (needSep) pw.println(" "); 8887 needSep = true; 8888 pw.println(" Process LRU list (sorted by oom_adj):"); 8889 dumpProcessOomList(pw, this, mLruProcesses, " ", 8890 "Proc", "PERS", false, dumpPackage); 8891 needSep = true; 8892 } 8893 8894 if (dumpAll) { 8895 synchronized (mPidsSelfLocked) { 8896 boolean printed = false; 8897 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8898 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8899 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8900 continue; 8901 } 8902 if (!printed) { 8903 if (needSep) pw.println(" "); 8904 needSep = true; 8905 pw.println(" PID mappings:"); 8906 printed = true; 8907 } 8908 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8909 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8910 } 8911 } 8912 } 8913 8914 if (mForegroundProcesses.size() > 0) { 8915 synchronized (mPidsSelfLocked) { 8916 boolean printed = false; 8917 for (int i=0; i<mForegroundProcesses.size(); i++) { 8918 ProcessRecord r = mPidsSelfLocked.get( 8919 mForegroundProcesses.valueAt(i).pid); 8920 if (dumpPackage != null && (r == null 8921 || !dumpPackage.equals(r.info.packageName))) { 8922 continue; 8923 } 8924 if (!printed) { 8925 if (needSep) pw.println(" "); 8926 needSep = true; 8927 pw.println(" Foreground Processes:"); 8928 printed = true; 8929 } 8930 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8931 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8932 } 8933 } 8934 } 8935 8936 if (mPersistentStartingProcesses.size() > 0) { 8937 if (needSep) pw.println(" "); 8938 needSep = true; 8939 pw.println(" Persisent processes that are starting:"); 8940 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8941 "Starting Norm", "Restarting PERS", dumpPackage); 8942 } 8943 8944 if (mRemovedProcesses.size() > 0) { 8945 if (needSep) pw.println(" "); 8946 needSep = true; 8947 pw.println(" Processes that are being removed:"); 8948 dumpProcessList(pw, this, mRemovedProcesses, " ", 8949 "Removed Norm", "Removed PERS", dumpPackage); 8950 } 8951 8952 if (mProcessesOnHold.size() > 0) { 8953 if (needSep) pw.println(" "); 8954 needSep = true; 8955 pw.println(" Processes that are on old until the system is ready:"); 8956 dumpProcessList(pw, this, mProcessesOnHold, " ", 8957 "OnHold Norm", "OnHold PERS", dumpPackage); 8958 } 8959 8960 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8961 8962 if (mProcessCrashTimes.getMap().size() > 0) { 8963 boolean printed = false; 8964 long now = SystemClock.uptimeMillis(); 8965 for (Map.Entry<String, SparseArray<Long>> procs 8966 : mProcessCrashTimes.getMap().entrySet()) { 8967 String pname = procs.getKey(); 8968 SparseArray<Long> uids = procs.getValue(); 8969 final int N = uids.size(); 8970 for (int i=0; i<N; i++) { 8971 int puid = uids.keyAt(i); 8972 ProcessRecord r = mProcessNames.get(pname, puid); 8973 if (dumpPackage != null && (r == null 8974 || !dumpPackage.equals(r.info.packageName))) { 8975 continue; 8976 } 8977 if (!printed) { 8978 if (needSep) pw.println(" "); 8979 needSep = true; 8980 pw.println(" Time since processes crashed:"); 8981 printed = true; 8982 } 8983 pw.print(" Process "); pw.print(pname); 8984 pw.print(" uid "); pw.print(puid); 8985 pw.print(": last crashed "); 8986 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 8987 pw.println(" ago"); 8988 } 8989 } 8990 } 8991 8992 if (mBadProcesses.getMap().size() > 0) { 8993 boolean printed = false; 8994 for (Map.Entry<String, SparseArray<Long>> procs 8995 : mBadProcesses.getMap().entrySet()) { 8996 String pname = procs.getKey(); 8997 SparseArray<Long> uids = procs.getValue(); 8998 final int N = uids.size(); 8999 for (int i=0; i<N; i++) { 9000 int puid = uids.keyAt(i); 9001 ProcessRecord r = mProcessNames.get(pname, puid); 9002 if (dumpPackage != null && (r == null 9003 || !dumpPackage.equals(r.info.packageName))) { 9004 continue; 9005 } 9006 if (!printed) { 9007 if (needSep) pw.println(" "); 9008 needSep = true; 9009 pw.println(" Bad processes:"); 9010 } 9011 pw.print(" Bad process "); pw.print(pname); 9012 pw.print(" uid "); pw.print(puid); 9013 pw.print(": crashed at time "); 9014 pw.println(uids.valueAt(i)); 9015 } 9016 } 9017 } 9018 9019 pw.println(); 9020 pw.println(" mHomeProcess: " + mHomeProcess); 9021 pw.println(" mPreviousProcess: " + mPreviousProcess); 9022 if (dumpAll) { 9023 StringBuilder sb = new StringBuilder(128); 9024 sb.append(" mPreviousProcessVisibleTime: "); 9025 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9026 pw.println(sb); 9027 } 9028 if (mHeavyWeightProcess != null) { 9029 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9030 } 9031 pw.println(" mConfiguration: " + mConfiguration); 9032 if (dumpAll) { 9033 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9034 if (mCompatModePackages.getPackages().size() > 0) { 9035 boolean printed = false; 9036 for (Map.Entry<String, Integer> entry 9037 : mCompatModePackages.getPackages().entrySet()) { 9038 String pkg = entry.getKey(); 9039 int mode = entry.getValue(); 9040 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9041 continue; 9042 } 9043 if (!printed) { 9044 pw.println(" mScreenCompatPackages:"); 9045 printed = true; 9046 } 9047 pw.print(" "); pw.print(pkg); pw.print(": "); 9048 pw.print(mode); pw.println(); 9049 } 9050 } 9051 } 9052 if (mSleeping || mWentToSleep || mLockScreenShown) { 9053 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9054 + " mLockScreenShown " + mLockScreenShown); 9055 } 9056 if (mShuttingDown) { 9057 pw.println(" mShuttingDown=" + mShuttingDown); 9058 } 9059 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9060 || mOrigWaitForDebugger) { 9061 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9062 + " mDebugTransient=" + mDebugTransient 9063 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9064 } 9065 if (mOpenGlTraceApp != null) { 9066 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9067 } 9068 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9069 || mProfileFd != null) { 9070 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9071 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9072 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9073 + mAutoStopProfiler); 9074 } 9075 if (mAlwaysFinishActivities || mController != null) { 9076 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9077 + " mController=" + mController); 9078 } 9079 if (dumpAll) { 9080 pw.println(" Total persistent processes: " + numPers); 9081 pw.println(" mStartRunning=" + mStartRunning 9082 + " mProcessesReady=" + mProcessesReady 9083 + " mSystemReady=" + mSystemReady); 9084 pw.println(" mBooting=" + mBooting 9085 + " mBooted=" + mBooted 9086 + " mFactoryTest=" + mFactoryTest); 9087 pw.print(" mLastPowerCheckRealtime="); 9088 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9089 pw.println(""); 9090 pw.print(" mLastPowerCheckUptime="); 9091 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9092 pw.println(""); 9093 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9094 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9095 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9096 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9097 + " mNumHiddenProcs=" + mNumHiddenProcs 9098 + " mNumServiceProcs=" + mNumServiceProcs 9099 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9100 } 9101 9102 return true; 9103 } 9104 9105 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9106 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9107 if (mProcessesToGc.size() > 0) { 9108 boolean printed = false; 9109 long now = SystemClock.uptimeMillis(); 9110 for (int i=0; i<mProcessesToGc.size(); i++) { 9111 ProcessRecord proc = mProcessesToGc.get(i); 9112 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9113 continue; 9114 } 9115 if (!printed) { 9116 if (needSep) pw.println(" "); 9117 needSep = true; 9118 pw.println(" Processes that are waiting to GC:"); 9119 printed = true; 9120 } 9121 pw.print(" Process "); pw.println(proc); 9122 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9123 pw.print(", last gced="); 9124 pw.print(now-proc.lastRequestedGc); 9125 pw.print(" ms ago, last lowMem="); 9126 pw.print(now-proc.lastLowMemory); 9127 pw.println(" ms ago"); 9128 9129 } 9130 } 9131 return needSep; 9132 } 9133 9134 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9135 int opti, boolean dumpAll) { 9136 boolean needSep = false; 9137 9138 if (mLruProcesses.size() > 0) { 9139 if (needSep) pw.println(" "); 9140 needSep = true; 9141 pw.println(" OOM levels:"); 9142 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9143 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9144 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9145 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9146 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9147 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9148 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9149 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9150 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9151 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9152 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9153 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9154 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9155 9156 if (needSep) pw.println(" "); 9157 needSep = true; 9158 pw.println(" Process OOM control:"); 9159 dumpProcessOomList(pw, this, mLruProcesses, " ", 9160 "Proc", "PERS", true, null); 9161 needSep = true; 9162 } 9163 9164 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9165 9166 pw.println(); 9167 pw.println(" mHomeProcess: " + mHomeProcess); 9168 pw.println(" mPreviousProcess: " + mPreviousProcess); 9169 if (mHeavyWeightProcess != null) { 9170 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9171 } 9172 9173 return true; 9174 } 9175 9176 /** 9177 * There are three ways to call this: 9178 * - no provider specified: dump all the providers 9179 * - a flattened component name that matched an existing provider was specified as the 9180 * first arg: dump that one provider 9181 * - the first arg isn't the flattened component name of an existing provider: 9182 * dump all providers whose component contains the first arg as a substring 9183 */ 9184 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9185 int opti, boolean dumpAll) { 9186 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9187 } 9188 9189 static class ItemMatcher { 9190 ArrayList<ComponentName> components; 9191 ArrayList<String> strings; 9192 ArrayList<Integer> objects; 9193 boolean all; 9194 9195 ItemMatcher() { 9196 all = true; 9197 } 9198 9199 void build(String name) { 9200 ComponentName componentName = ComponentName.unflattenFromString(name); 9201 if (componentName != null) { 9202 if (components == null) { 9203 components = new ArrayList<ComponentName>(); 9204 } 9205 components.add(componentName); 9206 all = false; 9207 } else { 9208 int objectId = 0; 9209 // Not a '/' separated full component name; maybe an object ID? 9210 try { 9211 objectId = Integer.parseInt(name, 16); 9212 if (objects == null) { 9213 objects = new ArrayList<Integer>(); 9214 } 9215 objects.add(objectId); 9216 all = false; 9217 } catch (RuntimeException e) { 9218 // Not an integer; just do string match. 9219 if (strings == null) { 9220 strings = new ArrayList<String>(); 9221 } 9222 strings.add(name); 9223 all = false; 9224 } 9225 } 9226 } 9227 9228 int build(String[] args, int opti) { 9229 for (; opti<args.length; opti++) { 9230 String name = args[opti]; 9231 if ("--".equals(name)) { 9232 return opti+1; 9233 } 9234 build(name); 9235 } 9236 return opti; 9237 } 9238 9239 boolean match(Object object, ComponentName comp) { 9240 if (all) { 9241 return true; 9242 } 9243 if (components != null) { 9244 for (int i=0; i<components.size(); i++) { 9245 if (components.get(i).equals(comp)) { 9246 return true; 9247 } 9248 } 9249 } 9250 if (objects != null) { 9251 for (int i=0; i<objects.size(); i++) { 9252 if (System.identityHashCode(object) == objects.get(i)) { 9253 return true; 9254 } 9255 } 9256 } 9257 if (strings != null) { 9258 String flat = comp.flattenToString(); 9259 for (int i=0; i<strings.size(); i++) { 9260 if (flat.contains(strings.get(i))) { 9261 return true; 9262 } 9263 } 9264 } 9265 return false; 9266 } 9267 } 9268 9269 /** 9270 * There are three things that cmd can be: 9271 * - a flattened component name that matches an existing activity 9272 * - the cmd arg isn't the flattened component name of an existing activity: 9273 * dump all activity whose component contains the cmd as a substring 9274 * - A hex number of the ActivityRecord object instance. 9275 */ 9276 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9277 int opti, boolean dumpAll) { 9278 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9279 9280 if ("all".equals(name)) { 9281 synchronized (this) { 9282 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9283 activities.add(r1); 9284 } 9285 } 9286 } else if ("top".equals(name)) { 9287 synchronized (this) { 9288 final int N = mMainStack.mHistory.size(); 9289 if (N > 0) { 9290 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9291 } 9292 } 9293 } else { 9294 ItemMatcher matcher = new ItemMatcher(); 9295 matcher.build(name); 9296 9297 synchronized (this) { 9298 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9299 if (matcher.match(r1, r1.intent.getComponent())) { 9300 activities.add(r1); 9301 } 9302 } 9303 } 9304 } 9305 9306 if (activities.size() <= 0) { 9307 return false; 9308 } 9309 9310 String[] newArgs = new String[args.length - opti]; 9311 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9312 9313 TaskRecord lastTask = null; 9314 boolean needSep = false; 9315 for (int i=activities.size()-1; i>=0; i--) { 9316 ActivityRecord r = (ActivityRecord)activities.get(i); 9317 if (needSep) { 9318 pw.println(); 9319 } 9320 needSep = true; 9321 synchronized (this) { 9322 if (lastTask != r.task) { 9323 lastTask = r.task; 9324 pw.print("TASK "); pw.print(lastTask.affinity); 9325 pw.print(" id="); pw.println(lastTask.taskId); 9326 if (dumpAll) { 9327 lastTask.dump(pw, " "); 9328 } 9329 } 9330 } 9331 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9332 } 9333 return true; 9334 } 9335 9336 /** 9337 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9338 * there is a thread associated with the activity. 9339 */ 9340 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9341 final ActivityRecord r, String[] args, boolean dumpAll) { 9342 String innerPrefix = prefix + " "; 9343 synchronized (this) { 9344 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9345 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9346 pw.print(" pid="); 9347 if (r.app != null) pw.println(r.app.pid); 9348 else pw.println("(not running)"); 9349 if (dumpAll) { 9350 r.dump(pw, innerPrefix); 9351 } 9352 } 9353 if (r.app != null && r.app.thread != null) { 9354 // flush anything that is already in the PrintWriter since the thread is going 9355 // to write to the file descriptor directly 9356 pw.flush(); 9357 try { 9358 TransferPipe tp = new TransferPipe(); 9359 try { 9360 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9361 r.appToken, innerPrefix, args); 9362 tp.go(fd); 9363 } finally { 9364 tp.kill(); 9365 } 9366 } catch (IOException e) { 9367 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9368 } catch (RemoteException e) { 9369 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9370 } 9371 } 9372 } 9373 9374 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9375 int opti, boolean dumpAll, String dumpPackage) { 9376 boolean needSep = false; 9377 9378 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9379 if (dumpAll) { 9380 if (mRegisteredReceivers.size() > 0) { 9381 boolean printed = false; 9382 Iterator it = mRegisteredReceivers.values().iterator(); 9383 while (it.hasNext()) { 9384 ReceiverList r = (ReceiverList)it.next(); 9385 if (dumpPackage != null && (r.app == null || 9386 !dumpPackage.equals(r.app.info.packageName))) { 9387 continue; 9388 } 9389 if (!printed) { 9390 pw.println(" Registered Receivers:"); 9391 needSep = true; 9392 printed = true; 9393 } 9394 pw.print(" * "); pw.println(r); 9395 r.dump(pw, " "); 9396 } 9397 } 9398 9399 if (mReceiverResolver.dump(pw, needSep ? 9400 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9401 " ", dumpPackage, false)) { 9402 needSep = true; 9403 } 9404 } 9405 9406 for (BroadcastQueue q : mBroadcastQueues) { 9407 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9408 } 9409 9410 needSep = true; 9411 9412 if (mStickyBroadcasts != null && dumpPackage == null) { 9413 if (needSep) { 9414 pw.println(); 9415 } 9416 needSep = true; 9417 pw.println(" Sticky broadcasts:"); 9418 StringBuilder sb = new StringBuilder(128); 9419 for (Map.Entry<String, ArrayList<Intent>> ent 9420 : mStickyBroadcasts.entrySet()) { 9421 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9422 if (dumpAll) { 9423 pw.println(":"); 9424 ArrayList<Intent> intents = ent.getValue(); 9425 final int N = intents.size(); 9426 for (int i=0; i<N; i++) { 9427 sb.setLength(0); 9428 sb.append(" Intent: "); 9429 intents.get(i).toShortString(sb, false, true, false, false); 9430 pw.println(sb.toString()); 9431 Bundle bundle = intents.get(i).getExtras(); 9432 if (bundle != null) { 9433 pw.print(" "); 9434 pw.println(bundle.toString()); 9435 } 9436 } 9437 } else { 9438 pw.println(""); 9439 } 9440 } 9441 needSep = true; 9442 } 9443 9444 if (dumpAll) { 9445 pw.println(); 9446 for (BroadcastQueue queue : mBroadcastQueues) { 9447 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9448 + queue.mBroadcastsScheduled); 9449 } 9450 pw.println(" mHandler:"); 9451 mHandler.dump(new PrintWriterPrinter(pw), " "); 9452 needSep = true; 9453 } 9454 9455 return needSep; 9456 } 9457 9458 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9459 int opti, boolean dumpAll, String dumpPackage) { 9460 boolean needSep = true; 9461 9462 ItemMatcher matcher = new ItemMatcher(); 9463 matcher.build(args, opti); 9464 9465 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9466 9467 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9468 9469 if (mLaunchingProviders.size() > 0) { 9470 boolean printed = false; 9471 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9472 ContentProviderRecord r = mLaunchingProviders.get(i); 9473 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9474 continue; 9475 } 9476 if (!printed) { 9477 if (needSep) pw.println(" "); 9478 needSep = true; 9479 pw.println(" Launching content providers:"); 9480 printed = true; 9481 } 9482 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9483 pw.println(r); 9484 } 9485 } 9486 9487 if (mGrantedUriPermissions.size() > 0) { 9488 if (needSep) pw.println(); 9489 needSep = true; 9490 pw.println("Granted Uri Permissions:"); 9491 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9492 int uid = mGrantedUriPermissions.keyAt(i); 9493 HashMap<Uri, UriPermission> perms 9494 = mGrantedUriPermissions.valueAt(i); 9495 pw.print(" * UID "); pw.print(uid); 9496 pw.println(" holds:"); 9497 for (UriPermission perm : perms.values()) { 9498 pw.print(" "); pw.println(perm); 9499 if (dumpAll) { 9500 perm.dump(pw, " "); 9501 } 9502 } 9503 } 9504 needSep = true; 9505 } 9506 9507 return needSep; 9508 } 9509 9510 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9511 int opti, boolean dumpAll, String dumpPackage) { 9512 boolean needSep = false; 9513 9514 if (mIntentSenderRecords.size() > 0) { 9515 boolean printed = false; 9516 Iterator<WeakReference<PendingIntentRecord>> it 9517 = mIntentSenderRecords.values().iterator(); 9518 while (it.hasNext()) { 9519 WeakReference<PendingIntentRecord> ref = it.next(); 9520 PendingIntentRecord rec = ref != null ? ref.get(): null; 9521 if (dumpPackage != null && (rec == null 9522 || !dumpPackage.equals(rec.key.packageName))) { 9523 continue; 9524 } 9525 if (!printed) { 9526 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9527 printed = true; 9528 } 9529 needSep = true; 9530 if (rec != null) { 9531 pw.print(" * "); pw.println(rec); 9532 if (dumpAll) { 9533 rec.dump(pw, " "); 9534 } 9535 } else { 9536 pw.print(" * "); pw.println(ref); 9537 } 9538 } 9539 } 9540 9541 return needSep; 9542 } 9543 9544 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9545 String prefix, String label, boolean complete, boolean brief, boolean client, 9546 String dumpPackage) { 9547 TaskRecord lastTask = null; 9548 boolean needNL = false; 9549 final String innerPrefix = prefix + " "; 9550 final String[] args = new String[0]; 9551 for (int i=list.size()-1; i>=0; i--) { 9552 final ActivityRecord r = (ActivityRecord)list.get(i); 9553 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9554 continue; 9555 } 9556 final boolean full = !brief && (complete || !r.isInHistory()); 9557 if (needNL) { 9558 pw.println(" "); 9559 needNL = false; 9560 } 9561 if (lastTask != r.task) { 9562 lastTask = r.task; 9563 pw.print(prefix); 9564 pw.print(full ? "* " : " "); 9565 pw.println(lastTask); 9566 if (full) { 9567 lastTask.dump(pw, prefix + " "); 9568 } else if (complete) { 9569 // Complete + brief == give a summary. Isn't that obvious?!? 9570 if (lastTask.intent != null) { 9571 pw.print(prefix); pw.print(" "); 9572 pw.println(lastTask.intent.toInsecureStringWithClip()); 9573 } 9574 } 9575 } 9576 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9577 pw.print(" #"); pw.print(i); pw.print(": "); 9578 pw.println(r); 9579 if (full) { 9580 r.dump(pw, innerPrefix); 9581 } else if (complete) { 9582 // Complete + brief == give a summary. Isn't that obvious?!? 9583 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9584 if (r.app != null) { 9585 pw.print(innerPrefix); pw.println(r.app); 9586 } 9587 } 9588 if (client && r.app != null && r.app.thread != null) { 9589 // flush anything that is already in the PrintWriter since the thread is going 9590 // to write to the file descriptor directly 9591 pw.flush(); 9592 try { 9593 TransferPipe tp = new TransferPipe(); 9594 try { 9595 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9596 r.appToken, innerPrefix, args); 9597 // Short timeout, since blocking here can 9598 // deadlock with the application. 9599 tp.go(fd, 2000); 9600 } finally { 9601 tp.kill(); 9602 } 9603 } catch (IOException e) { 9604 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9605 } catch (RemoteException e) { 9606 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9607 } 9608 needNL = true; 9609 } 9610 } 9611 } 9612 9613 private static String buildOomTag(String prefix, String space, int val, int base) { 9614 if (val == base) { 9615 if (space == null) return prefix; 9616 return prefix + " "; 9617 } 9618 return prefix + "+" + Integer.toString(val-base); 9619 } 9620 9621 private static final int dumpProcessList(PrintWriter pw, 9622 ActivityManagerService service, List list, 9623 String prefix, String normalLabel, String persistentLabel, 9624 String dumpPackage) { 9625 int numPers = 0; 9626 final int N = list.size()-1; 9627 for (int i=N; i>=0; i--) { 9628 ProcessRecord r = (ProcessRecord)list.get(i); 9629 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9630 continue; 9631 } 9632 pw.println(String.format("%s%s #%2d: %s", 9633 prefix, (r.persistent ? persistentLabel : normalLabel), 9634 i, r.toString())); 9635 if (r.persistent) { 9636 numPers++; 9637 } 9638 } 9639 return numPers; 9640 } 9641 9642 private static final boolean dumpProcessOomList(PrintWriter pw, 9643 ActivityManagerService service, List<ProcessRecord> origList, 9644 String prefix, String normalLabel, String persistentLabel, 9645 boolean inclDetails, String dumpPackage) { 9646 9647 ArrayList<Pair<ProcessRecord, Integer>> list 9648 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9649 for (int i=0; i<origList.size(); i++) { 9650 ProcessRecord r = origList.get(i); 9651 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9652 continue; 9653 } 9654 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9655 } 9656 9657 if (list.size() <= 0) { 9658 return false; 9659 } 9660 9661 Comparator<Pair<ProcessRecord, Integer>> comparator 9662 = new Comparator<Pair<ProcessRecord, Integer>>() { 9663 @Override 9664 public int compare(Pair<ProcessRecord, Integer> object1, 9665 Pair<ProcessRecord, Integer> object2) { 9666 if (object1.first.setAdj != object2.first.setAdj) { 9667 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9668 } 9669 if (object1.second.intValue() != object2.second.intValue()) { 9670 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9671 } 9672 return 0; 9673 } 9674 }; 9675 9676 Collections.sort(list, comparator); 9677 9678 final long curRealtime = SystemClock.elapsedRealtime(); 9679 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9680 final long curUptime = SystemClock.uptimeMillis(); 9681 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9682 9683 for (int i=list.size()-1; i>=0; i--) { 9684 ProcessRecord r = list.get(i).first; 9685 String oomAdj; 9686 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9687 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9688 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9689 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9690 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9691 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9692 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9693 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9694 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9695 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9696 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9697 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9698 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9699 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9700 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9701 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9702 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9703 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9704 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9705 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9706 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9707 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9708 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9709 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9710 } else { 9711 oomAdj = Integer.toString(r.setAdj); 9712 } 9713 String schedGroup; 9714 switch (r.setSchedGroup) { 9715 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9716 schedGroup = "B"; 9717 break; 9718 case Process.THREAD_GROUP_DEFAULT: 9719 schedGroup = "F"; 9720 break; 9721 default: 9722 schedGroup = Integer.toString(r.setSchedGroup); 9723 break; 9724 } 9725 String foreground; 9726 if (r.foregroundActivities) { 9727 foreground = "A"; 9728 } else if (r.foregroundServices) { 9729 foreground = "S"; 9730 } else { 9731 foreground = " "; 9732 } 9733 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9734 prefix, (r.persistent ? persistentLabel : normalLabel), 9735 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9736 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9737 if (r.adjSource != null || r.adjTarget != null) { 9738 pw.print(prefix); 9739 pw.print(" "); 9740 if (r.adjTarget instanceof ComponentName) { 9741 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9742 } else if (r.adjTarget != null) { 9743 pw.print(r.adjTarget.toString()); 9744 } else { 9745 pw.print("{null}"); 9746 } 9747 pw.print("<="); 9748 if (r.adjSource instanceof ProcessRecord) { 9749 pw.print("Proc{"); 9750 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9751 pw.println("}"); 9752 } else if (r.adjSource != null) { 9753 pw.println(r.adjSource.toString()); 9754 } else { 9755 pw.println("{null}"); 9756 } 9757 } 9758 if (inclDetails) { 9759 pw.print(prefix); 9760 pw.print(" "); 9761 pw.print("oom: max="); pw.print(r.maxAdj); 9762 pw.print(" hidden="); pw.print(r.hiddenAdj); 9763 pw.print(" empty="); pw.print(r.emptyAdj); 9764 pw.print(" curRaw="); pw.print(r.curRawAdj); 9765 pw.print(" setRaw="); pw.print(r.setRawAdj); 9766 pw.print(" cur="); pw.print(r.curAdj); 9767 pw.print(" set="); pw.println(r.setAdj); 9768 pw.print(prefix); 9769 pw.print(" "); 9770 pw.print("keeping="); pw.print(r.keeping); 9771 pw.print(" hidden="); pw.print(r.hidden); 9772 pw.print(" empty="); pw.print(r.empty); 9773 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9774 9775 if (!r.keeping) { 9776 if (r.lastWakeTime != 0) { 9777 long wtime; 9778 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9779 synchronized (stats) { 9780 wtime = stats.getProcessWakeTime(r.info.uid, 9781 r.pid, curRealtime); 9782 } 9783 long timeUsed = wtime - r.lastWakeTime; 9784 pw.print(prefix); 9785 pw.print(" "); 9786 pw.print("keep awake over "); 9787 TimeUtils.formatDuration(realtimeSince, pw); 9788 pw.print(" used "); 9789 TimeUtils.formatDuration(timeUsed, pw); 9790 pw.print(" ("); 9791 pw.print((timeUsed*100)/realtimeSince); 9792 pw.println("%)"); 9793 } 9794 if (r.lastCpuTime != 0) { 9795 long timeUsed = r.curCpuTime - r.lastCpuTime; 9796 pw.print(prefix); 9797 pw.print(" "); 9798 pw.print("run cpu over "); 9799 TimeUtils.formatDuration(uptimeSince, pw); 9800 pw.print(" used "); 9801 TimeUtils.formatDuration(timeUsed, pw); 9802 pw.print(" ("); 9803 pw.print((timeUsed*100)/uptimeSince); 9804 pw.println("%)"); 9805 } 9806 } 9807 } 9808 } 9809 return true; 9810 } 9811 9812 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9813 ArrayList<ProcessRecord> procs; 9814 synchronized (this) { 9815 if (args != null && args.length > start 9816 && args[start].charAt(0) != '-') { 9817 procs = new ArrayList<ProcessRecord>(); 9818 int pid = -1; 9819 try { 9820 pid = Integer.parseInt(args[start]); 9821 } catch (NumberFormatException e) { 9822 9823 } 9824 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9825 ProcessRecord proc = mLruProcesses.get(i); 9826 if (proc.pid == pid) { 9827 procs.add(proc); 9828 } else if (proc.processName.equals(args[start])) { 9829 procs.add(proc); 9830 } 9831 } 9832 if (procs.size() <= 0) { 9833 pw.println("No process found for: " + args[start]); 9834 return null; 9835 } 9836 } else { 9837 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9838 } 9839 } 9840 return procs; 9841 } 9842 9843 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9844 PrintWriter pw, String[] args) { 9845 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9846 if (procs == null) { 9847 return; 9848 } 9849 9850 long uptime = SystemClock.uptimeMillis(); 9851 long realtime = SystemClock.elapsedRealtime(); 9852 pw.println("Applications Graphics Acceleration Info:"); 9853 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9854 9855 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9856 ProcessRecord r = procs.get(i); 9857 if (r.thread != null) { 9858 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9859 pw.flush(); 9860 try { 9861 TransferPipe tp = new TransferPipe(); 9862 try { 9863 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9864 tp.go(fd); 9865 } finally { 9866 tp.kill(); 9867 } 9868 } catch (IOException e) { 9869 pw.println("Failure while dumping the app: " + r); 9870 pw.flush(); 9871 } catch (RemoteException e) { 9872 pw.println("Got a RemoteException while dumping the app " + r); 9873 pw.flush(); 9874 } 9875 } 9876 } 9877 } 9878 9879 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9880 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9881 if (procs == null) { 9882 return; 9883 } 9884 9885 pw.println("Applications Database Info:"); 9886 9887 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9888 ProcessRecord r = procs.get(i); 9889 if (r.thread != null) { 9890 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9891 pw.flush(); 9892 try { 9893 TransferPipe tp = new TransferPipe(); 9894 try { 9895 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9896 tp.go(fd); 9897 } finally { 9898 tp.kill(); 9899 } 9900 } catch (IOException e) { 9901 pw.println("Failure while dumping the app: " + r); 9902 pw.flush(); 9903 } catch (RemoteException e) { 9904 pw.println("Got a RemoteException while dumping the app " + r); 9905 pw.flush(); 9906 } 9907 } 9908 } 9909 } 9910 9911 final static class MemItem { 9912 final String label; 9913 final String shortLabel; 9914 final long pss; 9915 final int id; 9916 ArrayList<MemItem> subitems; 9917 9918 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9919 label = _label; 9920 shortLabel = _shortLabel; 9921 pss = _pss; 9922 id = _id; 9923 } 9924 } 9925 9926 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9927 boolean sort) { 9928 if (sort) { 9929 Collections.sort(items, new Comparator<MemItem>() { 9930 @Override 9931 public int compare(MemItem lhs, MemItem rhs) { 9932 if (lhs.pss < rhs.pss) { 9933 return 1; 9934 } else if (lhs.pss > rhs.pss) { 9935 return -1; 9936 } 9937 return 0; 9938 } 9939 }); 9940 } 9941 9942 for (int i=0; i<items.size(); i++) { 9943 MemItem mi = items.get(i); 9944 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9945 if (mi.subitems != null) { 9946 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9947 } 9948 } 9949 } 9950 9951 // These are in KB. 9952 static final long[] DUMP_MEM_BUCKETS = new long[] { 9953 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9954 120*1024, 160*1024, 200*1024, 9955 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9956 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9957 }; 9958 9959 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9960 boolean stackLike) { 9961 int start = label.lastIndexOf('.'); 9962 if (start >= 0) start++; 9963 else start = 0; 9964 int end = label.length(); 9965 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9966 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9967 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9968 out.append(bucket); 9969 out.append(stackLike ? "MB." : "MB "); 9970 out.append(label, start, end); 9971 return; 9972 } 9973 } 9974 out.append(memKB/1024); 9975 out.append(stackLike ? "MB." : "MB "); 9976 out.append(label, start, end); 9977 } 9978 9979 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 9980 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 9981 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 9982 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 9983 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 9984 }; 9985 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 9986 "System", "Persistent", "Foreground", 9987 "Visible", "Perceptible", "Heavy Weight", 9988 "Backup", "A Services", "Home", "Previous", 9989 "B Services", "Background" 9990 }; 9991 9992 final void dumpApplicationMemoryUsage(FileDescriptor fd, 9993 PrintWriter pw, String prefix, String[] args, boolean brief, 9994 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 9995 boolean dumpAll = false; 9996 boolean oomOnly = false; 9997 9998 int opti = 0; 9999 while (opti < args.length) { 10000 String opt = args[opti]; 10001 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10002 break; 10003 } 10004 opti++; 10005 if ("-a".equals(opt)) { 10006 dumpAll = true; 10007 } else if ("--oom".equals(opt)) { 10008 oomOnly = true; 10009 } else if ("-h".equals(opt)) { 10010 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10011 pw.println(" -a: include all available information for each process."); 10012 pw.println(" --oom: only show processes organized by oom adj."); 10013 pw.println("If [process] is specified it can be the name or "); 10014 pw.println("pid of a specific process to dump."); 10015 return; 10016 } else { 10017 pw.println("Unknown argument: " + opt + "; use -h for help"); 10018 } 10019 } 10020 10021 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10022 if (procs == null) { 10023 return; 10024 } 10025 10026 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10027 long uptime = SystemClock.uptimeMillis(); 10028 long realtime = SystemClock.elapsedRealtime(); 10029 10030 if (procs.size() == 1 || isCheckinRequest) { 10031 dumpAll = true; 10032 } 10033 10034 if (isCheckinRequest) { 10035 // short checkin version 10036 pw.println(uptime + "," + realtime); 10037 pw.flush(); 10038 } else { 10039 pw.println("Applications Memory Usage (kB):"); 10040 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10041 } 10042 10043 String[] innerArgs = new String[args.length-opti]; 10044 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10045 10046 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10047 long nativePss=0, dalvikPss=0, otherPss=0; 10048 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10049 10050 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10051 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10052 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10053 10054 long totalPss = 0; 10055 10056 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10057 ProcessRecord r = procs.get(i); 10058 if (r.thread != null) { 10059 if (!isCheckinRequest && dumpAll) { 10060 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10061 pw.flush(); 10062 } 10063 Debug.MemoryInfo mi = null; 10064 if (dumpAll) { 10065 try { 10066 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10067 } catch (RemoteException e) { 10068 if (!isCheckinRequest) { 10069 pw.println("Got RemoteException!"); 10070 pw.flush(); 10071 } 10072 } 10073 } else { 10074 mi = new Debug.MemoryInfo(); 10075 Debug.getMemoryInfo(r.pid, mi); 10076 } 10077 10078 if (!isCheckinRequest && mi != null) { 10079 long myTotalPss = mi.getTotalPss(); 10080 totalPss += myTotalPss; 10081 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10082 r.processName, myTotalPss, 0); 10083 procMems.add(pssItem); 10084 10085 nativePss += mi.nativePss; 10086 dalvikPss += mi.dalvikPss; 10087 otherPss += mi.otherPss; 10088 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10089 long mem = mi.getOtherPss(j); 10090 miscPss[j] += mem; 10091 otherPss -= mem; 10092 } 10093 10094 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10095 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10096 || oomIndex == (oomPss.length-1)) { 10097 oomPss[oomIndex] += myTotalPss; 10098 if (oomProcs[oomIndex] == null) { 10099 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10100 } 10101 oomProcs[oomIndex].add(pssItem); 10102 break; 10103 } 10104 } 10105 } 10106 } 10107 } 10108 10109 if (!isCheckinRequest && procs.size() > 1) { 10110 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10111 10112 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10113 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10114 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10115 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10116 String label = Debug.MemoryInfo.getOtherLabel(j); 10117 catMems.add(new MemItem(label, label, miscPss[j], j)); 10118 } 10119 10120 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10121 for (int j=0; j<oomPss.length; j++) { 10122 if (oomPss[j] != 0) { 10123 String label = DUMP_MEM_OOM_LABEL[j]; 10124 MemItem item = new MemItem(label, label, oomPss[j], 10125 DUMP_MEM_OOM_ADJ[j]); 10126 item.subitems = oomProcs[j]; 10127 oomMems.add(item); 10128 } 10129 } 10130 10131 if (outTag != null || outStack != null) { 10132 if (outTag != null) { 10133 appendMemBucket(outTag, totalPss, "total", false); 10134 } 10135 if (outStack != null) { 10136 appendMemBucket(outStack, totalPss, "total", true); 10137 } 10138 boolean firstLine = true; 10139 for (int i=0; i<oomMems.size(); i++) { 10140 MemItem miCat = oomMems.get(i); 10141 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10142 continue; 10143 } 10144 if (miCat.id < ProcessList.SERVICE_ADJ 10145 || miCat.id == ProcessList.HOME_APP_ADJ 10146 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10147 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10148 outTag.append(" / "); 10149 } 10150 if (outStack != null) { 10151 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10152 if (firstLine) { 10153 outStack.append(":"); 10154 firstLine = false; 10155 } 10156 outStack.append("\n\t at "); 10157 } else { 10158 outStack.append("$"); 10159 } 10160 } 10161 for (int j=0; j<miCat.subitems.size(); j++) { 10162 MemItem mi = miCat.subitems.get(j); 10163 if (j > 0) { 10164 if (outTag != null) { 10165 outTag.append(" "); 10166 } 10167 if (outStack != null) { 10168 outStack.append("$"); 10169 } 10170 } 10171 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10172 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10173 } 10174 if (outStack != null) { 10175 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10176 } 10177 } 10178 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10179 outStack.append("("); 10180 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10181 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10182 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10183 outStack.append(":"); 10184 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10185 } 10186 } 10187 outStack.append(")"); 10188 } 10189 } 10190 } 10191 } 10192 10193 if (!brief && !oomOnly) { 10194 pw.println(); 10195 pw.println("Total PSS by process:"); 10196 dumpMemItems(pw, " ", procMems, true); 10197 pw.println(); 10198 } 10199 pw.println("Total PSS by OOM adjustment:"); 10200 dumpMemItems(pw, " ", oomMems, false); 10201 if (!oomOnly) { 10202 PrintWriter out = categoryPw != null ? categoryPw : pw; 10203 out.println(); 10204 out.println("Total PSS by category:"); 10205 dumpMemItems(out, " ", catMems, true); 10206 } 10207 pw.println(); 10208 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10209 final int[] SINGLE_LONG_FORMAT = new int[] { 10210 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10211 }; 10212 long[] longOut = new long[1]; 10213 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10214 SINGLE_LONG_FORMAT, null, longOut, null); 10215 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10216 longOut[0] = 0; 10217 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10218 SINGLE_LONG_FORMAT, null, longOut, null); 10219 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10220 longOut[0] = 0; 10221 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10222 SINGLE_LONG_FORMAT, null, longOut, null); 10223 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10224 longOut[0] = 0; 10225 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10226 SINGLE_LONG_FORMAT, null, longOut, null); 10227 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10228 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10229 pw.print(shared); pw.println(" kB"); 10230 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10231 pw.print(voltile); pw.println(" kB volatile"); 10232 } 10233 } 10234 10235 /** 10236 * Searches array of arguments for the specified string 10237 * @param args array of argument strings 10238 * @param value value to search for 10239 * @return true if the value is contained in the array 10240 */ 10241 private static boolean scanArgs(String[] args, String value) { 10242 if (args != null) { 10243 for (String arg : args) { 10244 if (value.equals(arg)) { 10245 return true; 10246 } 10247 } 10248 } 10249 return false; 10250 } 10251 10252 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10253 ContentProviderRecord cpr, boolean always) { 10254 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10255 10256 if (!inLaunching || always) { 10257 synchronized (cpr) { 10258 cpr.launchingApp = null; 10259 cpr.notifyAll(); 10260 } 10261 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10262 String names[] = cpr.info.authority.split(";"); 10263 for (int j = 0; j < names.length; j++) { 10264 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10265 } 10266 } 10267 10268 for (int i=0; i<cpr.connections.size(); i++) { 10269 ContentProviderConnection conn = cpr.connections.get(i); 10270 if (conn.waiting) { 10271 // If this connection is waiting for the provider, then we don't 10272 // need to mess with its process unless we are always removing 10273 // or for some reason the provider is not currently launching. 10274 if (inLaunching && !always) { 10275 continue; 10276 } 10277 } 10278 ProcessRecord capp = conn.client; 10279 conn.dead = true; 10280 if (conn.stableCount > 0) { 10281 if (!capp.persistent && capp.thread != null 10282 && capp.pid != 0 10283 && capp.pid != MY_PID) { 10284 Slog.i(TAG, "Kill " + capp.processName 10285 + " (pid " + capp.pid + "): provider " + cpr.info.name 10286 + " in dying process " + (proc != null ? proc.processName : "??")); 10287 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10288 capp.processName, capp.setAdj, "dying provider " 10289 + cpr.name.toShortString()); 10290 Process.killProcessQuiet(capp.pid); 10291 } 10292 } else if (capp.thread != null && conn.provider.provider != null) { 10293 try { 10294 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10295 } catch (RemoteException e) { 10296 } 10297 // In the protocol here, we don't expect the client to correctly 10298 // clean up this connection, we'll just remove it. 10299 cpr.connections.remove(i); 10300 conn.client.conProviders.remove(conn); 10301 } 10302 } 10303 10304 if (inLaunching && always) { 10305 mLaunchingProviders.remove(cpr); 10306 } 10307 return inLaunching; 10308 } 10309 10310 /** 10311 * Main code for cleaning up a process when it has gone away. This is 10312 * called both as a result of the process dying, or directly when stopping 10313 * a process when running in single process mode. 10314 */ 10315 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10316 boolean restarting, boolean allowRestart, int index) { 10317 if (index >= 0) { 10318 mLruProcesses.remove(index); 10319 } 10320 10321 mProcessesToGc.remove(app); 10322 10323 // Dismiss any open dialogs. 10324 if (app.crashDialog != null) { 10325 app.crashDialog.dismiss(); 10326 app.crashDialog = null; 10327 } 10328 if (app.anrDialog != null) { 10329 app.anrDialog.dismiss(); 10330 app.anrDialog = null; 10331 } 10332 if (app.waitDialog != null) { 10333 app.waitDialog.dismiss(); 10334 app.waitDialog = null; 10335 } 10336 10337 app.crashing = false; 10338 app.notResponding = false; 10339 10340 app.resetPackageList(); 10341 app.unlinkDeathRecipient(); 10342 app.thread = null; 10343 app.forcingToForeground = null; 10344 app.foregroundServices = false; 10345 app.foregroundActivities = false; 10346 app.hasShownUi = false; 10347 app.hasAboveClient = false; 10348 10349 mServices.killServicesLocked(app, allowRestart); 10350 10351 boolean restart = false; 10352 10353 // Remove published content providers. 10354 if (!app.pubProviders.isEmpty()) { 10355 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10356 while (it.hasNext()) { 10357 ContentProviderRecord cpr = it.next(); 10358 10359 final boolean always = app.bad || !allowRestart; 10360 if (removeDyingProviderLocked(app, cpr, always) || always) { 10361 // We left the provider in the launching list, need to 10362 // restart it. 10363 restart = true; 10364 } 10365 10366 cpr.provider = null; 10367 cpr.proc = null; 10368 } 10369 app.pubProviders.clear(); 10370 } 10371 10372 // Take care of any launching providers waiting for this process. 10373 if (checkAppInLaunchingProvidersLocked(app, false)) { 10374 restart = true; 10375 } 10376 10377 // Unregister from connected content providers. 10378 if (!app.conProviders.isEmpty()) { 10379 for (int i=0; i<app.conProviders.size(); i++) { 10380 ContentProviderConnection conn = app.conProviders.get(i); 10381 conn.provider.connections.remove(conn); 10382 } 10383 app.conProviders.clear(); 10384 } 10385 10386 // At this point there may be remaining entries in mLaunchingProviders 10387 // where we were the only one waiting, so they are no longer of use. 10388 // Look for these and clean up if found. 10389 // XXX Commented out for now. Trying to figure out a way to reproduce 10390 // the actual situation to identify what is actually going on. 10391 if (false) { 10392 for (int i=0; i<mLaunchingProviders.size(); i++) { 10393 ContentProviderRecord cpr = (ContentProviderRecord) 10394 mLaunchingProviders.get(i); 10395 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10396 synchronized (cpr) { 10397 cpr.launchingApp = null; 10398 cpr.notifyAll(); 10399 } 10400 } 10401 } 10402 } 10403 10404 skipCurrentReceiverLocked(app); 10405 10406 // Unregister any receivers. 10407 if (app.receivers.size() > 0) { 10408 Iterator<ReceiverList> it = app.receivers.iterator(); 10409 while (it.hasNext()) { 10410 removeReceiverLocked(it.next()); 10411 } 10412 app.receivers.clear(); 10413 } 10414 10415 // If the app is undergoing backup, tell the backup manager about it 10416 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10417 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10418 try { 10419 IBackupManager bm = IBackupManager.Stub.asInterface( 10420 ServiceManager.getService(Context.BACKUP_SERVICE)); 10421 bm.agentDisconnected(app.info.packageName); 10422 } catch (RemoteException e) { 10423 // can't happen; backup manager is local 10424 } 10425 } 10426 10427 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10428 ProcessChangeItem item = mPendingProcessChanges.get(i); 10429 if (item.pid == app.pid) { 10430 mPendingProcessChanges.remove(i); 10431 mAvailProcessChanges.add(item); 10432 } 10433 } 10434 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10435 10436 // If the caller is restarting this app, then leave it in its 10437 // current lists and let the caller take care of it. 10438 if (restarting) { 10439 return; 10440 } 10441 10442 if (!app.persistent || app.isolated) { 10443 if (DEBUG_PROCESSES) Slog.v(TAG, 10444 "Removing non-persistent process during cleanup: " + app); 10445 mProcessNames.remove(app.processName, app.uid); 10446 mIsolatedProcesses.remove(app.uid); 10447 if (mHeavyWeightProcess == app) { 10448 mHeavyWeightProcess = null; 10449 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10450 } 10451 } else if (!app.removed) { 10452 // This app is persistent, so we need to keep its record around. 10453 // If it is not already on the pending app list, add it there 10454 // and start a new process for it. 10455 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10456 mPersistentStartingProcesses.add(app); 10457 restart = true; 10458 } 10459 } 10460 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10461 "Clean-up removing on hold: " + app); 10462 mProcessesOnHold.remove(app); 10463 10464 if (app == mHomeProcess) { 10465 mHomeProcess = null; 10466 } 10467 if (app == mPreviousProcess) { 10468 mPreviousProcess = null; 10469 } 10470 10471 if (restart && !app.isolated) { 10472 // We have components that still need to be running in the 10473 // process, so re-launch it. 10474 mProcessNames.put(app.processName, app.uid, app); 10475 startProcessLocked(app, "restart", app.processName); 10476 } else if (app.pid > 0 && app.pid != MY_PID) { 10477 // Goodbye! 10478 synchronized (mPidsSelfLocked) { 10479 mPidsSelfLocked.remove(app.pid); 10480 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10481 } 10482 app.setPid(0); 10483 } 10484 } 10485 10486 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10487 // Look through the content providers we are waiting to have launched, 10488 // and if any run in this process then either schedule a restart of 10489 // the process or kill the client waiting for it if this process has 10490 // gone bad. 10491 int NL = mLaunchingProviders.size(); 10492 boolean restart = false; 10493 for (int i=0; i<NL; i++) { 10494 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10495 if (cpr.launchingApp == app) { 10496 if (!alwaysBad && !app.bad) { 10497 restart = true; 10498 } else { 10499 removeDyingProviderLocked(app, cpr, true); 10500 NL = mLaunchingProviders.size(); 10501 } 10502 } 10503 } 10504 return restart; 10505 } 10506 10507 // ========================================================= 10508 // SERVICES 10509 // ========================================================= 10510 10511 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10512 int flags) { 10513 enforceNotIsolatedCaller("getServices"); 10514 synchronized (this) { 10515 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10516 } 10517 } 10518 10519 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10520 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10521 synchronized (this) { 10522 return mServices.getRunningServiceControlPanelLocked(name); 10523 } 10524 } 10525 10526 public ComponentName startService(IApplicationThread caller, Intent service, 10527 String resolvedType) { 10528 enforceNotIsolatedCaller("startService"); 10529 // Refuse possible leaked file descriptors 10530 if (service != null && service.hasFileDescriptors() == true) { 10531 throw new IllegalArgumentException("File descriptors passed in Intent"); 10532 } 10533 10534 if (DEBUG_SERVICE) 10535 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10536 synchronized(this) { 10537 final int callingPid = Binder.getCallingPid(); 10538 final int callingUid = Binder.getCallingUid(); 10539 final long origId = Binder.clearCallingIdentity(); 10540 ComponentName res = mServices.startServiceLocked(caller, service, 10541 resolvedType, callingPid, callingUid); 10542 Binder.restoreCallingIdentity(origId); 10543 return res; 10544 } 10545 } 10546 10547 ComponentName startServiceInPackage(int uid, 10548 Intent service, String resolvedType) { 10549 synchronized(this) { 10550 if (DEBUG_SERVICE) 10551 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10552 final long origId = Binder.clearCallingIdentity(); 10553 ComponentName res = mServices.startServiceLocked(null, service, 10554 resolvedType, -1, uid); 10555 Binder.restoreCallingIdentity(origId); 10556 return res; 10557 } 10558 } 10559 10560 public int stopService(IApplicationThread caller, Intent service, 10561 String resolvedType) { 10562 enforceNotIsolatedCaller("stopService"); 10563 // Refuse possible leaked file descriptors 10564 if (service != null && service.hasFileDescriptors() == true) { 10565 throw new IllegalArgumentException("File descriptors passed in Intent"); 10566 } 10567 10568 synchronized(this) { 10569 return mServices.stopServiceLocked(caller, service, resolvedType); 10570 } 10571 } 10572 10573 public IBinder peekService(Intent service, String resolvedType) { 10574 enforceNotIsolatedCaller("peekService"); 10575 // Refuse possible leaked file descriptors 10576 if (service != null && service.hasFileDescriptors() == true) { 10577 throw new IllegalArgumentException("File descriptors passed in Intent"); 10578 } 10579 synchronized(this) { 10580 return mServices.peekServiceLocked(service, resolvedType); 10581 } 10582 } 10583 10584 public boolean stopServiceToken(ComponentName className, IBinder token, 10585 int startId) { 10586 synchronized(this) { 10587 return mServices.stopServiceTokenLocked(className, token, startId); 10588 } 10589 } 10590 10591 public void setServiceForeground(ComponentName className, IBinder token, 10592 int id, Notification notification, boolean removeNotification) { 10593 synchronized(this) { 10594 mServices.setServiceForegroundLocked(className, token, id, notification, 10595 removeNotification); 10596 } 10597 } 10598 10599 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10600 String className, int flags) { 10601 boolean result = false; 10602 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10603 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10604 if (ActivityManager.checkUidPermission( 10605 android.Manifest.permission.INTERACT_ACROSS_USERS, 10606 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10607 ComponentName comp = new ComponentName(aInfo.packageName, className); 10608 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10609 + " requests FLAG_SINGLE_USER, but app does not hold " 10610 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10611 Slog.w(TAG, msg); 10612 throw new SecurityException(msg); 10613 } 10614 result = true; 10615 } 10616 } else if (componentProcessName == aInfo.packageName) { 10617 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10618 } else if ("system".equals(componentProcessName)) { 10619 result = true; 10620 } 10621 if (DEBUG_MU) { 10622 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10623 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10624 } 10625 return result; 10626 } 10627 10628 public int bindService(IApplicationThread caller, IBinder token, 10629 Intent service, String resolvedType, 10630 IServiceConnection connection, int flags, int userId) { 10631 enforceNotIsolatedCaller("bindService"); 10632 // Refuse possible leaked file descriptors 10633 if (service != null && service.hasFileDescriptors() == true) { 10634 throw new IllegalArgumentException("File descriptors passed in Intent"); 10635 } 10636 10637 checkValidCaller(Binder.getCallingUid(), userId); 10638 10639 synchronized(this) { 10640 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10641 connection, flags, userId); 10642 } 10643 } 10644 10645 public boolean unbindService(IServiceConnection connection) { 10646 synchronized (this) { 10647 return mServices.unbindServiceLocked(connection); 10648 } 10649 } 10650 10651 public void publishService(IBinder token, Intent intent, IBinder service) { 10652 // Refuse possible leaked file descriptors 10653 if (intent != null && intent.hasFileDescriptors() == true) { 10654 throw new IllegalArgumentException("File descriptors passed in Intent"); 10655 } 10656 10657 synchronized(this) { 10658 if (!(token instanceof ServiceRecord)) { 10659 throw new IllegalArgumentException("Invalid service token"); 10660 } 10661 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10662 } 10663 } 10664 10665 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10666 // Refuse possible leaked file descriptors 10667 if (intent != null && intent.hasFileDescriptors() == true) { 10668 throw new IllegalArgumentException("File descriptors passed in Intent"); 10669 } 10670 10671 synchronized(this) { 10672 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10673 } 10674 } 10675 10676 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10677 synchronized(this) { 10678 if (!(token instanceof ServiceRecord)) { 10679 throw new IllegalArgumentException("Invalid service token"); 10680 } 10681 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10682 } 10683 } 10684 10685 // ========================================================= 10686 // BACKUP AND RESTORE 10687 // ========================================================= 10688 10689 // Cause the target app to be launched if necessary and its backup agent 10690 // instantiated. The backup agent will invoke backupAgentCreated() on the 10691 // activity manager to announce its creation. 10692 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10693 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10694 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10695 10696 synchronized(this) { 10697 // !!! TODO: currently no check here that we're already bound 10698 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10699 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10700 synchronized (stats) { 10701 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10702 } 10703 10704 // Backup agent is now in use, its package can't be stopped. 10705 try { 10706 AppGlobals.getPackageManager().setPackageStoppedState( 10707 app.packageName, false, UserHandle.getUserId(app.uid)); 10708 } catch (RemoteException e) { 10709 } catch (IllegalArgumentException e) { 10710 Slog.w(TAG, "Failed trying to unstop package " 10711 + app.packageName + ": " + e); 10712 } 10713 10714 BackupRecord r = new BackupRecord(ss, app, backupMode); 10715 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10716 ? new ComponentName(app.packageName, app.backupAgentName) 10717 : new ComponentName("android", "FullBackupAgent"); 10718 // startProcessLocked() returns existing proc's record if it's already running 10719 ProcessRecord proc = startProcessLocked(app.processName, app, 10720 false, 0, "backup", hostingName, false, false); 10721 if (proc == null) { 10722 Slog.e(TAG, "Unable to start backup agent process " + r); 10723 return false; 10724 } 10725 10726 r.app = proc; 10727 mBackupTarget = r; 10728 mBackupAppName = app.packageName; 10729 10730 // Try not to kill the process during backup 10731 updateOomAdjLocked(proc); 10732 10733 // If the process is already attached, schedule the creation of the backup agent now. 10734 // If it is not yet live, this will be done when it attaches to the framework. 10735 if (proc.thread != null) { 10736 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10737 try { 10738 proc.thread.scheduleCreateBackupAgent(app, 10739 compatibilityInfoForPackageLocked(app), backupMode); 10740 } catch (RemoteException e) { 10741 // Will time out on the backup manager side 10742 } 10743 } else { 10744 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10745 } 10746 // Invariants: at this point, the target app process exists and the application 10747 // is either already running or in the process of coming up. mBackupTarget and 10748 // mBackupAppName describe the app, so that when it binds back to the AM we 10749 // know that it's scheduled for a backup-agent operation. 10750 } 10751 10752 return true; 10753 } 10754 10755 // A backup agent has just come up 10756 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10757 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10758 + " = " + agent); 10759 10760 synchronized(this) { 10761 if (!agentPackageName.equals(mBackupAppName)) { 10762 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10763 return; 10764 } 10765 } 10766 10767 long oldIdent = Binder.clearCallingIdentity(); 10768 try { 10769 IBackupManager bm = IBackupManager.Stub.asInterface( 10770 ServiceManager.getService(Context.BACKUP_SERVICE)); 10771 bm.agentConnected(agentPackageName, agent); 10772 } catch (RemoteException e) { 10773 // can't happen; the backup manager service is local 10774 } catch (Exception e) { 10775 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10776 e.printStackTrace(); 10777 } finally { 10778 Binder.restoreCallingIdentity(oldIdent); 10779 } 10780 } 10781 10782 // done with this agent 10783 public void unbindBackupAgent(ApplicationInfo appInfo) { 10784 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10785 if (appInfo == null) { 10786 Slog.w(TAG, "unbind backup agent for null app"); 10787 return; 10788 } 10789 10790 synchronized(this) { 10791 if (mBackupAppName == null) { 10792 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10793 return; 10794 } 10795 10796 if (!mBackupAppName.equals(appInfo.packageName)) { 10797 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10798 return; 10799 } 10800 10801 ProcessRecord proc = mBackupTarget.app; 10802 mBackupTarget = null; 10803 mBackupAppName = null; 10804 10805 // Not backing this app up any more; reset its OOM adjustment 10806 updateOomAdjLocked(proc); 10807 10808 // If the app crashed during backup, 'thread' will be null here 10809 if (proc.thread != null) { 10810 try { 10811 proc.thread.scheduleDestroyBackupAgent(appInfo, 10812 compatibilityInfoForPackageLocked(appInfo)); 10813 } catch (Exception e) { 10814 Slog.e(TAG, "Exception when unbinding backup agent:"); 10815 e.printStackTrace(); 10816 } 10817 } 10818 } 10819 } 10820 // ========================================================= 10821 // BROADCASTS 10822 // ========================================================= 10823 10824 private final List getStickiesLocked(String action, IntentFilter filter, 10825 List cur) { 10826 final ContentResolver resolver = mContext.getContentResolver(); 10827 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10828 if (list == null) { 10829 return cur; 10830 } 10831 int N = list.size(); 10832 for (int i=0; i<N; i++) { 10833 Intent intent = list.get(i); 10834 if (filter.match(resolver, intent, true, TAG) >= 0) { 10835 if (cur == null) { 10836 cur = new ArrayList<Intent>(); 10837 } 10838 cur.add(intent); 10839 } 10840 } 10841 return cur; 10842 } 10843 10844 boolean isPendingBroadcastProcessLocked(int pid) { 10845 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10846 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10847 } 10848 10849 void skipPendingBroadcastLocked(int pid) { 10850 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10851 for (BroadcastQueue queue : mBroadcastQueues) { 10852 queue.skipPendingBroadcastLocked(pid); 10853 } 10854 } 10855 10856 // The app just attached; send any pending broadcasts that it should receive 10857 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10858 boolean didSomething = false; 10859 for (BroadcastQueue queue : mBroadcastQueues) { 10860 didSomething |= queue.sendPendingBroadcastsLocked(app); 10861 } 10862 return didSomething; 10863 } 10864 10865 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10866 IIntentReceiver receiver, IntentFilter filter, String permission) { 10867 enforceNotIsolatedCaller("registerReceiver"); 10868 int callingUid; 10869 synchronized(this) { 10870 ProcessRecord callerApp = null; 10871 if (caller != null) { 10872 callerApp = getRecordForAppLocked(caller); 10873 if (callerApp == null) { 10874 throw new SecurityException( 10875 "Unable to find app for caller " + caller 10876 + " (pid=" + Binder.getCallingPid() 10877 + ") when registering receiver " + receiver); 10878 } 10879 if (callerApp.info.uid != Process.SYSTEM_UID && 10880 !callerApp.pkgList.contains(callerPackage)) { 10881 throw new SecurityException("Given caller package " + callerPackage 10882 + " is not running in process " + callerApp); 10883 } 10884 callingUid = callerApp.info.uid; 10885 } else { 10886 callerPackage = null; 10887 callingUid = Binder.getCallingUid(); 10888 } 10889 10890 List allSticky = null; 10891 10892 // Look for any matching sticky broadcasts... 10893 Iterator actions = filter.actionsIterator(); 10894 if (actions != null) { 10895 while (actions.hasNext()) { 10896 String action = (String)actions.next(); 10897 allSticky = getStickiesLocked(action, filter, allSticky); 10898 } 10899 } else { 10900 allSticky = getStickiesLocked(null, filter, allSticky); 10901 } 10902 10903 // The first sticky in the list is returned directly back to 10904 // the client. 10905 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10906 10907 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10908 + ": " + sticky); 10909 10910 if (receiver == null) { 10911 return sticky; 10912 } 10913 10914 ReceiverList rl 10915 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10916 if (rl == null) { 10917 rl = new ReceiverList(this, callerApp, 10918 Binder.getCallingPid(), 10919 Binder.getCallingUid(), receiver); 10920 if (rl.app != null) { 10921 rl.app.receivers.add(rl); 10922 } else { 10923 try { 10924 receiver.asBinder().linkToDeath(rl, 0); 10925 } catch (RemoteException e) { 10926 return sticky; 10927 } 10928 rl.linkedToDeath = true; 10929 } 10930 mRegisteredReceivers.put(receiver.asBinder(), rl); 10931 } 10932 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10933 permission, callingUid); 10934 rl.add(bf); 10935 if (!bf.debugCheck()) { 10936 Slog.w(TAG, "==> For Dynamic broadast"); 10937 } 10938 mReceiverResolver.addFilter(bf); 10939 10940 // Enqueue broadcasts for all existing stickies that match 10941 // this filter. 10942 if (allSticky != null) { 10943 ArrayList receivers = new ArrayList(); 10944 receivers.add(bf); 10945 10946 int N = allSticky.size(); 10947 for (int i=0; i<N; i++) { 10948 Intent intent = (Intent)allSticky.get(i); 10949 BroadcastQueue queue = broadcastQueueForIntent(intent); 10950 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10951 null, -1, -1, null, receivers, null, 0, null, null, 10952 false, true, true, false); 10953 queue.enqueueParallelBroadcastLocked(r); 10954 queue.scheduleBroadcastsLocked(); 10955 } 10956 } 10957 10958 return sticky; 10959 } 10960 } 10961 10962 public void unregisterReceiver(IIntentReceiver receiver) { 10963 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10964 10965 final long origId = Binder.clearCallingIdentity(); 10966 try { 10967 boolean doTrim = false; 10968 10969 synchronized(this) { 10970 ReceiverList rl 10971 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10972 if (rl != null) { 10973 if (rl.curBroadcast != null) { 10974 BroadcastRecord r = rl.curBroadcast; 10975 final boolean doNext = finishReceiverLocked( 10976 receiver.asBinder(), r.resultCode, r.resultData, 10977 r.resultExtras, r.resultAbort, true); 10978 if (doNext) { 10979 doTrim = true; 10980 r.queue.processNextBroadcast(false); 10981 } 10982 } 10983 10984 if (rl.app != null) { 10985 rl.app.receivers.remove(rl); 10986 } 10987 removeReceiverLocked(rl); 10988 if (rl.linkedToDeath) { 10989 rl.linkedToDeath = false; 10990 rl.receiver.asBinder().unlinkToDeath(rl, 0); 10991 } 10992 } 10993 } 10994 10995 // If we actually concluded any broadcasts, we might now be able 10996 // to trim the recipients' apps from our working set 10997 if (doTrim) { 10998 trimApplications(); 10999 return; 11000 } 11001 11002 } finally { 11003 Binder.restoreCallingIdentity(origId); 11004 } 11005 } 11006 11007 void removeReceiverLocked(ReceiverList rl) { 11008 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11009 int N = rl.size(); 11010 for (int i=0; i<N; i++) { 11011 mReceiverResolver.removeFilter(rl.get(i)); 11012 } 11013 } 11014 11015 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11016 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11017 ProcessRecord r = mLruProcesses.get(i); 11018 if (r.thread != null) { 11019 try { 11020 r.thread.dispatchPackageBroadcast(cmd, packages); 11021 } catch (RemoteException ex) { 11022 } 11023 } 11024 } 11025 } 11026 11027 private final int broadcastIntentLocked(ProcessRecord callerApp, 11028 String callerPackage, Intent intent, String resolvedType, 11029 IIntentReceiver resultTo, int resultCode, String resultData, 11030 Bundle map, String requiredPermission, 11031 boolean ordered, boolean sticky, int callingPid, int callingUid, 11032 int userId) { 11033 intent = new Intent(intent); 11034 11035 // By default broadcasts do not go to stopped apps. 11036 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11037 11038 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11039 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11040 + " ordered=" + ordered + " userid=" + userId); 11041 if ((resultTo != null) && !ordered) { 11042 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11043 } 11044 11045 boolean onlySendToCaller = false; 11046 11047 // If the caller is trying to send this broadcast to a different 11048 // user, verify that is allowed. 11049 if (UserHandle.getUserId(callingUid) != userId) { 11050 if (checkComponentPermission( 11051 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11052 callingPid, callingUid, -1, true) 11053 != PackageManager.PERMISSION_GRANTED) { 11054 if (checkComponentPermission( 11055 android.Manifest.permission.INTERACT_ACROSS_USERS, 11056 callingPid, callingUid, -1, true) 11057 == PackageManager.PERMISSION_GRANTED) { 11058 onlySendToCaller = true; 11059 } else { 11060 String msg = "Permission Denial: " + intent.getAction() 11061 + " broadcast from " + callerPackage 11062 + " asks to send as user " + userId 11063 + " but is calling from user " + UserHandle.getUserId(callingUid) 11064 + "; this requires " 11065 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11066 Slog.w(TAG, msg); 11067 throw new SecurityException(msg); 11068 } 11069 } 11070 } 11071 11072 // Handle special intents: if this broadcast is from the package 11073 // manager about a package being removed, we need to remove all of 11074 // its activities from the history stack. 11075 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11076 intent.getAction()); 11077 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11078 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11079 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11080 || uidRemoved) { 11081 if (checkComponentPermission( 11082 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11083 callingPid, callingUid, -1, true) 11084 == PackageManager.PERMISSION_GRANTED) { 11085 if (uidRemoved) { 11086 final Bundle intentExtras = intent.getExtras(); 11087 final int uid = intentExtras != null 11088 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11089 if (uid >= 0) { 11090 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11091 synchronized (bs) { 11092 bs.removeUidStatsLocked(uid); 11093 } 11094 } 11095 } else { 11096 // If resources are unvailble just force stop all 11097 // those packages and flush the attribute cache as well. 11098 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11099 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11100 if (list != null && (list.length > 0)) { 11101 for (String pkg : list) { 11102 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11103 } 11104 sendPackageBroadcastLocked( 11105 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11106 } 11107 } else { 11108 Uri data = intent.getData(); 11109 String ssp; 11110 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11111 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11112 forceStopPackageLocked(ssp, 11113 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11114 false, userId); 11115 } 11116 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11117 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11118 new String[] {ssp}); 11119 } 11120 } 11121 } 11122 } 11123 } else { 11124 String msg = "Permission Denial: " + intent.getAction() 11125 + " broadcast from " + callerPackage + " (pid=" + callingPid 11126 + ", uid=" + callingUid + ")" 11127 + " requires " 11128 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11129 Slog.w(TAG, msg); 11130 throw new SecurityException(msg); 11131 } 11132 11133 // Special case for adding a package: by default turn on compatibility 11134 // mode. 11135 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11136 Uri data = intent.getData(); 11137 String ssp; 11138 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11139 mCompatModePackages.handlePackageAddedLocked(ssp, 11140 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11141 } 11142 } 11143 11144 /* 11145 * If this is the time zone changed action, queue up a message that will reset the timezone 11146 * of all currently running processes. This message will get queued up before the broadcast 11147 * happens. 11148 */ 11149 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11150 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11151 } 11152 11153 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11154 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11155 } 11156 11157 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11158 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11159 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11160 } 11161 11162 /* 11163 * Prevent non-system code (defined here to be non-persistent 11164 * processes) from sending protected broadcasts. 11165 */ 11166 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11167 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11168 callingUid == 0) { 11169 // Always okay. 11170 } else if (callerApp == null || !callerApp.persistent) { 11171 try { 11172 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11173 intent.getAction())) { 11174 String msg = "Permission Denial: not allowed to send broadcast " 11175 + intent.getAction() + " from pid=" 11176 + callingPid + ", uid=" + callingUid; 11177 Slog.w(TAG, msg); 11178 throw new SecurityException(msg); 11179 } 11180 } catch (RemoteException e) { 11181 Slog.w(TAG, "Remote exception", e); 11182 return ActivityManager.BROADCAST_SUCCESS; 11183 } 11184 } 11185 11186 // Add to the sticky list if requested. 11187 if (sticky) { 11188 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11189 callingPid, callingUid) 11190 != PackageManager.PERMISSION_GRANTED) { 11191 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11192 + callingPid + ", uid=" + callingUid 11193 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11194 Slog.w(TAG, msg); 11195 throw new SecurityException(msg); 11196 } 11197 if (requiredPermission != null) { 11198 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11199 + " and enforce permission " + requiredPermission); 11200 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11201 } 11202 if (intent.getComponent() != null) { 11203 throw new SecurityException( 11204 "Sticky broadcasts can't target a specific component"); 11205 } 11206 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11207 if (list == null) { 11208 list = new ArrayList<Intent>(); 11209 mStickyBroadcasts.put(intent.getAction(), list); 11210 } 11211 int N = list.size(); 11212 int i; 11213 for (i=0; i<N; i++) { 11214 if (intent.filterEquals(list.get(i))) { 11215 // This sticky already exists, replace it. 11216 list.set(i, new Intent(intent)); 11217 break; 11218 } 11219 } 11220 if (i >= N) { 11221 list.add(new Intent(intent)); 11222 } 11223 } 11224 11225 // Figure out who all will receive this broadcast. 11226 List receivers = null; 11227 List<BroadcastFilter> registeredReceivers = null; 11228 try { 11229 // Need to resolve the intent to interested receivers... 11230 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11231 == 0) { 11232 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11233 intent, resolvedType, STOCK_PM_FLAGS, userId); 11234 } 11235 if (intent.getComponent() == null) { 11236 registeredReceivers = mReceiverResolver.queryIntent(intent, 11237 resolvedType, false, userId); 11238 } 11239 } catch (RemoteException ex) { 11240 // pm is in same process, this will never happen. 11241 } 11242 11243 final boolean replacePending = 11244 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11245 11246 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11247 + " replacePending=" + replacePending); 11248 11249 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11250 if (!ordered && NR > 0) { 11251 // If we are not serializing this broadcast, then send the 11252 // registered receivers separately so they don't wait for the 11253 // components to be launched. 11254 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11255 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11256 callerPackage, callingPid, callingUid, requiredPermission, 11257 registeredReceivers, resultTo, resultCode, resultData, map, 11258 ordered, sticky, false, onlySendToCaller); 11259 if (DEBUG_BROADCAST) Slog.v( 11260 TAG, "Enqueueing parallel broadcast " + r); 11261 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11262 if (!replaced) { 11263 queue.enqueueParallelBroadcastLocked(r); 11264 queue.scheduleBroadcastsLocked(); 11265 } 11266 registeredReceivers = null; 11267 NR = 0; 11268 } 11269 11270 // Merge into one list. 11271 int ir = 0; 11272 if (receivers != null) { 11273 // A special case for PACKAGE_ADDED: do not allow the package 11274 // being added to see this broadcast. This prevents them from 11275 // using this as a back door to get run as soon as they are 11276 // installed. Maybe in the future we want to have a special install 11277 // broadcast or such for apps, but we'd like to deliberately make 11278 // this decision. 11279 String skipPackages[] = null; 11280 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11281 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11282 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11283 Uri data = intent.getData(); 11284 if (data != null) { 11285 String pkgName = data.getSchemeSpecificPart(); 11286 if (pkgName != null) { 11287 skipPackages = new String[] { pkgName }; 11288 } 11289 } 11290 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11291 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11292 } 11293 if (skipPackages != null && (skipPackages.length > 0)) { 11294 for (String skipPackage : skipPackages) { 11295 if (skipPackage != null) { 11296 int NT = receivers.size(); 11297 for (int it=0; it<NT; it++) { 11298 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11299 if (curt.activityInfo.packageName.equals(skipPackage)) { 11300 receivers.remove(it); 11301 it--; 11302 NT--; 11303 } 11304 } 11305 } 11306 } 11307 } 11308 11309 int NT = receivers != null ? receivers.size() : 0; 11310 int it = 0; 11311 ResolveInfo curt = null; 11312 BroadcastFilter curr = null; 11313 while (it < NT && ir < NR) { 11314 if (curt == null) { 11315 curt = (ResolveInfo)receivers.get(it); 11316 } 11317 if (curr == null) { 11318 curr = registeredReceivers.get(ir); 11319 } 11320 if (curr.getPriority() >= curt.priority) { 11321 // Insert this broadcast record into the final list. 11322 receivers.add(it, curr); 11323 ir++; 11324 curr = null; 11325 it++; 11326 NT++; 11327 } else { 11328 // Skip to the next ResolveInfo in the final list. 11329 it++; 11330 curt = null; 11331 } 11332 } 11333 } 11334 while (ir < NR) { 11335 if (receivers == null) { 11336 receivers = new ArrayList(); 11337 } 11338 receivers.add(registeredReceivers.get(ir)); 11339 ir++; 11340 } 11341 11342 if ((receivers != null && receivers.size() > 0) 11343 || resultTo != null) { 11344 BroadcastQueue queue = broadcastQueueForIntent(intent); 11345 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11346 callerPackage, callingPid, callingUid, requiredPermission, 11347 receivers, resultTo, resultCode, resultData, map, ordered, 11348 sticky, false, onlySendToCaller); 11349 if (DEBUG_BROADCAST) Slog.v( 11350 TAG, "Enqueueing ordered broadcast " + r 11351 + ": prev had " + queue.mOrderedBroadcasts.size()); 11352 if (DEBUG_BROADCAST) { 11353 int seq = r.intent.getIntExtra("seq", -1); 11354 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11355 } 11356 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11357 if (!replaced) { 11358 queue.enqueueOrderedBroadcastLocked(r); 11359 queue.scheduleBroadcastsLocked(); 11360 } 11361 } 11362 11363 return ActivityManager.BROADCAST_SUCCESS; 11364 } 11365 11366 final Intent verifyBroadcastLocked(Intent intent) { 11367 // Refuse possible leaked file descriptors 11368 if (intent != null && intent.hasFileDescriptors() == true) { 11369 throw new IllegalArgumentException("File descriptors passed in Intent"); 11370 } 11371 11372 int flags = intent.getFlags(); 11373 11374 if (!mProcessesReady) { 11375 // if the caller really truly claims to know what they're doing, go 11376 // ahead and allow the broadcast without launching any receivers 11377 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11378 intent = new Intent(intent); 11379 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11380 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11381 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11382 + " before boot completion"); 11383 throw new IllegalStateException("Cannot broadcast before boot completed"); 11384 } 11385 } 11386 11387 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11388 throw new IllegalArgumentException( 11389 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11390 } 11391 11392 return intent; 11393 } 11394 11395 public final int broadcastIntent(IApplicationThread caller, 11396 Intent intent, String resolvedType, IIntentReceiver resultTo, 11397 int resultCode, String resultData, Bundle map, 11398 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11399 enforceNotIsolatedCaller("broadcastIntent"); 11400 synchronized(this) { 11401 intent = verifyBroadcastLocked(intent); 11402 11403 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11404 final int callingPid = Binder.getCallingPid(); 11405 final int callingUid = Binder.getCallingUid(); 11406 final long origId = Binder.clearCallingIdentity(); 11407 int res = broadcastIntentLocked(callerApp, 11408 callerApp != null ? callerApp.info.packageName : null, 11409 intent, resolvedType, resultTo, 11410 resultCode, resultData, map, requiredPermission, serialized, sticky, 11411 callingPid, callingUid, userId); 11412 Binder.restoreCallingIdentity(origId); 11413 return res; 11414 } 11415 } 11416 11417 int broadcastIntentInPackage(String packageName, int uid, 11418 Intent intent, String resolvedType, IIntentReceiver resultTo, 11419 int resultCode, String resultData, Bundle map, 11420 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11421 synchronized(this) { 11422 intent = verifyBroadcastLocked(intent); 11423 11424 final long origId = Binder.clearCallingIdentity(); 11425 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11426 resultTo, resultCode, resultData, map, requiredPermission, 11427 serialized, sticky, -1, uid, userId); 11428 Binder.restoreCallingIdentity(origId); 11429 return res; 11430 } 11431 } 11432 11433 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11434 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11435 // Refuse possible leaked file descriptors 11436 if (intent != null && intent.hasFileDescriptors() == true) { 11437 throw new IllegalArgumentException("File descriptors passed in Intent"); 11438 } 11439 11440 synchronized(this) { 11441 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11442 != PackageManager.PERMISSION_GRANTED) { 11443 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11444 + Binder.getCallingPid() 11445 + ", uid=" + Binder.getCallingUid() 11446 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11447 Slog.w(TAG, msg); 11448 throw new SecurityException(msg); 11449 } 11450 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11451 if (list != null) { 11452 int N = list.size(); 11453 int i; 11454 for (i=0; i<N; i++) { 11455 if (intent.filterEquals(list.get(i))) { 11456 list.remove(i); 11457 break; 11458 } 11459 } 11460 } 11461 } 11462 } 11463 11464 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11465 String resultData, Bundle resultExtras, boolean resultAbort, 11466 boolean explicit) { 11467 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11468 if (r == null) { 11469 Slog.w(TAG, "finishReceiver called but not found on queue"); 11470 return false; 11471 } 11472 11473 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11474 explicit); 11475 } 11476 11477 public void finishReceiver(IBinder who, int resultCode, String resultData, 11478 Bundle resultExtras, boolean resultAbort) { 11479 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11480 11481 // Refuse possible leaked file descriptors 11482 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11483 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11484 } 11485 11486 final long origId = Binder.clearCallingIdentity(); 11487 try { 11488 boolean doNext = false; 11489 BroadcastRecord r = null; 11490 11491 synchronized(this) { 11492 r = broadcastRecordForReceiverLocked(who); 11493 if (r != null) { 11494 doNext = r.queue.finishReceiverLocked(r, resultCode, 11495 resultData, resultExtras, resultAbort, true); 11496 } 11497 } 11498 11499 if (doNext) { 11500 r.queue.processNextBroadcast(false); 11501 } 11502 trimApplications(); 11503 } finally { 11504 Binder.restoreCallingIdentity(origId); 11505 } 11506 } 11507 11508 // ========================================================= 11509 // INSTRUMENTATION 11510 // ========================================================= 11511 11512 public boolean startInstrumentation(ComponentName className, 11513 String profileFile, int flags, Bundle arguments, 11514 IInstrumentationWatcher watcher) { 11515 enforceNotIsolatedCaller("startInstrumentation"); 11516 // Refuse possible leaked file descriptors 11517 if (arguments != null && arguments.hasFileDescriptors()) { 11518 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11519 } 11520 11521 synchronized(this) { 11522 InstrumentationInfo ii = null; 11523 ApplicationInfo ai = null; 11524 try { 11525 ii = mContext.getPackageManager().getInstrumentationInfo( 11526 className, STOCK_PM_FLAGS); 11527 ai = mContext.getPackageManager().getApplicationInfo( 11528 ii.targetPackage, STOCK_PM_FLAGS); 11529 } catch (PackageManager.NameNotFoundException e) { 11530 } 11531 if (ii == null) { 11532 reportStartInstrumentationFailure(watcher, className, 11533 "Unable to find instrumentation info for: " + className); 11534 return false; 11535 } 11536 if (ai == null) { 11537 reportStartInstrumentationFailure(watcher, className, 11538 "Unable to find instrumentation target package: " + ii.targetPackage); 11539 return false; 11540 } 11541 11542 int match = mContext.getPackageManager().checkSignatures( 11543 ii.targetPackage, ii.packageName); 11544 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11545 String msg = "Permission Denial: starting instrumentation " 11546 + className + " from pid=" 11547 + Binder.getCallingPid() 11548 + ", uid=" + Binder.getCallingPid() 11549 + " not allowed because package " + ii.packageName 11550 + " does not have a signature matching the target " 11551 + ii.targetPackage; 11552 reportStartInstrumentationFailure(watcher, className, msg); 11553 throw new SecurityException(msg); 11554 } 11555 11556 int userId = UserHandle.getCallingUserId(); 11557 final long origId = Binder.clearCallingIdentity(); 11558 // Instrumentation can kill and relaunch even persistent processes 11559 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11560 ProcessRecord app = addAppLocked(ai, false); 11561 app.instrumentationClass = className; 11562 app.instrumentationInfo = ai; 11563 app.instrumentationProfileFile = profileFile; 11564 app.instrumentationArguments = arguments; 11565 app.instrumentationWatcher = watcher; 11566 app.instrumentationResultClass = className; 11567 Binder.restoreCallingIdentity(origId); 11568 } 11569 11570 return true; 11571 } 11572 11573 /** 11574 * Report errors that occur while attempting to start Instrumentation. Always writes the 11575 * error to the logs, but if somebody is watching, send the report there too. This enables 11576 * the "am" command to report errors with more information. 11577 * 11578 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11579 * @param cn The component name of the instrumentation. 11580 * @param report The error report. 11581 */ 11582 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11583 ComponentName cn, String report) { 11584 Slog.w(TAG, report); 11585 try { 11586 if (watcher != null) { 11587 Bundle results = new Bundle(); 11588 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11589 results.putString("Error", report); 11590 watcher.instrumentationStatus(cn, -1, results); 11591 } 11592 } catch (RemoteException e) { 11593 Slog.w(TAG, e); 11594 } 11595 } 11596 11597 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11598 if (app.instrumentationWatcher != null) { 11599 try { 11600 // NOTE: IInstrumentationWatcher *must* be oneway here 11601 app.instrumentationWatcher.instrumentationFinished( 11602 app.instrumentationClass, 11603 resultCode, 11604 results); 11605 } catch (RemoteException e) { 11606 } 11607 } 11608 app.instrumentationWatcher = null; 11609 app.instrumentationClass = null; 11610 app.instrumentationInfo = null; 11611 app.instrumentationProfileFile = null; 11612 app.instrumentationArguments = null; 11613 11614 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11615 } 11616 11617 public void finishInstrumentation(IApplicationThread target, 11618 int resultCode, Bundle results) { 11619 int userId = UserHandle.getCallingUserId(); 11620 // Refuse possible leaked file descriptors 11621 if (results != null && results.hasFileDescriptors()) { 11622 throw new IllegalArgumentException("File descriptors passed in Intent"); 11623 } 11624 11625 synchronized(this) { 11626 ProcessRecord app = getRecordForAppLocked(target); 11627 if (app == null) { 11628 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11629 return; 11630 } 11631 final long origId = Binder.clearCallingIdentity(); 11632 finishInstrumentationLocked(app, resultCode, results); 11633 Binder.restoreCallingIdentity(origId); 11634 } 11635 } 11636 11637 // ========================================================= 11638 // CONFIGURATION 11639 // ========================================================= 11640 11641 public ConfigurationInfo getDeviceConfigurationInfo() { 11642 ConfigurationInfo config = new ConfigurationInfo(); 11643 synchronized (this) { 11644 config.reqTouchScreen = mConfiguration.touchscreen; 11645 config.reqKeyboardType = mConfiguration.keyboard; 11646 config.reqNavigation = mConfiguration.navigation; 11647 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11648 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11649 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11650 } 11651 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11652 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11653 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11654 } 11655 config.reqGlEsVersion = GL_ES_VERSION; 11656 } 11657 return config; 11658 } 11659 11660 public Configuration getConfiguration() { 11661 Configuration ci; 11662 synchronized(this) { 11663 ci = new Configuration(mConfiguration); 11664 } 11665 return ci; 11666 } 11667 11668 public void updatePersistentConfiguration(Configuration values) { 11669 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11670 "updateConfiguration()"); 11671 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11672 "updateConfiguration()"); 11673 if (values == null) { 11674 throw new NullPointerException("Configuration must not be null"); 11675 } 11676 11677 synchronized(this) { 11678 final long origId = Binder.clearCallingIdentity(); 11679 updateConfigurationLocked(values, null, true, false); 11680 Binder.restoreCallingIdentity(origId); 11681 } 11682 } 11683 11684 public void updateConfiguration(Configuration values) { 11685 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11686 "updateConfiguration()"); 11687 11688 synchronized(this) { 11689 if (values == null && mWindowManager != null) { 11690 // sentinel: fetch the current configuration from the window manager 11691 values = mWindowManager.computeNewConfiguration(); 11692 } 11693 11694 if (mWindowManager != null) { 11695 mProcessList.applyDisplaySize(mWindowManager); 11696 } 11697 11698 final long origId = Binder.clearCallingIdentity(); 11699 if (values != null) { 11700 Settings.System.clearConfiguration(values); 11701 } 11702 updateConfigurationLocked(values, null, false, false); 11703 Binder.restoreCallingIdentity(origId); 11704 } 11705 } 11706 11707 /** 11708 * Do either or both things: (1) change the current configuration, and (2) 11709 * make sure the given activity is running with the (now) current 11710 * configuration. Returns true if the activity has been left running, or 11711 * false if <var>starting</var> is being destroyed to match the new 11712 * configuration. 11713 * @param persistent TODO 11714 */ 11715 boolean updateConfigurationLocked(Configuration values, 11716 ActivityRecord starting, boolean persistent, boolean initLocale) { 11717 // do nothing if we are headless 11718 if (mHeadless) return true; 11719 11720 int changes = 0; 11721 11722 boolean kept = true; 11723 11724 if (values != null) { 11725 Configuration newConfig = new Configuration(mConfiguration); 11726 changes = newConfig.updateFrom(values); 11727 if (changes != 0) { 11728 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11729 Slog.i(TAG, "Updating configuration to: " + values); 11730 } 11731 11732 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11733 11734 if (values.locale != null && !initLocale) { 11735 saveLocaleLocked(values.locale, 11736 !values.locale.equals(mConfiguration.locale), 11737 values.userSetLocale); 11738 } 11739 11740 mConfigurationSeq++; 11741 if (mConfigurationSeq <= 0) { 11742 mConfigurationSeq = 1; 11743 } 11744 newConfig.seq = mConfigurationSeq; 11745 mConfiguration = newConfig; 11746 Slog.i(TAG, "Config changed: " + newConfig); 11747 11748 final Configuration configCopy = new Configuration(mConfiguration); 11749 11750 // TODO: If our config changes, should we auto dismiss any currently 11751 // showing dialogs? 11752 mShowDialogs = shouldShowDialogs(newConfig); 11753 11754 AttributeCache ac = AttributeCache.instance(); 11755 if (ac != null) { 11756 ac.updateConfiguration(configCopy); 11757 } 11758 11759 // Make sure all resources in our process are updated 11760 // right now, so that anyone who is going to retrieve 11761 // resource values after we return will be sure to get 11762 // the new ones. This is especially important during 11763 // boot, where the first config change needs to guarantee 11764 // all resources have that config before following boot 11765 // code is executed. 11766 mSystemThread.applyConfigurationToResources(configCopy); 11767 11768 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11769 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11770 msg.obj = new Configuration(configCopy); 11771 mHandler.sendMessage(msg); 11772 } 11773 11774 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11775 ProcessRecord app = mLruProcesses.get(i); 11776 try { 11777 if (app.thread != null) { 11778 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11779 + app.processName + " new config " + mConfiguration); 11780 app.thread.scheduleConfigurationChanged(configCopy); 11781 } 11782 } catch (Exception e) { 11783 } 11784 } 11785 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11786 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11787 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11788 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11789 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11790 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11791 broadcastIntentLocked(null, null, 11792 new Intent(Intent.ACTION_LOCALE_CHANGED), 11793 null, null, 0, null, null, 11794 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11795 } 11796 } 11797 } 11798 11799 if (changes != 0 && starting == null) { 11800 // If the configuration changed, and the caller is not already 11801 // in the process of starting an activity, then find the top 11802 // activity to check if its configuration needs to change. 11803 starting = mMainStack.topRunningActivityLocked(null); 11804 } 11805 11806 if (starting != null) { 11807 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11808 // And we need to make sure at this point that all other activities 11809 // are made visible with the correct configuration. 11810 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11811 } 11812 11813 if (values != null && mWindowManager != null) { 11814 mWindowManager.setNewConfiguration(mConfiguration); 11815 } 11816 11817 return kept; 11818 } 11819 11820 /** 11821 * Decide based on the configuration whether we should shouw the ANR, 11822 * crash, etc dialogs. The idea is that if there is no affordnace to 11823 * press the on-screen buttons, we shouldn't show the dialog. 11824 * 11825 * A thought: SystemUI might also want to get told about this, the Power 11826 * dialog / global actions also might want different behaviors. 11827 */ 11828 private static final boolean shouldShowDialogs(Configuration config) { 11829 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11830 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11831 } 11832 11833 /** 11834 * Save the locale. You must be inside a synchronized (this) block. 11835 */ 11836 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11837 if(isDiff) { 11838 SystemProperties.set("user.language", l.getLanguage()); 11839 SystemProperties.set("user.region", l.getCountry()); 11840 } 11841 11842 if(isPersist) { 11843 SystemProperties.set("persist.sys.language", l.getLanguage()); 11844 SystemProperties.set("persist.sys.country", l.getCountry()); 11845 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11846 } 11847 } 11848 11849 @Override 11850 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11851 ActivityRecord srec = ActivityRecord.forToken(token); 11852 return srec != null && srec.task.affinity != null && 11853 srec.task.affinity.equals(destAffinity); 11854 } 11855 11856 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11857 Intent resultData) { 11858 ComponentName dest = destIntent.getComponent(); 11859 11860 synchronized (this) { 11861 ActivityRecord srec = ActivityRecord.forToken(token); 11862 if (srec == null) { 11863 return false; 11864 } 11865 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11866 final int start = history.indexOf(srec); 11867 if (start < 0) { 11868 // Current activity is not in history stack; do nothing. 11869 return false; 11870 } 11871 int finishTo = start - 1; 11872 ActivityRecord parent = null; 11873 boolean foundParentInTask = false; 11874 if (dest != null) { 11875 TaskRecord tr = srec.task; 11876 for (int i = start - 1; i >= 0; i--) { 11877 ActivityRecord r = history.get(i); 11878 if (tr != r.task) { 11879 // Couldn't find parent in the same task; stop at the one above this. 11880 // (Root of current task; in-app "home" behavior) 11881 // Always at least finish the current activity. 11882 finishTo = Math.min(start - 1, i + 1); 11883 parent = history.get(finishTo); 11884 break; 11885 } else if (r.info.packageName.equals(dest.getPackageName()) && 11886 r.info.name.equals(dest.getClassName())) { 11887 finishTo = i; 11888 parent = r; 11889 foundParentInTask = true; 11890 break; 11891 } 11892 } 11893 } 11894 11895 if (mController != null) { 11896 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11897 if (next != null) { 11898 // ask watcher if this is allowed 11899 boolean resumeOK = true; 11900 try { 11901 resumeOK = mController.activityResuming(next.packageName); 11902 } catch (RemoteException e) { 11903 mController = null; 11904 } 11905 11906 if (!resumeOK) { 11907 return false; 11908 } 11909 } 11910 } 11911 final long origId = Binder.clearCallingIdentity(); 11912 for (int i = start; i > finishTo; i--) { 11913 ActivityRecord r = history.get(i); 11914 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11915 "navigate-up"); 11916 // Only return the supplied result for the first activity finished 11917 resultCode = Activity.RESULT_CANCELED; 11918 resultData = null; 11919 } 11920 11921 if (parent != null && foundParentInTask) { 11922 final int parentLaunchMode = parent.info.launchMode; 11923 final int destIntentFlags = destIntent.getFlags(); 11924 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11925 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11926 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11927 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11928 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11929 } else { 11930 try { 11931 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11932 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 11933 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11934 null, aInfo, parent.appToken, null, 11935 0, -1, parent.launchedFromUid, 0, null, true, null); 11936 foundParentInTask = res == ActivityManager.START_SUCCESS; 11937 } catch (RemoteException e) { 11938 foundParentInTask = false; 11939 } 11940 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11941 resultData, "navigate-up"); 11942 } 11943 } 11944 Binder.restoreCallingIdentity(origId); 11945 return foundParentInTask; 11946 } 11947 } 11948 11949 public int getLaunchedFromUid(IBinder activityToken) { 11950 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11951 if (srec == null) { 11952 return -1; 11953 } 11954 return srec.launchedFromUid; 11955 } 11956 11957 // ========================================================= 11958 // LIFETIME MANAGEMENT 11959 // ========================================================= 11960 11961 // Returns which broadcast queue the app is the current [or imminent] receiver 11962 // on, or 'null' if the app is not an active broadcast recipient. 11963 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11964 BroadcastRecord r = app.curReceiver; 11965 if (r != null) { 11966 return r.queue; 11967 } 11968 11969 // It's not the current receiver, but it might be starting up to become one 11970 synchronized (this) { 11971 for (BroadcastQueue queue : mBroadcastQueues) { 11972 r = queue.mPendingBroadcast; 11973 if (r != null && r.curApp == app) { 11974 // found it; report which queue it's in 11975 return queue; 11976 } 11977 } 11978 } 11979 11980 return null; 11981 } 11982 11983 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 11984 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 11985 if (mAdjSeq == app.adjSeq) { 11986 // This adjustment has already been computed. If we are calling 11987 // from the top, we may have already computed our adjustment with 11988 // an earlier hidden adjustment that isn't really for us... if 11989 // so, use the new hidden adjustment. 11990 if (!recursed && app.hidden) { 11991 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 11992 app.hasActivities ? hiddenAdj : emptyAdj; 11993 } 11994 return app.curRawAdj; 11995 } 11996 11997 if (app.thread == null) { 11998 app.adjSeq = mAdjSeq; 11999 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12000 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12001 } 12002 12003 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12004 app.adjSource = null; 12005 app.adjTarget = null; 12006 app.empty = false; 12007 app.hidden = false; 12008 12009 final int activitiesSize = app.activities.size(); 12010 12011 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12012 // The max adjustment doesn't allow this app to be anything 12013 // below foreground, so it is not worth doing work for it. 12014 app.adjType = "fixed"; 12015 app.adjSeq = mAdjSeq; 12016 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12017 app.hasActivities = false; 12018 app.foregroundActivities = false; 12019 app.keeping = true; 12020 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12021 // System process can do UI, and when they do we want to have 12022 // them trim their memory after the user leaves the UI. To 12023 // facilitate this, here we need to determine whether or not it 12024 // is currently showing UI. 12025 app.systemNoUi = true; 12026 if (app == TOP_APP) { 12027 app.systemNoUi = false; 12028 app.hasActivities = true; 12029 } else if (activitiesSize > 0) { 12030 for (int j = 0; j < activitiesSize; j++) { 12031 final ActivityRecord r = app.activities.get(j); 12032 if (r.visible) { 12033 app.systemNoUi = false; 12034 } 12035 if (r.app == app) { 12036 app.hasActivities = true; 12037 } 12038 } 12039 } 12040 return (app.curAdj=app.maxAdj); 12041 } 12042 12043 app.keeping = false; 12044 app.systemNoUi = false; 12045 app.hasActivities = false; 12046 12047 // Determine the importance of the process, starting with most 12048 // important to least, and assign an appropriate OOM adjustment. 12049 int adj; 12050 int schedGroup; 12051 boolean foregroundActivities = false; 12052 boolean interesting = false; 12053 BroadcastQueue queue; 12054 if (app == TOP_APP) { 12055 // The last app on the list is the foreground app. 12056 adj = ProcessList.FOREGROUND_APP_ADJ; 12057 schedGroup = Process.THREAD_GROUP_DEFAULT; 12058 app.adjType = "top-activity"; 12059 foregroundActivities = true; 12060 interesting = true; 12061 app.hasActivities = true; 12062 } else if (app.instrumentationClass != null) { 12063 // Don't want to kill running instrumentation. 12064 adj = ProcessList.FOREGROUND_APP_ADJ; 12065 schedGroup = Process.THREAD_GROUP_DEFAULT; 12066 app.adjType = "instrumentation"; 12067 interesting = true; 12068 } else if ((queue = isReceivingBroadcast(app)) != null) { 12069 // An app that is currently receiving a broadcast also 12070 // counts as being in the foreground for OOM killer purposes. 12071 // It's placed in a sched group based on the nature of the 12072 // broadcast as reflected by which queue it's active in. 12073 adj = ProcessList.FOREGROUND_APP_ADJ; 12074 schedGroup = (queue == mFgBroadcastQueue) 12075 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12076 app.adjType = "broadcast"; 12077 } else if (app.executingServices.size() > 0) { 12078 // An app that is currently executing a service callback also 12079 // counts as being in the foreground. 12080 adj = ProcessList.FOREGROUND_APP_ADJ; 12081 schedGroup = Process.THREAD_GROUP_DEFAULT; 12082 app.adjType = "exec-service"; 12083 } else { 12084 // Assume process is hidden (has activities); we will correct 12085 // later if this is not the case. 12086 adj = hiddenAdj; 12087 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12088 app.hidden = true; 12089 app.adjType = "bg-activities"; 12090 } 12091 12092 boolean hasStoppingActivities = false; 12093 12094 // Examine all activities if not already foreground. 12095 if (!foregroundActivities && activitiesSize > 0) { 12096 for (int j = 0; j < activitiesSize; j++) { 12097 final ActivityRecord r = app.activities.get(j); 12098 if (r.visible) { 12099 // App has a visible activity; only upgrade adjustment. 12100 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12101 adj = ProcessList.VISIBLE_APP_ADJ; 12102 app.adjType = "visible"; 12103 } 12104 schedGroup = Process.THREAD_GROUP_DEFAULT; 12105 app.hidden = false; 12106 app.hasActivities = true; 12107 foregroundActivities = true; 12108 break; 12109 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12110 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12111 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12112 app.adjType = "pausing"; 12113 } 12114 app.hidden = false; 12115 foregroundActivities = true; 12116 } else if (r.state == ActivityState.STOPPING) { 12117 // We will apply the actual adjustment later, because 12118 // we want to allow this process to immediately go through 12119 // any memory trimming that is in effect. 12120 app.hidden = false; 12121 foregroundActivities = true; 12122 hasStoppingActivities = true; 12123 } 12124 if (r.app == app) { 12125 app.hasActivities = true; 12126 } 12127 } 12128 } 12129 12130 if (adj == hiddenAdj && !app.hasActivities) { 12131 // Whoops, this process is completely empty as far as we know 12132 // at this point. 12133 adj = emptyAdj; 12134 app.empty = true; 12135 app.adjType = "bg-empty"; 12136 } 12137 12138 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12139 if (app.foregroundServices) { 12140 // The user is aware of this app, so make it visible. 12141 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12142 app.hidden = false; 12143 app.adjType = "foreground-service"; 12144 schedGroup = Process.THREAD_GROUP_DEFAULT; 12145 } else if (app.forcingToForeground != null) { 12146 // The user is aware of this app, so make it visible. 12147 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12148 app.hidden = false; 12149 app.adjType = "force-foreground"; 12150 app.adjSource = app.forcingToForeground; 12151 schedGroup = Process.THREAD_GROUP_DEFAULT; 12152 } 12153 } 12154 12155 if (app.foregroundServices) { 12156 interesting = true; 12157 } 12158 12159 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12160 // We don't want to kill the current heavy-weight process. 12161 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12162 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12163 app.hidden = false; 12164 app.adjType = "heavy"; 12165 } 12166 12167 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12168 // This process is hosting what we currently consider to be the 12169 // home app, so we don't want to let it go into the background. 12170 adj = ProcessList.HOME_APP_ADJ; 12171 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12172 app.hidden = false; 12173 app.adjType = "home"; 12174 } 12175 12176 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12177 && app.activities.size() > 0) { 12178 // This was the previous process that showed UI to the user. 12179 // We want to try to keep it around more aggressively, to give 12180 // a good experience around switching between two apps. 12181 adj = ProcessList.PREVIOUS_APP_ADJ; 12182 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12183 app.hidden = false; 12184 app.adjType = "previous"; 12185 } 12186 12187 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12188 + " reason=" + app.adjType); 12189 12190 // By default, we use the computed adjustment. It may be changed if 12191 // there are applications dependent on our services or providers, but 12192 // this gives us a baseline and makes sure we don't get into an 12193 // infinite recursion. 12194 app.adjSeq = mAdjSeq; 12195 app.curRawAdj = app.nonStoppingAdj = adj; 12196 12197 if (mBackupTarget != null && app == mBackupTarget.app) { 12198 // If possible we want to avoid killing apps while they're being backed up 12199 if (adj > ProcessList.BACKUP_APP_ADJ) { 12200 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12201 adj = ProcessList.BACKUP_APP_ADJ; 12202 app.adjType = "backup"; 12203 app.hidden = false; 12204 } 12205 } 12206 12207 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12208 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12209 final long now = SystemClock.uptimeMillis(); 12210 // This process is more important if the top activity is 12211 // bound to the service. 12212 Iterator<ServiceRecord> jt = app.services.iterator(); 12213 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12214 ServiceRecord s = jt.next(); 12215 if (s.startRequested) { 12216 if (app.hasShownUi && app != mHomeProcess) { 12217 // If this process has shown some UI, let it immediately 12218 // go to the LRU list because it may be pretty heavy with 12219 // UI stuff. We'll tag it with a label just to help 12220 // debug and understand what is going on. 12221 if (adj > ProcessList.SERVICE_ADJ) { 12222 app.adjType = "started-bg-ui-services"; 12223 } 12224 } else { 12225 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12226 // This service has seen some activity within 12227 // recent memory, so we will keep its process ahead 12228 // of the background processes. 12229 if (adj > ProcessList.SERVICE_ADJ) { 12230 adj = ProcessList.SERVICE_ADJ; 12231 app.adjType = "started-services"; 12232 app.hidden = false; 12233 } 12234 } 12235 // If we have let the service slide into the background 12236 // state, still have some text describing what it is doing 12237 // even though the service no longer has an impact. 12238 if (adj > ProcessList.SERVICE_ADJ) { 12239 app.adjType = "started-bg-services"; 12240 } 12241 } 12242 // Don't kill this process because it is doing work; it 12243 // has said it is doing work. 12244 app.keeping = true; 12245 } 12246 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12247 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12248 Iterator<ArrayList<ConnectionRecord>> kt 12249 = s.connections.values().iterator(); 12250 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12251 ArrayList<ConnectionRecord> clist = kt.next(); 12252 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12253 // XXX should compute this based on the max of 12254 // all connected clients. 12255 ConnectionRecord cr = clist.get(i); 12256 if (cr.binding.client == app) { 12257 // Binding to ourself is not interesting. 12258 continue; 12259 } 12260 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12261 ProcessRecord client = cr.binding.client; 12262 int clientAdj = adj; 12263 int myHiddenAdj = hiddenAdj; 12264 if (myHiddenAdj > client.hiddenAdj) { 12265 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12266 myHiddenAdj = client.hiddenAdj; 12267 } else { 12268 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12269 } 12270 } 12271 int myEmptyAdj = emptyAdj; 12272 if (myEmptyAdj > client.emptyAdj) { 12273 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12274 myEmptyAdj = client.emptyAdj; 12275 } else { 12276 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12277 } 12278 } 12279 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12280 myEmptyAdj, TOP_APP, true, doingAll); 12281 String adjType = null; 12282 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12283 // Not doing bind OOM management, so treat 12284 // this guy more like a started service. 12285 if (app.hasShownUi && app != mHomeProcess) { 12286 // If this process has shown some UI, let it immediately 12287 // go to the LRU list because it may be pretty heavy with 12288 // UI stuff. We'll tag it with a label just to help 12289 // debug and understand what is going on. 12290 if (adj > clientAdj) { 12291 adjType = "bound-bg-ui-services"; 12292 } 12293 app.hidden = false; 12294 clientAdj = adj; 12295 } else { 12296 if (now >= (s.lastActivity 12297 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12298 // This service has not seen activity within 12299 // recent memory, so allow it to drop to the 12300 // LRU list if there is no other reason to keep 12301 // it around. We'll also tag it with a label just 12302 // to help debug and undertand what is going on. 12303 if (adj > clientAdj) { 12304 adjType = "bound-bg-services"; 12305 } 12306 clientAdj = adj; 12307 } 12308 } 12309 } 12310 if (adj > clientAdj) { 12311 // If this process has recently shown UI, and 12312 // the process that is binding to it is less 12313 // important than being visible, then we don't 12314 // care about the binding as much as we care 12315 // about letting this process get into the LRU 12316 // list to be killed and restarted if needed for 12317 // memory. 12318 if (app.hasShownUi && app != mHomeProcess 12319 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12320 adjType = "bound-bg-ui-services"; 12321 } else { 12322 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12323 |Context.BIND_IMPORTANT)) != 0) { 12324 adj = clientAdj; 12325 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12326 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12327 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12328 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12329 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12330 adj = clientAdj; 12331 } else { 12332 app.pendingUiClean = true; 12333 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12334 adj = ProcessList.VISIBLE_APP_ADJ; 12335 } 12336 } 12337 if (!client.hidden) { 12338 app.hidden = false; 12339 } 12340 if (client.keeping) { 12341 app.keeping = true; 12342 } 12343 adjType = "service"; 12344 } 12345 } 12346 if (adjType != null) { 12347 app.adjType = adjType; 12348 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12349 .REASON_SERVICE_IN_USE; 12350 app.adjSource = cr.binding.client; 12351 app.adjSourceOom = clientAdj; 12352 app.adjTarget = s.name; 12353 } 12354 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12355 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12356 schedGroup = Process.THREAD_GROUP_DEFAULT; 12357 } 12358 } 12359 } 12360 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12361 ActivityRecord a = cr.activity; 12362 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12363 (a.visible || a.state == ActivityState.RESUMED 12364 || a.state == ActivityState.PAUSING)) { 12365 adj = ProcessList.FOREGROUND_APP_ADJ; 12366 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12367 schedGroup = Process.THREAD_GROUP_DEFAULT; 12368 } 12369 app.hidden = false; 12370 app.adjType = "service"; 12371 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12372 .REASON_SERVICE_IN_USE; 12373 app.adjSource = a; 12374 app.adjSourceOom = adj; 12375 app.adjTarget = s.name; 12376 } 12377 } 12378 } 12379 } 12380 } 12381 } 12382 12383 // Finally, if this process has active services running in it, we 12384 // would like to avoid killing it unless it would prevent the current 12385 // application from running. By default we put the process in 12386 // with the rest of the background processes; as we scan through 12387 // its services we may bump it up from there. 12388 if (adj > hiddenAdj) { 12389 adj = hiddenAdj; 12390 app.hidden = false; 12391 app.adjType = "bg-services"; 12392 } 12393 } 12394 12395 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12396 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12397 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12398 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12399 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12400 ContentProviderRecord cpr = jt.next(); 12401 for (int i = cpr.connections.size()-1; 12402 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12403 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12404 i--) { 12405 ContentProviderConnection conn = cpr.connections.get(i); 12406 ProcessRecord client = conn.client; 12407 if (client == app) { 12408 // Being our own client is not interesting. 12409 continue; 12410 } 12411 int myHiddenAdj = hiddenAdj; 12412 if (myHiddenAdj > client.hiddenAdj) { 12413 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12414 myHiddenAdj = client.hiddenAdj; 12415 } else { 12416 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12417 } 12418 } 12419 int myEmptyAdj = emptyAdj; 12420 if (myEmptyAdj > client.emptyAdj) { 12421 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12422 myEmptyAdj = client.emptyAdj; 12423 } else { 12424 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12425 } 12426 } 12427 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12428 myEmptyAdj, TOP_APP, true, doingAll); 12429 if (adj > clientAdj) { 12430 if (app.hasShownUi && app != mHomeProcess 12431 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12432 app.adjType = "bg-ui-provider"; 12433 } else { 12434 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12435 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12436 app.adjType = "provider"; 12437 } 12438 if (!client.hidden) { 12439 app.hidden = false; 12440 } 12441 if (client.keeping) { 12442 app.keeping = true; 12443 } 12444 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12445 .REASON_PROVIDER_IN_USE; 12446 app.adjSource = client; 12447 app.adjSourceOom = clientAdj; 12448 app.adjTarget = cpr.name; 12449 } 12450 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12451 schedGroup = Process.THREAD_GROUP_DEFAULT; 12452 } 12453 } 12454 // If the provider has external (non-framework) process 12455 // dependencies, ensure that its adjustment is at least 12456 // FOREGROUND_APP_ADJ. 12457 if (cpr.hasExternalProcessHandles()) { 12458 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12459 adj = ProcessList.FOREGROUND_APP_ADJ; 12460 schedGroup = Process.THREAD_GROUP_DEFAULT; 12461 app.hidden = false; 12462 app.keeping = true; 12463 app.adjType = "provider"; 12464 app.adjTarget = cpr.name; 12465 } 12466 } 12467 } 12468 } 12469 12470 if (adj == ProcessList.SERVICE_ADJ) { 12471 if (doingAll) { 12472 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12473 mNewNumServiceProcs++; 12474 } 12475 if (app.serviceb) { 12476 adj = ProcessList.SERVICE_B_ADJ; 12477 } 12478 } else { 12479 app.serviceb = false; 12480 } 12481 12482 app.nonStoppingAdj = adj; 12483 12484 if (hasStoppingActivities) { 12485 // Only upgrade adjustment. 12486 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12487 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12488 app.adjType = "stopping"; 12489 } 12490 } 12491 12492 app.curRawAdj = adj; 12493 12494 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12495 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12496 if (adj > app.maxAdj) { 12497 adj = app.maxAdj; 12498 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12499 schedGroup = Process.THREAD_GROUP_DEFAULT; 12500 } 12501 } 12502 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12503 app.keeping = true; 12504 } 12505 12506 if (app.hasAboveClient) { 12507 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12508 // then we need to drop its adjustment to be lower than the service's 12509 // in order to honor the request. We want to drop it by one adjustment 12510 // level... but there is special meaning applied to various levels so 12511 // we will skip some of them. 12512 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12513 // System process will not get dropped, ever 12514 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12515 adj = ProcessList.VISIBLE_APP_ADJ; 12516 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12517 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12518 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12519 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12520 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12521 adj++; 12522 } 12523 } 12524 12525 int importance = app.memImportance; 12526 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12527 app.curAdj = adj; 12528 app.curSchedGroup = schedGroup; 12529 if (!interesting) { 12530 // For this reporting, if there is not something explicitly 12531 // interesting in this process then we will push it to the 12532 // background importance. 12533 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12534 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12535 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12536 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12537 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12538 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12539 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12540 } else if (adj >= ProcessList.SERVICE_ADJ) { 12541 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12542 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12543 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12544 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12545 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12546 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12547 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12548 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12549 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12550 } else { 12551 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12552 } 12553 } 12554 12555 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12556 if (foregroundActivities != app.foregroundActivities) { 12557 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12558 } 12559 if (changes != 0) { 12560 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12561 app.memImportance = importance; 12562 app.foregroundActivities = foregroundActivities; 12563 int i = mPendingProcessChanges.size()-1; 12564 ProcessChangeItem item = null; 12565 while (i >= 0) { 12566 item = mPendingProcessChanges.get(i); 12567 if (item.pid == app.pid) { 12568 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12569 break; 12570 } 12571 i--; 12572 } 12573 if (i < 0) { 12574 // No existing item in pending changes; need a new one. 12575 final int NA = mAvailProcessChanges.size(); 12576 if (NA > 0) { 12577 item = mAvailProcessChanges.remove(NA-1); 12578 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12579 } else { 12580 item = new ProcessChangeItem(); 12581 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12582 } 12583 item.changes = 0; 12584 item.pid = app.pid; 12585 item.uid = app.info.uid; 12586 if (mPendingProcessChanges.size() == 0) { 12587 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12588 "*** Enqueueing dispatch processes changed!"); 12589 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12590 } 12591 mPendingProcessChanges.add(item); 12592 } 12593 item.changes |= changes; 12594 item.importance = importance; 12595 item.foregroundActivities = foregroundActivities; 12596 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12597 + Integer.toHexString(System.identityHashCode(item)) 12598 + " " + app.toShortString() + ": changes=" + item.changes 12599 + " importance=" + item.importance 12600 + " foreground=" + item.foregroundActivities 12601 + " type=" + app.adjType + " source=" + app.adjSource 12602 + " target=" + app.adjTarget); 12603 } 12604 12605 return app.curRawAdj; 12606 } 12607 12608 /** 12609 * Ask a given process to GC right now. 12610 */ 12611 final void performAppGcLocked(ProcessRecord app) { 12612 try { 12613 app.lastRequestedGc = SystemClock.uptimeMillis(); 12614 if (app.thread != null) { 12615 if (app.reportLowMemory) { 12616 app.reportLowMemory = false; 12617 app.thread.scheduleLowMemory(); 12618 } else { 12619 app.thread.processInBackground(); 12620 } 12621 } 12622 } catch (Exception e) { 12623 // whatever. 12624 } 12625 } 12626 12627 /** 12628 * Returns true if things are idle enough to perform GCs. 12629 */ 12630 private final boolean canGcNowLocked() { 12631 boolean processingBroadcasts = false; 12632 for (BroadcastQueue q : mBroadcastQueues) { 12633 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12634 processingBroadcasts = true; 12635 } 12636 } 12637 return !processingBroadcasts 12638 && (mSleeping || (mMainStack.mResumedActivity != null && 12639 mMainStack.mResumedActivity.idle)); 12640 } 12641 12642 /** 12643 * Perform GCs on all processes that are waiting for it, but only 12644 * if things are idle. 12645 */ 12646 final void performAppGcsLocked() { 12647 final int N = mProcessesToGc.size(); 12648 if (N <= 0) { 12649 return; 12650 } 12651 if (canGcNowLocked()) { 12652 while (mProcessesToGc.size() > 0) { 12653 ProcessRecord proc = mProcessesToGc.remove(0); 12654 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12655 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12656 <= SystemClock.uptimeMillis()) { 12657 // To avoid spamming the system, we will GC processes one 12658 // at a time, waiting a few seconds between each. 12659 performAppGcLocked(proc); 12660 scheduleAppGcsLocked(); 12661 return; 12662 } else { 12663 // It hasn't been long enough since we last GCed this 12664 // process... put it in the list to wait for its time. 12665 addProcessToGcListLocked(proc); 12666 break; 12667 } 12668 } 12669 } 12670 12671 scheduleAppGcsLocked(); 12672 } 12673 } 12674 12675 /** 12676 * If all looks good, perform GCs on all processes waiting for them. 12677 */ 12678 final void performAppGcsIfAppropriateLocked() { 12679 if (canGcNowLocked()) { 12680 performAppGcsLocked(); 12681 return; 12682 } 12683 // Still not idle, wait some more. 12684 scheduleAppGcsLocked(); 12685 } 12686 12687 /** 12688 * Schedule the execution of all pending app GCs. 12689 */ 12690 final void scheduleAppGcsLocked() { 12691 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12692 12693 if (mProcessesToGc.size() > 0) { 12694 // Schedule a GC for the time to the next process. 12695 ProcessRecord proc = mProcessesToGc.get(0); 12696 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12697 12698 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12699 long now = SystemClock.uptimeMillis(); 12700 if (when < (now+GC_TIMEOUT)) { 12701 when = now + GC_TIMEOUT; 12702 } 12703 mHandler.sendMessageAtTime(msg, when); 12704 } 12705 } 12706 12707 /** 12708 * Add a process to the array of processes waiting to be GCed. Keeps the 12709 * list in sorted order by the last GC time. The process can't already be 12710 * on the list. 12711 */ 12712 final void addProcessToGcListLocked(ProcessRecord proc) { 12713 boolean added = false; 12714 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12715 if (mProcessesToGc.get(i).lastRequestedGc < 12716 proc.lastRequestedGc) { 12717 added = true; 12718 mProcessesToGc.add(i+1, proc); 12719 break; 12720 } 12721 } 12722 if (!added) { 12723 mProcessesToGc.add(0, proc); 12724 } 12725 } 12726 12727 /** 12728 * Set up to ask a process to GC itself. This will either do it 12729 * immediately, or put it on the list of processes to gc the next 12730 * time things are idle. 12731 */ 12732 final void scheduleAppGcLocked(ProcessRecord app) { 12733 long now = SystemClock.uptimeMillis(); 12734 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12735 return; 12736 } 12737 if (!mProcessesToGc.contains(app)) { 12738 addProcessToGcListLocked(app); 12739 scheduleAppGcsLocked(); 12740 } 12741 } 12742 12743 final void checkExcessivePowerUsageLocked(boolean doKills) { 12744 updateCpuStatsNow(); 12745 12746 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12747 boolean doWakeKills = doKills; 12748 boolean doCpuKills = doKills; 12749 if (mLastPowerCheckRealtime == 0) { 12750 doWakeKills = false; 12751 } 12752 if (mLastPowerCheckUptime == 0) { 12753 doCpuKills = false; 12754 } 12755 if (stats.isScreenOn()) { 12756 doWakeKills = false; 12757 } 12758 final long curRealtime = SystemClock.elapsedRealtime(); 12759 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12760 final long curUptime = SystemClock.uptimeMillis(); 12761 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12762 mLastPowerCheckRealtime = curRealtime; 12763 mLastPowerCheckUptime = curUptime; 12764 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12765 doWakeKills = false; 12766 } 12767 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12768 doCpuKills = false; 12769 } 12770 int i = mLruProcesses.size(); 12771 while (i > 0) { 12772 i--; 12773 ProcessRecord app = mLruProcesses.get(i); 12774 if (!app.keeping) { 12775 long wtime; 12776 synchronized (stats) { 12777 wtime = stats.getProcessWakeTime(app.info.uid, 12778 app.pid, curRealtime); 12779 } 12780 long wtimeUsed = wtime - app.lastWakeTime; 12781 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12782 if (DEBUG_POWER) { 12783 StringBuilder sb = new StringBuilder(128); 12784 sb.append("Wake for "); 12785 app.toShortString(sb); 12786 sb.append(": over "); 12787 TimeUtils.formatDuration(realtimeSince, sb); 12788 sb.append(" used "); 12789 TimeUtils.formatDuration(wtimeUsed, sb); 12790 sb.append(" ("); 12791 sb.append((wtimeUsed*100)/realtimeSince); 12792 sb.append("%)"); 12793 Slog.i(TAG, sb.toString()); 12794 sb.setLength(0); 12795 sb.append("CPU for "); 12796 app.toShortString(sb); 12797 sb.append(": over "); 12798 TimeUtils.formatDuration(uptimeSince, sb); 12799 sb.append(" used "); 12800 TimeUtils.formatDuration(cputimeUsed, sb); 12801 sb.append(" ("); 12802 sb.append((cputimeUsed*100)/uptimeSince); 12803 sb.append("%)"); 12804 Slog.i(TAG, sb.toString()); 12805 } 12806 // If a process has held a wake lock for more 12807 // than 50% of the time during this period, 12808 // that sounds bad. Kill! 12809 if (doWakeKills && realtimeSince > 0 12810 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12811 synchronized (stats) { 12812 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12813 realtimeSince, wtimeUsed); 12814 } 12815 Slog.w(TAG, "Excessive wake lock in " + app.processName 12816 + " (pid " + app.pid + "): held " + wtimeUsed 12817 + " during " + realtimeSince); 12818 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12819 app.processName, app.setAdj, "excessive wake lock"); 12820 Process.killProcessQuiet(app.pid); 12821 } else if (doCpuKills && uptimeSince > 0 12822 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12823 synchronized (stats) { 12824 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12825 uptimeSince, cputimeUsed); 12826 } 12827 Slog.w(TAG, "Excessive CPU in " + app.processName 12828 + " (pid " + app.pid + "): used " + cputimeUsed 12829 + " during " + uptimeSince); 12830 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12831 app.processName, app.setAdj, "excessive cpu"); 12832 Process.killProcessQuiet(app.pid); 12833 } else { 12834 app.lastWakeTime = wtime; 12835 app.lastCpuTime = app.curCpuTime; 12836 } 12837 } 12838 } 12839 } 12840 12841 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12842 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12843 app.hiddenAdj = hiddenAdj; 12844 app.emptyAdj = emptyAdj; 12845 12846 if (app.thread == null) { 12847 return false; 12848 } 12849 12850 final boolean wasKeeping = app.keeping; 12851 12852 boolean success = true; 12853 12854 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12855 12856 if (app.curRawAdj != app.setRawAdj) { 12857 if (wasKeeping && !app.keeping) { 12858 // This app is no longer something we want to keep. Note 12859 // its current wake lock time to later know to kill it if 12860 // it is not behaving well. 12861 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12862 synchronized (stats) { 12863 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12864 app.pid, SystemClock.elapsedRealtime()); 12865 } 12866 app.lastCpuTime = app.curCpuTime; 12867 } 12868 12869 app.setRawAdj = app.curRawAdj; 12870 } 12871 12872 if (app.curAdj != app.setAdj) { 12873 if (Process.setOomAdj(app.pid, app.curAdj)) { 12874 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12875 TAG, "Set " + app.pid + " " + app.processName + 12876 " adj " + app.curAdj + ": " + app.adjType); 12877 app.setAdj = app.curAdj; 12878 } else { 12879 success = false; 12880 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12881 } 12882 } 12883 if (app.setSchedGroup != app.curSchedGroup) { 12884 app.setSchedGroup = app.curSchedGroup; 12885 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12886 "Setting process group of " + app.processName 12887 + " to " + app.curSchedGroup); 12888 if (app.waitingToKill != null && 12889 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12890 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12891 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12892 app.processName, app.setAdj, app.waitingToKill); 12893 app.killedBackground = true; 12894 Process.killProcessQuiet(app.pid); 12895 success = false; 12896 } else { 12897 if (true) { 12898 long oldId = Binder.clearCallingIdentity(); 12899 try { 12900 Process.setProcessGroup(app.pid, app.curSchedGroup); 12901 } catch (Exception e) { 12902 Slog.w(TAG, "Failed setting process group of " + app.pid 12903 + " to " + app.curSchedGroup); 12904 e.printStackTrace(); 12905 } finally { 12906 Binder.restoreCallingIdentity(oldId); 12907 } 12908 } else { 12909 if (app.thread != null) { 12910 try { 12911 app.thread.setSchedulingGroup(app.curSchedGroup); 12912 } catch (RemoteException e) { 12913 } 12914 } 12915 } 12916 } 12917 } 12918 return success; 12919 } 12920 12921 private final ActivityRecord resumedAppLocked() { 12922 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12923 if (resumedActivity == null || resumedActivity.app == null) { 12924 resumedActivity = mMainStack.mPausingActivity; 12925 if (resumedActivity == null || resumedActivity.app == null) { 12926 resumedActivity = mMainStack.topRunningActivityLocked(null); 12927 } 12928 } 12929 return resumedActivity; 12930 } 12931 12932 final boolean updateOomAdjLocked(ProcessRecord app) { 12933 final ActivityRecord TOP_ACT = resumedAppLocked(); 12934 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12935 int curAdj = app.curAdj; 12936 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12937 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12938 12939 mAdjSeq++; 12940 12941 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 12942 TOP_APP, false); 12943 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12944 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12945 if (nowHidden != wasHidden) { 12946 // Changed to/from hidden state, so apps after it in the LRU 12947 // list may also be changed. 12948 updateOomAdjLocked(); 12949 } 12950 return success; 12951 } 12952 12953 final void updateOomAdjLocked() { 12954 final ActivityRecord TOP_ACT = resumedAppLocked(); 12955 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12956 12957 if (false) { 12958 RuntimeException e = new RuntimeException(); 12959 e.fillInStackTrace(); 12960 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12961 } 12962 12963 mAdjSeq++; 12964 mNewNumServiceProcs = 0; 12965 12966 // Let's determine how many processes we have running vs. 12967 // how many slots we have for background processes; we may want 12968 // to put multiple processes in a slot of there are enough of 12969 // them. 12970 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 12971 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 12972 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 12973 if (emptyFactor < 1) emptyFactor = 1; 12974 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 12975 if (hiddenFactor < 1) hiddenFactor = 1; 12976 int stepHidden = 0; 12977 int stepEmpty = 0; 12978 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 12979 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 12980 int numHidden = 0; 12981 int numEmpty = 0; 12982 int numTrimming = 0; 12983 12984 mNumNonHiddenProcs = 0; 12985 mNumHiddenProcs = 0; 12986 12987 // First update the OOM adjustment for each of the 12988 // application processes based on their current state. 12989 int i = mLruProcesses.size(); 12990 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 12991 int nextHiddenAdj = curHiddenAdj+1; 12992 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 12993 int nextEmptyAdj = curEmptyAdj+2; 12994 while (i > 0) { 12995 i--; 12996 ProcessRecord app = mLruProcesses.get(i); 12997 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 12998 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 12999 if (!app.killedBackground) { 13000 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13001 // This process was assigned as a hidden process... step the 13002 // hidden level. 13003 mNumHiddenProcs++; 13004 if (curHiddenAdj != nextHiddenAdj) { 13005 stepHidden++; 13006 if (stepHidden >= hiddenFactor) { 13007 stepHidden = 0; 13008 curHiddenAdj = nextHiddenAdj; 13009 nextHiddenAdj += 2; 13010 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13011 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13012 } 13013 } 13014 } 13015 numHidden++; 13016 if (numHidden > hiddenProcessLimit) { 13017 Slog.i(TAG, "No longer want " + app.processName 13018 + " (pid " + app.pid + "): hidden #" + numHidden); 13019 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13020 app.processName, app.setAdj, "too many background"); 13021 app.killedBackground = true; 13022 Process.killProcessQuiet(app.pid); 13023 } 13024 } else { 13025 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13026 // This process was assigned as an empty process... step the 13027 // empty level. 13028 if (curEmptyAdj != nextEmptyAdj) { 13029 stepEmpty++; 13030 if (stepEmpty >= emptyFactor) { 13031 stepEmpty = 0; 13032 curEmptyAdj = nextEmptyAdj; 13033 nextEmptyAdj += 2; 13034 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13035 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13036 } 13037 } 13038 } 13039 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13040 mNumNonHiddenProcs++; 13041 } 13042 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13043 numEmpty++; 13044 if (numEmpty > emptyProcessLimit) { 13045 Slog.i(TAG, "No longer want " + app.processName 13046 + " (pid " + app.pid + "): empty #" + numEmpty); 13047 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13048 app.processName, app.setAdj, "too many background"); 13049 app.killedBackground = true; 13050 Process.killProcessQuiet(app.pid); 13051 } 13052 } 13053 } 13054 if (app.isolated && app.services.size() <= 0) { 13055 // If this is an isolated process, and there are no 13056 // services running in it, then the process is no longer 13057 // needed. We agressively kill these because we can by 13058 // definition not re-use the same process again, and it is 13059 // good to avoid having whatever code was running in them 13060 // left sitting around after no longer needed. 13061 Slog.i(TAG, "Isolated process " + app.processName 13062 + " (pid " + app.pid + ") no longer needed"); 13063 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13064 app.processName, app.setAdj, "isolated not needed"); 13065 app.killedBackground = true; 13066 Process.killProcessQuiet(app.pid); 13067 } 13068 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13069 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13070 && !app.killedBackground) { 13071 numTrimming++; 13072 } 13073 } 13074 } 13075 13076 mNumServiceProcs = mNewNumServiceProcs; 13077 13078 // Now determine the memory trimming level of background processes. 13079 // Unfortunately we need to start at the back of the list to do this 13080 // properly. We only do this if the number of background apps we 13081 // are managing to keep around is less than half the maximum we desire; 13082 // if we are keeping a good number around, we'll let them use whatever 13083 // memory they want. 13084 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13085 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13086 final int numHiddenAndEmpty = numHidden + numEmpty; 13087 final int N = mLruProcesses.size(); 13088 int factor = numTrimming/3; 13089 int minFactor = 2; 13090 if (mHomeProcess != null) minFactor++; 13091 if (mPreviousProcess != null) minFactor++; 13092 if (factor < minFactor) factor = minFactor; 13093 int step = 0; 13094 int fgTrimLevel; 13095 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13096 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13097 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13098 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13099 } else { 13100 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13101 } 13102 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13103 for (i=0; i<N; i++) { 13104 ProcessRecord app = mLruProcesses.get(i); 13105 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13106 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13107 && !app.killedBackground) { 13108 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13109 try { 13110 app.thread.scheduleTrimMemory(curLevel); 13111 } catch (RemoteException e) { 13112 } 13113 if (false) { 13114 // For now we won't do this; our memory trimming seems 13115 // to be good enough at this point that destroying 13116 // activities causes more harm than good. 13117 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13118 && app != mHomeProcess && app != mPreviousProcess) { 13119 // Need to do this on its own message because the stack may not 13120 // be in a consistent state at this point. 13121 // For these apps we will also finish their activities 13122 // to help them free memory. 13123 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13124 } 13125 } 13126 } 13127 app.trimMemoryLevel = curLevel; 13128 step++; 13129 if (step >= factor) { 13130 step = 0; 13131 switch (curLevel) { 13132 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13133 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13134 break; 13135 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13136 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13137 break; 13138 } 13139 } 13140 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13141 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13142 && app.thread != null) { 13143 try { 13144 app.thread.scheduleTrimMemory( 13145 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13146 } catch (RemoteException e) { 13147 } 13148 } 13149 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13150 } else { 13151 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13152 && app.pendingUiClean) { 13153 // If this application is now in the background and it 13154 // had done UI, then give it the special trim level to 13155 // have it free UI resources. 13156 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13157 if (app.trimMemoryLevel < level && app.thread != null) { 13158 try { 13159 app.thread.scheduleTrimMemory(level); 13160 } catch (RemoteException e) { 13161 } 13162 } 13163 app.pendingUiClean = false; 13164 } 13165 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13166 try { 13167 app.thread.scheduleTrimMemory(fgTrimLevel); 13168 } catch (RemoteException e) { 13169 } 13170 } 13171 app.trimMemoryLevel = fgTrimLevel; 13172 } 13173 } 13174 } else { 13175 final int N = mLruProcesses.size(); 13176 for (i=0; i<N; i++) { 13177 ProcessRecord app = mLruProcesses.get(i); 13178 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13179 && app.pendingUiClean) { 13180 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13181 && app.thread != null) { 13182 try { 13183 app.thread.scheduleTrimMemory( 13184 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13185 } catch (RemoteException e) { 13186 } 13187 } 13188 app.pendingUiClean = false; 13189 } 13190 app.trimMemoryLevel = 0; 13191 } 13192 } 13193 13194 if (mAlwaysFinishActivities) { 13195 // Need to do this on its own message because the stack may not 13196 // be in a consistent state at this point. 13197 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13198 } 13199 } 13200 13201 final void trimApplications() { 13202 synchronized (this) { 13203 int i; 13204 13205 // First remove any unused application processes whose package 13206 // has been removed. 13207 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13208 final ProcessRecord app = mRemovedProcesses.get(i); 13209 if (app.activities.size() == 0 13210 && app.curReceiver == null && app.services.size() == 0) { 13211 Slog.i( 13212 TAG, "Exiting empty application process " 13213 + app.processName + " (" 13214 + (app.thread != null ? app.thread.asBinder() : null) 13215 + ")\n"); 13216 if (app.pid > 0 && app.pid != MY_PID) { 13217 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13218 app.processName, app.setAdj, "empty"); 13219 Process.killProcessQuiet(app.pid); 13220 } else { 13221 try { 13222 app.thread.scheduleExit(); 13223 } catch (Exception e) { 13224 // Ignore exceptions. 13225 } 13226 } 13227 cleanUpApplicationRecordLocked(app, false, true, -1); 13228 mRemovedProcesses.remove(i); 13229 13230 if (app.persistent) { 13231 if (app.persistent) { 13232 addAppLocked(app.info, false); 13233 } 13234 } 13235 } 13236 } 13237 13238 // Now update the oom adj for all processes. 13239 updateOomAdjLocked(); 13240 } 13241 } 13242 13243 /** This method sends the specified signal to each of the persistent apps */ 13244 public void signalPersistentProcesses(int sig) throws RemoteException { 13245 if (sig != Process.SIGNAL_USR1) { 13246 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13247 } 13248 13249 synchronized (this) { 13250 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13251 != PackageManager.PERMISSION_GRANTED) { 13252 throw new SecurityException("Requires permission " 13253 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13254 } 13255 13256 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13257 ProcessRecord r = mLruProcesses.get(i); 13258 if (r.thread != null && r.persistent) { 13259 Process.sendSignal(r.pid, sig); 13260 } 13261 } 13262 } 13263 } 13264 13265 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13266 if (proc == null || proc == mProfileProc) { 13267 proc = mProfileProc; 13268 path = mProfileFile; 13269 profileType = mProfileType; 13270 clearProfilerLocked(); 13271 } 13272 if (proc == null) { 13273 return; 13274 } 13275 try { 13276 proc.thread.profilerControl(false, path, null, profileType); 13277 } catch (RemoteException e) { 13278 throw new IllegalStateException("Process disappeared"); 13279 } 13280 } 13281 13282 private void clearProfilerLocked() { 13283 if (mProfileFd != null) { 13284 try { 13285 mProfileFd.close(); 13286 } catch (IOException e) { 13287 } 13288 } 13289 mProfileApp = null; 13290 mProfileProc = null; 13291 mProfileFile = null; 13292 mProfileType = 0; 13293 mAutoStopProfiler = false; 13294 } 13295 13296 public boolean profileControl(String process, boolean start, 13297 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13298 13299 try { 13300 synchronized (this) { 13301 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13302 // its own permission. 13303 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13304 != PackageManager.PERMISSION_GRANTED) { 13305 throw new SecurityException("Requires permission " 13306 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13307 } 13308 13309 if (start && fd == null) { 13310 throw new IllegalArgumentException("null fd"); 13311 } 13312 13313 ProcessRecord proc = null; 13314 if (process != null) { 13315 try { 13316 int pid = Integer.parseInt(process); 13317 synchronized (mPidsSelfLocked) { 13318 proc = mPidsSelfLocked.get(pid); 13319 } 13320 } catch (NumberFormatException e) { 13321 } 13322 13323 if (proc == null) { 13324 HashMap<String, SparseArray<ProcessRecord>> all 13325 = mProcessNames.getMap(); 13326 SparseArray<ProcessRecord> procs = all.get(process); 13327 if (procs != null && procs.size() > 0) { 13328 proc = procs.valueAt(0); 13329 } 13330 } 13331 } 13332 13333 if (start && (proc == null || proc.thread == null)) { 13334 throw new IllegalArgumentException("Unknown process: " + process); 13335 } 13336 13337 if (start) { 13338 stopProfilerLocked(null, null, 0); 13339 setProfileApp(proc.info, proc.processName, path, fd, false); 13340 mProfileProc = proc; 13341 mProfileType = profileType; 13342 try { 13343 fd = fd.dup(); 13344 } catch (IOException e) { 13345 fd = null; 13346 } 13347 proc.thread.profilerControl(start, path, fd, profileType); 13348 fd = null; 13349 mProfileFd = null; 13350 } else { 13351 stopProfilerLocked(proc, path, profileType); 13352 if (fd != null) { 13353 try { 13354 fd.close(); 13355 } catch (IOException e) { 13356 } 13357 } 13358 } 13359 13360 return true; 13361 } 13362 } catch (RemoteException e) { 13363 throw new IllegalStateException("Process disappeared"); 13364 } finally { 13365 if (fd != null) { 13366 try { 13367 fd.close(); 13368 } catch (IOException e) { 13369 } 13370 } 13371 } 13372 } 13373 13374 public boolean dumpHeap(String process, boolean managed, 13375 String path, ParcelFileDescriptor fd) throws RemoteException { 13376 13377 try { 13378 synchronized (this) { 13379 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13380 // its own permission (same as profileControl). 13381 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13382 != PackageManager.PERMISSION_GRANTED) { 13383 throw new SecurityException("Requires permission " 13384 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13385 } 13386 13387 if (fd == null) { 13388 throw new IllegalArgumentException("null fd"); 13389 } 13390 13391 ProcessRecord proc = null; 13392 try { 13393 int pid = Integer.parseInt(process); 13394 synchronized (mPidsSelfLocked) { 13395 proc = mPidsSelfLocked.get(pid); 13396 } 13397 } catch (NumberFormatException e) { 13398 } 13399 13400 if (proc == null) { 13401 HashMap<String, SparseArray<ProcessRecord>> all 13402 = mProcessNames.getMap(); 13403 SparseArray<ProcessRecord> procs = all.get(process); 13404 if (procs != null && procs.size() > 0) { 13405 proc = procs.valueAt(0); 13406 } 13407 } 13408 13409 if (proc == null || proc.thread == null) { 13410 throw new IllegalArgumentException("Unknown process: " + process); 13411 } 13412 13413 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13414 if (!isDebuggable) { 13415 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13416 throw new SecurityException("Process not debuggable: " + proc); 13417 } 13418 } 13419 13420 proc.thread.dumpHeap(managed, path, fd); 13421 fd = null; 13422 return true; 13423 } 13424 } catch (RemoteException e) { 13425 throw new IllegalStateException("Process disappeared"); 13426 } finally { 13427 if (fd != null) { 13428 try { 13429 fd.close(); 13430 } catch (IOException e) { 13431 } 13432 } 13433 } 13434 } 13435 13436 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13437 public void monitor() { 13438 synchronized (this) { } 13439 } 13440 13441 void onCoreSettingsChange(Bundle settings) { 13442 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13443 ProcessRecord processRecord = mLruProcesses.get(i); 13444 try { 13445 if (processRecord.thread != null) { 13446 processRecord.thread.setCoreSettings(settings); 13447 } 13448 } catch (RemoteException re) { 13449 /* ignore */ 13450 } 13451 } 13452 } 13453 13454 // Multi-user methods 13455 13456 public boolean switchUser(int userId) { 13457 final int callingUid = Binder.getCallingUid(); 13458 if (callingUid != 0 && callingUid != Process.myUid()) { 13459 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13460 return false; 13461 } 13462 if (mCurrentUserId == userId) 13463 return true; 13464 13465 synchronized (this) { 13466 // Check if user is already logged in, otherwise check if user exists first before 13467 // adding to the list of logged in users. 13468 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13469 if (!userExists(userId)) { 13470 return false; 13471 } 13472 mLoggedInUsers.append(userId, userId); 13473 } 13474 13475 mCurrentUserId = userId; 13476 boolean haveActivities = mMainStack.switchUser(userId); 13477 if (!haveActivities) { 13478 startHomeActivityLocked(userId); 13479 } 13480 13481 } 13482 13483 // Inform of user switch 13484 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13485 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 13486 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 13487 13488 return true; 13489 } 13490 13491 @Override 13492 public UserInfo getCurrentUser() throws RemoteException { 13493 final int callingUid = Binder.getCallingUid(); 13494 if (callingUid != 0 && callingUid != Process.myUid()) { 13495 Slog.e(TAG, "Trying to get user from unauthorized app"); 13496 return null; 13497 } 13498 return getUserManager().getUserInfo(mCurrentUserId); 13499 } 13500 13501 private void onUserRemoved(Intent intent) { 13502 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 13503 if (extraUserId < 1) return; 13504 13505 // Kill all the processes for the user 13506 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13507 synchronized (this) { 13508 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13509 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13510 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13511 for (int i = 0; i < uids.size(); i++) { 13512 if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) { 13513 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13514 } 13515 } 13516 } 13517 13518 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13519 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13520 false, false, true, true, extraUserId); 13521 } 13522 } 13523 } 13524 13525 private boolean userExists(int userId) { 13526 UserInfo user = getUserManager().getUserInfo(userId); 13527 return user != null; 13528 } 13529 13530 UserManager getUserManager() { 13531 if (mUserManager == null) { 13532 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13533 } 13534 return mUserManager; 13535 } 13536 13537 private void checkValidCaller(int uid, int userId) { 13538 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13539 13540 throw new SecurityException("Caller uid=" + uid 13541 + " is not privileged to communicate with user=" + userId); 13542 } 13543 13544 private int applyUserId(int uid, int userId) { 13545 return UserHandle.getUid(userId, uid); 13546 } 13547 13548 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13549 if (info == null) return null; 13550 ApplicationInfo newInfo = new ApplicationInfo(info); 13551 newInfo.uid = applyUserId(info.uid, userId); 13552 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13553 + info.packageName; 13554 return newInfo; 13555 } 13556 13557 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13558 if (aInfo == null 13559 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13560 return aInfo; 13561 } 13562 13563 ActivityInfo info = new ActivityInfo(aInfo); 13564 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13565 return info; 13566 } 13567} 13568