ActivityManagerService.java revision 5f7979993979466c79ab4f38d83c6f2aca361662
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.wm.WindowManagerService; 31 32import dalvik.system.Zygote; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityManagerNative; 37import android.app.ActivityOptions; 38import android.app.ActivityThread; 39import android.app.AlertDialog; 40import android.app.AppGlobals; 41import android.app.ApplicationErrorReport; 42import android.app.Dialog; 43import android.app.IActivityController; 44import android.app.IApplicationThread; 45import android.app.IInstrumentationWatcher; 46import android.app.INotificationManager; 47import android.app.IProcessObserver; 48import android.app.IServiceConnection; 49import android.app.IThumbnailReceiver; 50import android.app.Instrumentation; 51import android.app.Notification; 52import android.app.NotificationManager; 53import android.app.PendingIntent; 54import android.app.backup.IBackupManager; 55import android.content.ActivityNotFoundException; 56import android.content.BroadcastReceiver; 57import android.content.ClipData; 58import android.content.ComponentCallbacks2; 59import android.content.ComponentName; 60import android.content.ContentProvider; 61import android.content.ContentResolver; 62import android.content.Context; 63import android.content.DialogInterface; 64import android.content.IContentProvider; 65import android.content.IIntentReceiver; 66import android.content.IIntentSender; 67import android.content.Intent; 68import android.content.IntentFilter; 69import android.content.IntentSender; 70import android.content.pm.ActivityInfo; 71import android.content.pm.ApplicationInfo; 72import android.content.pm.ConfigurationInfo; 73import android.content.pm.IPackageDataObserver; 74import android.content.pm.IPackageManager; 75import android.content.pm.InstrumentationInfo; 76import android.content.pm.PackageInfo; 77import android.content.pm.PackageManager; 78import android.content.pm.UserInfo; 79import android.content.pm.PackageManager.NameNotFoundException; 80import android.content.pm.PathPermission; 81import android.content.pm.ProviderInfo; 82import android.content.pm.ResolveInfo; 83import android.content.pm.ServiceInfo; 84import android.content.res.CompatibilityInfo; 85import android.content.res.Configuration; 86import android.graphics.Bitmap; 87import android.net.Proxy; 88import android.net.ProxyProperties; 89import android.net.Uri; 90import android.os.Binder; 91import android.os.Build; 92import android.os.Bundle; 93import android.os.Debug; 94import android.os.DropBoxManager; 95import android.os.Environment; 96import android.os.FileObserver; 97import android.os.FileUtils; 98import android.os.Handler; 99import android.os.IBinder; 100import android.os.IPermissionController; 101import android.os.Looper; 102import android.os.Message; 103import android.os.Parcel; 104import android.os.ParcelFileDescriptor; 105import android.os.Process; 106import android.os.RemoteCallbackList; 107import android.os.RemoteException; 108import android.os.ServiceManager; 109import android.os.StrictMode; 110import android.os.SystemClock; 111import android.os.SystemProperties; 112import android.os.UserHandle; 113import android.os.UserManager; 114import android.provider.Settings; 115import android.text.format.Time; 116import android.util.EventLog; 117import android.util.LocaleUtil; 118import android.util.Log; 119import android.util.Pair; 120import android.util.PrintWriterPrinter; 121import android.util.Slog; 122import android.util.SparseArray; 123import android.util.SparseIntArray; 124import android.util.TimeUtils; 125import android.view.Gravity; 126import android.view.LayoutInflater; 127import android.view.View; 128import android.view.WindowManager; 129import android.view.WindowManagerPolicy; 130 131import java.io.BufferedInputStream; 132import java.io.BufferedOutputStream; 133import java.io.BufferedReader; 134import java.io.DataInputStream; 135import java.io.DataOutputStream; 136import java.io.File; 137import java.io.FileDescriptor; 138import java.io.FileInputStream; 139import java.io.FileNotFoundException; 140import java.io.FileOutputStream; 141import java.io.IOException; 142import java.io.InputStreamReader; 143import java.io.PrintWriter; 144import java.io.StringWriter; 145import java.lang.ref.WeakReference; 146import java.util.ArrayList; 147import java.util.Collections; 148import java.util.Comparator; 149import java.util.HashMap; 150import java.util.HashSet; 151import java.util.Iterator; 152import java.util.List; 153import java.util.Locale; 154import java.util.Map; 155import java.util.Map.Entry; 156import java.util.Set; 157import java.util.concurrent.atomic.AtomicBoolean; 158import java.util.concurrent.atomic.AtomicLong; 159 160public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 162 private static final String USER_DATA_DIR = "/data/user/"; 163 static final String TAG = "ActivityManager"; 164 static final String TAG_MU = "ActivityManagerServiceMU"; 165 static final boolean DEBUG = false; 166 static final boolean localLOGV = DEBUG; 167 static final boolean DEBUG_SWITCH = localLOGV || false; 168 static final boolean DEBUG_TASKS = localLOGV || false; 169 static final boolean DEBUG_PAUSE = localLOGV || false; 170 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 171 static final boolean DEBUG_TRANSITION = localLOGV || false; 172 static final boolean DEBUG_BROADCAST = localLOGV || false; 173 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_SERVICE = localLOGV || false; 176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 177 static final boolean DEBUG_VISBILITY = localLOGV || false; 178 static final boolean DEBUG_PROCESSES = localLOGV || false; 179 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 180 static final boolean DEBUG_PROVIDER = localLOGV || false; 181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 182 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 183 static final boolean DEBUG_RESULTS = localLOGV || false; 184 static final boolean DEBUG_BACKUP = localLOGV || false; 185 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 186 static final boolean DEBUG_POWER = localLOGV || false; 187 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 188 static final boolean DEBUG_MU = localLOGV || false; 189 static final boolean VALIDATE_TOKENS = false; 190 static final boolean SHOW_ACTIVITY_START_TIME = true; 191 192 // Control over CPU and battery monitoring. 193 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 194 static final boolean MONITOR_CPU_USAGE = true; 195 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 196 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 197 static final boolean MONITOR_THREAD_CPU_USAGE = false; 198 199 // The flags that are set for all calls we make to the package manager. 200 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 201 202 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 203 204 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 205 206 // Maximum number of recent tasks that we can remember. 207 static final int MAX_RECENT_TASKS = 20; 208 209 // Amount of time after a call to stopAppSwitches() during which we will 210 // prevent further untrusted switches from happening. 211 static final long APP_SWITCH_DELAY_TIME = 5*1000; 212 213 // How long we wait for a launched process to attach to the activity manager 214 // before we decide it's never going to come up for real. 215 static final int PROC_START_TIMEOUT = 10*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real, when the process was 219 // started with a wrapper for instrumentation (such as Valgrind) because it 220 // could take much longer than usual. 221 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 222 223 // How long to wait after going idle before forcing apps to GC. 224 static final int GC_TIMEOUT = 5*1000; 225 226 // The minimum amount of time between successive GC requests for a process. 227 static final int GC_MIN_INTERVAL = 60*1000; 228 229 // The rate at which we check for apps using excessive power -- 15 mins. 230 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 231 232 // The minimum sample duration we will allow before deciding we have 233 // enough data on wake locks to start killing things. 234 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on CPU usage to start killing things. 238 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // How long we allow a receiver to run before giving up on it. 241 static final int BROADCAST_FG_TIMEOUT = 10*1000; 242 static final int BROADCAST_BG_TIMEOUT = 60*1000; 243 244 // How long we wait until we timeout on key dispatching. 245 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 246 247 // How long we wait until we timeout on key dispatching during instrumentation. 248 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 249 250 static final int MY_PID = Process.myPid(); 251 252 static final String[] EMPTY_STRING_ARRAY = new String[0]; 253 254 public ActivityStack mMainStack; 255 256 private final boolean mHeadless; 257 258 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 259 // default actuion automatically. Important for devices without direct input 260 // devices. 261 private boolean mShowDialogs = true; 262 263 /** 264 * Description of a request to start a new activity, which has been held 265 * due to app switches being disabled. 266 */ 267 static class PendingActivityLaunch { 268 ActivityRecord r; 269 ActivityRecord sourceRecord; 270 int startFlags; 271 } 272 273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 274 = new ArrayList<PendingActivityLaunch>(); 275 276 277 BroadcastQueue mFgBroadcastQueue; 278 BroadcastQueue mBgBroadcastQueue; 279 // Convenient for easy iteration over the queues. Foreground is first 280 // so that dispatch of foreground broadcasts gets precedence. 281 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 282 283 BroadcastQueue broadcastQueueForIntent(Intent intent) { 284 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 285 if (DEBUG_BACKGROUND_BROADCAST) { 286 Slog.i(TAG, "Broadcast intent " + intent + " on " 287 + (isFg ? "foreground" : "background") 288 + " queue"); 289 } 290 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 291 } 292 293 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 294 for (BroadcastQueue queue : mBroadcastQueues) { 295 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 296 if (r != null) { 297 return r; 298 } 299 } 300 return null; 301 } 302 303 /** 304 * Activity we have told the window manager to have key focus. 305 */ 306 ActivityRecord mFocusedActivity = null; 307 /** 308 * List of intents that were used to start the most recent tasks. 309 */ 310 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 311 312 /** 313 * Process management. 314 */ 315 final ProcessList mProcessList = new ProcessList(); 316 317 /** 318 * All of the applications we currently have running organized by name. 319 * The keys are strings of the application package name (as 320 * returned by the package manager), and the keys are ApplicationRecord 321 * objects. 322 */ 323 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 324 325 /** 326 * The currently running isolated processes. 327 */ 328 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 329 330 /** 331 * Counter for assigning isolated process uids, to avoid frequently reusing the 332 * same ones. 333 */ 334 int mNextIsolatedProcessUid = 0; 335 336 /** 337 * The currently running heavy-weight process, if any. 338 */ 339 ProcessRecord mHeavyWeightProcess = null; 340 341 /** 342 * The last time that various processes have crashed. 343 */ 344 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 345 346 /** 347 * Set of applications that we consider to be bad, and will reject 348 * incoming broadcasts from (which the user has no control over). 349 * Processes are added to this set when they have crashed twice within 350 * a minimum amount of time; they are removed from it when they are 351 * later restarted (hopefully due to some user action). The value is the 352 * time it was added to the list. 353 */ 354 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 355 356 /** 357 * All of the processes we currently have running organized by pid. 358 * The keys are the pid running the application. 359 * 360 * <p>NOTE: This object is protected by its own lock, NOT the global 361 * activity manager lock! 362 */ 363 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 364 365 /** 366 * All of the processes that have been forced to be foreground. The key 367 * is the pid of the caller who requested it (we hold a death 368 * link on it). 369 */ 370 abstract class ForegroundToken implements IBinder.DeathRecipient { 371 int pid; 372 IBinder token; 373 } 374 final SparseArray<ForegroundToken> mForegroundProcesses 375 = new SparseArray<ForegroundToken>(); 376 377 /** 378 * List of records for processes that someone had tried to start before the 379 * system was ready. We don't start them at that point, but ensure they 380 * are started by the time booting is complete. 381 */ 382 final ArrayList<ProcessRecord> mProcessesOnHold 383 = new ArrayList<ProcessRecord>(); 384 385 /** 386 * List of persistent applications that are in the process 387 * of being started. 388 */ 389 final ArrayList<ProcessRecord> mPersistentStartingProcesses 390 = new ArrayList<ProcessRecord>(); 391 392 /** 393 * Processes that are being forcibly torn down. 394 */ 395 final ArrayList<ProcessRecord> mRemovedProcesses 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of running applications, sorted by recent usage. 400 * The first entry in the list is the least recently used. 401 * It contains ApplicationRecord objects. This list does NOT include 402 * any persistent application records (since we never want to exit them). 403 */ 404 final ArrayList<ProcessRecord> mLruProcesses 405 = new ArrayList<ProcessRecord>(); 406 407 /** 408 * List of processes that should gc as soon as things are idle. 409 */ 410 final ArrayList<ProcessRecord> mProcessesToGc 411 = new ArrayList<ProcessRecord>(); 412 413 /** 414 * This is the process holding what we currently consider to be 415 * the "home" activity. 416 */ 417 ProcessRecord mHomeProcess; 418 419 /** 420 * This is the process holding the activity the user last visited that 421 * is in a different process from the one they are currently in. 422 */ 423 ProcessRecord mPreviousProcess; 424 425 /** 426 * The time at which the previous process was last visible. 427 */ 428 long mPreviousProcessVisibleTime; 429 430 /** 431 * Packages that the user has asked to have run in screen size 432 * compatibility mode instead of filling the screen. 433 */ 434 final CompatModePackages mCompatModePackages; 435 436 /** 437 * Set of PendingResultRecord objects that are currently active. 438 */ 439 final HashSet mPendingResultRecords = new HashSet(); 440 441 /** 442 * Set of IntentSenderRecord objects that are currently active. 443 */ 444 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 445 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 446 447 /** 448 * Fingerprints (hashCode()) of stack traces that we've 449 * already logged DropBox entries for. Guarded by itself. If 450 * something (rogue user app) forces this over 451 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 452 */ 453 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 454 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 455 456 /** 457 * Strict Mode background batched logging state. 458 * 459 * The string buffer is guarded by itself, and its lock is also 460 * used to determine if another batched write is already 461 * in-flight. 462 */ 463 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 464 465 /** 466 * Keeps track of all IIntentReceivers that have been registered for 467 * broadcasts. Hash keys are the receiver IBinder, hash value is 468 * a ReceiverList. 469 */ 470 final HashMap mRegisteredReceivers = new HashMap(); 471 472 /** 473 * Resolver for broadcast intents to registered receivers. 474 * Holds BroadcastFilter (subclass of IntentFilter). 475 */ 476 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 477 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 478 @Override 479 protected boolean allowFilterResult( 480 BroadcastFilter filter, List<BroadcastFilter> dest) { 481 IBinder target = filter.receiverList.receiver.asBinder(); 482 for (int i=dest.size()-1; i>=0; i--) { 483 if (dest.get(i).receiverList.receiver.asBinder() == target) { 484 return false; 485 } 486 } 487 return true; 488 } 489 490 @Override 491 protected BroadcastFilter[] newArray(int size) { 492 return new BroadcastFilter[size]; 493 } 494 495 @Override 496 protected String packageForFilter(BroadcastFilter filter) { 497 return filter.packageName; 498 } 499 }; 500 501 /** 502 * State of all active sticky broadcasts. Keys are the action of the 503 * sticky Intent, values are an ArrayList of all broadcasted intents with 504 * that action (which should usually be one). 505 */ 506 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 507 new HashMap<String, ArrayList<Intent>>(); 508 509 final ActiveServices mServices; 510 511 /** 512 * Backup/restore process management 513 */ 514 String mBackupAppName = null; 515 BackupRecord mBackupTarget = null; 516 517 /** 518 * List of PendingThumbnailsRecord objects of clients who are still 519 * waiting to receive all of the thumbnails for a task. 520 */ 521 final ArrayList mPendingThumbnails = new ArrayList(); 522 523 /** 524 * List of HistoryRecord objects that have been finished and must 525 * still report back to a pending thumbnail receiver. 526 */ 527 final ArrayList mCancelledThumbnails = new ArrayList(); 528 529 final ProviderMap mProviderMap = new ProviderMap(); 530 531 /** 532 * List of content providers who have clients waiting for them. The 533 * application is currently being launched and the provider will be 534 * removed from this list once it is published. 535 */ 536 final ArrayList<ContentProviderRecord> mLaunchingProviders 537 = new ArrayList<ContentProviderRecord>(); 538 539 /** 540 * Global set of specific Uri permissions that have been granted. 541 */ 542 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 543 = new SparseArray<HashMap<Uri, UriPermission>>(); 544 545 CoreSettingsObserver mCoreSettingsObserver; 546 547 /** 548 * Thread-local storage used to carry caller permissions over through 549 * indirect content-provider access. 550 * @see #ActivityManagerService.openContentUri() 551 */ 552 private class Identity { 553 public int pid; 554 public int uid; 555 556 Identity(int _pid, int _uid) { 557 pid = _pid; 558 uid = _uid; 559 } 560 } 561 562 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 563 564 /** 565 * All information we have collected about the runtime performance of 566 * any user id that can impact battery performance. 567 */ 568 final BatteryStatsService mBatteryStatsService; 569 570 /** 571 * information about component usage 572 */ 573 final UsageStatsService mUsageStatsService; 574 575 /** 576 * Current configuration information. HistoryRecord objects are given 577 * a reference to this object to indicate which configuration they are 578 * currently running in, so this object must be kept immutable. 579 */ 580 Configuration mConfiguration = new Configuration(); 581 582 /** 583 * Current sequencing integer of the configuration, for skipping old 584 * configurations. 585 */ 586 int mConfigurationSeq = 0; 587 588 /** 589 * Hardware-reported OpenGLES version. 590 */ 591 final int GL_ES_VERSION; 592 593 /** 594 * List of initialization arguments to pass to all processes when binding applications to them. 595 * For example, references to the commonly used services. 596 */ 597 HashMap<String, IBinder> mAppBindArgs; 598 599 /** 600 * Temporary to avoid allocations. Protected by main lock. 601 */ 602 final StringBuilder mStringBuilder = new StringBuilder(256); 603 604 /** 605 * Used to control how we initialize the service. 606 */ 607 boolean mStartRunning = false; 608 ComponentName mTopComponent; 609 String mTopAction; 610 String mTopData; 611 boolean mProcessesReady = false; 612 boolean mSystemReady = false; 613 boolean mBooting = false; 614 boolean mWaitingUpdate = false; 615 boolean mDidUpdate = false; 616 boolean mOnBattery = false; 617 boolean mLaunchWarningShown = false; 618 619 Context mContext; 620 621 int mFactoryTest; 622 623 boolean mCheckedForSetup; 624 625 /** 626 * The time at which we will allow normal application switches again, 627 * after a call to {@link #stopAppSwitches()}. 628 */ 629 long mAppSwitchesAllowedTime; 630 631 /** 632 * This is set to true after the first switch after mAppSwitchesAllowedTime 633 * is set; any switches after that will clear the time. 634 */ 635 boolean mDidAppSwitch; 636 637 /** 638 * Last time (in realtime) at which we checked for power usage. 639 */ 640 long mLastPowerCheckRealtime; 641 642 /** 643 * Last time (in uptime) at which we checked for power usage. 644 */ 645 long mLastPowerCheckUptime; 646 647 /** 648 * Set while we are wanting to sleep, to prevent any 649 * activities from being started/resumed. 650 */ 651 boolean mSleeping = false; 652 653 /** 654 * State of external calls telling us if the device is asleep. 655 */ 656 boolean mWentToSleep = false; 657 658 /** 659 * State of external call telling us if the lock screen is shown. 660 */ 661 boolean mLockScreenShown = false; 662 663 /** 664 * Set if we are shutting down the system, similar to sleeping. 665 */ 666 boolean mShuttingDown = false; 667 668 /** 669 * Task identifier that activities are currently being started 670 * in. Incremented each time a new task is created. 671 * todo: Replace this with a TokenSpace class that generates non-repeating 672 * integers that won't wrap. 673 */ 674 int mCurTask = 1; 675 676 /** 677 * Current sequence id for oom_adj computation traversal. 678 */ 679 int mAdjSeq = 0; 680 681 /** 682 * Current sequence id for process LRU updating. 683 */ 684 int mLruSeq = 0; 685 686 /** 687 * Keep track of the non-hidden/empty process we last found, to help 688 * determine how to distribute hidden/empty processes next time. 689 */ 690 int mNumNonHiddenProcs = 0; 691 692 /** 693 * Keep track of the number of hidden procs, to balance oom adj 694 * distribution between those and empty procs. 695 */ 696 int mNumHiddenProcs = 0; 697 698 /** 699 * Keep track of the number of service processes we last found, to 700 * determine on the next iteration which should be B services. 701 */ 702 int mNumServiceProcs = 0; 703 int mNewNumServiceProcs = 0; 704 705 /** 706 * System monitoring: number of processes that died since the last 707 * N procs were started. 708 */ 709 int[] mProcDeaths = new int[20]; 710 711 /** 712 * This is set if we had to do a delayed dexopt of an app before launching 713 * it, to increasing the ANR timeouts in that case. 714 */ 715 boolean mDidDexOpt; 716 717 String mDebugApp = null; 718 boolean mWaitForDebugger = false; 719 boolean mDebugTransient = false; 720 String mOrigDebugApp = null; 721 boolean mOrigWaitForDebugger = false; 722 boolean mAlwaysFinishActivities = false; 723 IActivityController mController = null; 724 String mProfileApp = null; 725 ProcessRecord mProfileProc = null; 726 String mProfileFile; 727 ParcelFileDescriptor mProfileFd; 728 int mProfileType = 0; 729 boolean mAutoStopProfiler = false; 730 String mOpenGlTraceApp = null; 731 732 static class ProcessChangeItem { 733 static final int CHANGE_ACTIVITIES = 1<<0; 734 static final int CHANGE_IMPORTANCE= 1<<1; 735 int changes; 736 int uid; 737 int pid; 738 int importance; 739 boolean foregroundActivities; 740 } 741 742 final RemoteCallbackList<IProcessObserver> mProcessObservers 743 = new RemoteCallbackList<IProcessObserver>(); 744 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 745 746 final ArrayList<ProcessChangeItem> mPendingProcessChanges 747 = new ArrayList<ProcessChangeItem>(); 748 final ArrayList<ProcessChangeItem> mAvailProcessChanges 749 = new ArrayList<ProcessChangeItem>(); 750 751 /** 752 * Callback of last caller to {@link #requestPss}. 753 */ 754 Runnable mRequestPssCallback; 755 756 /** 757 * Remaining processes for which we are waiting results from the last 758 * call to {@link #requestPss}. 759 */ 760 final ArrayList<ProcessRecord> mRequestPssList 761 = new ArrayList<ProcessRecord>(); 762 763 /** 764 * Runtime statistics collection thread. This object's lock is used to 765 * protect all related state. 766 */ 767 final Thread mProcessStatsThread; 768 769 /** 770 * Used to collect process stats when showing not responding dialog. 771 * Protected by mProcessStatsThread. 772 */ 773 final ProcessStats mProcessStats = new ProcessStats( 774 MONITOR_THREAD_CPU_USAGE); 775 final AtomicLong mLastCpuTime = new AtomicLong(0); 776 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 777 778 long mLastWriteTime = 0; 779 780 /** 781 * Set to true after the system has finished booting. 782 */ 783 boolean mBooted = false; 784 785 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 786 int mProcessLimitOverride = -1; 787 788 WindowManagerService mWindowManager; 789 790 static ActivityManagerService mSelf; 791 static ActivityThread mSystemThread; 792 793 private int mCurrentUserId; 794 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 795 private UserManager mUserManager; 796 797 private final class AppDeathRecipient implements IBinder.DeathRecipient { 798 final ProcessRecord mApp; 799 final int mPid; 800 final IApplicationThread mAppThread; 801 802 AppDeathRecipient(ProcessRecord app, int pid, 803 IApplicationThread thread) { 804 if (localLOGV) Slog.v( 805 TAG, "New death recipient " + this 806 + " for thread " + thread.asBinder()); 807 mApp = app; 808 mPid = pid; 809 mAppThread = thread; 810 } 811 812 public void binderDied() { 813 if (localLOGV) Slog.v( 814 TAG, "Death received in " + this 815 + " for thread " + mAppThread.asBinder()); 816 synchronized(ActivityManagerService.this) { 817 appDiedLocked(mApp, mPid, mAppThread); 818 } 819 } 820 } 821 822 static final int SHOW_ERROR_MSG = 1; 823 static final int SHOW_NOT_RESPONDING_MSG = 2; 824 static final int SHOW_FACTORY_ERROR_MSG = 3; 825 static final int UPDATE_CONFIGURATION_MSG = 4; 826 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 827 static final int WAIT_FOR_DEBUGGER_MSG = 6; 828 static final int SERVICE_TIMEOUT_MSG = 12; 829 static final int UPDATE_TIME_ZONE = 13; 830 static final int SHOW_UID_ERROR_MSG = 14; 831 static final int IM_FEELING_LUCKY_MSG = 15; 832 static final int PROC_START_TIMEOUT_MSG = 20; 833 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 834 static final int KILL_APPLICATION_MSG = 22; 835 static final int FINALIZE_PENDING_INTENT_MSG = 23; 836 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 837 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 838 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 839 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 840 static final int CLEAR_DNS_CACHE = 28; 841 static final int UPDATE_HTTP_PROXY = 29; 842 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 843 static final int DISPATCH_PROCESSES_CHANGED = 31; 844 static final int DISPATCH_PROCESS_DIED = 32; 845 static final int REPORT_MEM_USAGE = 33; 846 847 static final int FIRST_ACTIVITY_STACK_MSG = 100; 848 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 849 static final int FIRST_COMPAT_MODE_MSG = 300; 850 851 AlertDialog mUidAlert; 852 CompatModeDialog mCompatModeDialog; 853 long mLastMemUsageReportTime = 0; 854 855 final Handler mHandler = new Handler() { 856 //public Handler() { 857 // if (localLOGV) Slog.v(TAG, "Handler started!"); 858 //} 859 860 public void handleMessage(Message msg) { 861 switch (msg.what) { 862 case SHOW_ERROR_MSG: { 863 HashMap data = (HashMap) msg.obj; 864 synchronized (ActivityManagerService.this) { 865 ProcessRecord proc = (ProcessRecord)data.get("app"); 866 if (proc != null && proc.crashDialog != null) { 867 Slog.e(TAG, "App already has crash dialog: " + proc); 868 return; 869 } 870 AppErrorResult res = (AppErrorResult) data.get("result"); 871 if (mShowDialogs && !mSleeping && !mShuttingDown) { 872 Dialog d = new AppErrorDialog(mContext, res, proc); 873 d.show(); 874 proc.crashDialog = d; 875 } else { 876 // The device is asleep, so just pretend that the user 877 // saw a crash dialog and hit "force quit". 878 res.set(0); 879 } 880 } 881 882 ensureBootCompleted(); 883 } break; 884 case SHOW_NOT_RESPONDING_MSG: { 885 synchronized (ActivityManagerService.this) { 886 HashMap data = (HashMap) msg.obj; 887 ProcessRecord proc = (ProcessRecord)data.get("app"); 888 if (proc != null && proc.anrDialog != null) { 889 Slog.e(TAG, "App already has anr dialog: " + proc); 890 return; 891 } 892 893 Intent intent = new Intent("android.intent.action.ANR"); 894 if (!mProcessesReady) { 895 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 896 | Intent.FLAG_RECEIVER_FOREGROUND); 897 } 898 broadcastIntentLocked(null, null, intent, 899 null, null, 0, null, null, null, 900 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 901 902 if (mShowDialogs) { 903 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 904 mContext, proc, (ActivityRecord)data.get("activity")); 905 d.show(); 906 proc.anrDialog = d; 907 } else { 908 // Just kill the app if there is no dialog to be shown. 909 killAppAtUsersRequest(proc, null); 910 } 911 } 912 913 ensureBootCompleted(); 914 } break; 915 case SHOW_STRICT_MODE_VIOLATION_MSG: { 916 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 917 synchronized (ActivityManagerService.this) { 918 ProcessRecord proc = (ProcessRecord) data.get("app"); 919 if (proc == null) { 920 Slog.e(TAG, "App not found when showing strict mode dialog."); 921 break; 922 } 923 if (proc.crashDialog != null) { 924 Slog.e(TAG, "App already has strict mode dialog: " + proc); 925 return; 926 } 927 AppErrorResult res = (AppErrorResult) data.get("result"); 928 if (mShowDialogs && !mSleeping && !mShuttingDown) { 929 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 930 d.show(); 931 proc.crashDialog = d; 932 } else { 933 // The device is asleep, so just pretend that the user 934 // saw a crash dialog and hit "force quit". 935 res.set(0); 936 } 937 } 938 ensureBootCompleted(); 939 } break; 940 case SHOW_FACTORY_ERROR_MSG: { 941 Dialog d = new FactoryErrorDialog( 942 mContext, msg.getData().getCharSequence("msg")); 943 d.show(); 944 ensureBootCompleted(); 945 } break; 946 case UPDATE_CONFIGURATION_MSG: { 947 final ContentResolver resolver = mContext.getContentResolver(); 948 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 949 } break; 950 case GC_BACKGROUND_PROCESSES_MSG: { 951 synchronized (ActivityManagerService.this) { 952 performAppGcsIfAppropriateLocked(); 953 } 954 } break; 955 case WAIT_FOR_DEBUGGER_MSG: { 956 synchronized (ActivityManagerService.this) { 957 ProcessRecord app = (ProcessRecord)msg.obj; 958 if (msg.arg1 != 0) { 959 if (!app.waitedForDebugger) { 960 Dialog d = new AppWaitingForDebuggerDialog( 961 ActivityManagerService.this, 962 mContext, app); 963 app.waitDialog = d; 964 app.waitedForDebugger = true; 965 d.show(); 966 } 967 } else { 968 if (app.waitDialog != null) { 969 app.waitDialog.dismiss(); 970 app.waitDialog = null; 971 } 972 } 973 } 974 } break; 975 case SERVICE_TIMEOUT_MSG: { 976 if (mDidDexOpt) { 977 mDidDexOpt = false; 978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 979 nmsg.obj = msg.obj; 980 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 981 return; 982 } 983 mServices.serviceTimeout((ProcessRecord)msg.obj); 984 } break; 985 case UPDATE_TIME_ZONE: { 986 synchronized (ActivityManagerService.this) { 987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 988 ProcessRecord r = mLruProcesses.get(i); 989 if (r.thread != null) { 990 try { 991 r.thread.updateTimeZone(); 992 } catch (RemoteException ex) { 993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 994 } 995 } 996 } 997 } 998 } break; 999 case CLEAR_DNS_CACHE: { 1000 synchronized (ActivityManagerService.this) { 1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1002 ProcessRecord r = mLruProcesses.get(i); 1003 if (r.thread != null) { 1004 try { 1005 r.thread.clearDnsCache(); 1006 } catch (RemoteException ex) { 1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1008 } 1009 } 1010 } 1011 } 1012 } break; 1013 case UPDATE_HTTP_PROXY: { 1014 ProxyProperties proxy = (ProxyProperties)msg.obj; 1015 String host = ""; 1016 String port = ""; 1017 String exclList = ""; 1018 if (proxy != null) { 1019 host = proxy.getHost(); 1020 port = Integer.toString(proxy.getPort()); 1021 exclList = proxy.getExclusionList(); 1022 } 1023 synchronized (ActivityManagerService.this) { 1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1025 ProcessRecord r = mLruProcesses.get(i); 1026 if (r.thread != null) { 1027 try { 1028 r.thread.setHttpProxy(host, port, exclList); 1029 } catch (RemoteException ex) { 1030 Slog.w(TAG, "Failed to update http proxy for: " + 1031 r.info.processName); 1032 } 1033 } 1034 } 1035 } 1036 } break; 1037 case SHOW_UID_ERROR_MSG: { 1038 String title = "System UIDs Inconsistent"; 1039 String text = "UIDs on the system are inconsistent, you need to wipe your" 1040 + " data partition or your device will be unstable."; 1041 Log.e(TAG, title + ": " + text); 1042 if (mShowDialogs) { 1043 // XXX This is a temporary dialog, no need to localize. 1044 AlertDialog d = new BaseErrorDialog(mContext); 1045 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1046 d.setCancelable(false); 1047 d.setTitle(title); 1048 d.setMessage(text); 1049 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1050 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1051 mUidAlert = d; 1052 d.show(); 1053 } 1054 } break; 1055 case IM_FEELING_LUCKY_MSG: { 1056 if (mUidAlert != null) { 1057 mUidAlert.dismiss(); 1058 mUidAlert = null; 1059 } 1060 } break; 1061 case PROC_START_TIMEOUT_MSG: { 1062 if (mDidDexOpt) { 1063 mDidDexOpt = false; 1064 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1065 nmsg.obj = msg.obj; 1066 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1067 return; 1068 } 1069 ProcessRecord app = (ProcessRecord)msg.obj; 1070 synchronized (ActivityManagerService.this) { 1071 processStartTimedOutLocked(app); 1072 } 1073 } break; 1074 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1075 synchronized (ActivityManagerService.this) { 1076 doPendingActivityLaunchesLocked(true); 1077 } 1078 } break; 1079 case KILL_APPLICATION_MSG: { 1080 synchronized (ActivityManagerService.this) { 1081 int uid = msg.arg1; 1082 boolean restart = (msg.arg2 == 1); 1083 String pkg = (String) msg.obj; 1084 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1085 UserHandle.getUserId(uid)); 1086 } 1087 } break; 1088 case FINALIZE_PENDING_INTENT_MSG: { 1089 ((PendingIntentRecord)msg.obj).completeFinalize(); 1090 } break; 1091 case POST_HEAVY_NOTIFICATION_MSG: { 1092 INotificationManager inm = NotificationManager.getService(); 1093 if (inm == null) { 1094 return; 1095 } 1096 1097 ActivityRecord root = (ActivityRecord)msg.obj; 1098 ProcessRecord process = root.app; 1099 if (process == null) { 1100 return; 1101 } 1102 1103 try { 1104 Context context = mContext.createPackageContext(process.info.packageName, 0); 1105 String text = mContext.getString(R.string.heavy_weight_notification, 1106 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1107 Notification notification = new Notification(); 1108 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1109 notification.when = 0; 1110 notification.flags = Notification.FLAG_ONGOING_EVENT; 1111 notification.tickerText = text; 1112 notification.defaults = 0; // please be quiet 1113 notification.sound = null; 1114 notification.vibrate = null; 1115 notification.setLatestEventInfo(context, text, 1116 mContext.getText(R.string.heavy_weight_notification_detail), 1117 PendingIntent.getActivity(mContext, 0, root.intent, 1118 PendingIntent.FLAG_CANCEL_CURRENT)); 1119 1120 try { 1121 int[] outId = new int[1]; 1122 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1123 notification, outId); 1124 } catch (RuntimeException e) { 1125 Slog.w(ActivityManagerService.TAG, 1126 "Error showing notification for heavy-weight app", e); 1127 } catch (RemoteException e) { 1128 } 1129 } catch (NameNotFoundException e) { 1130 Slog.w(TAG, "Unable to create context for heavy notification", e); 1131 } 1132 } break; 1133 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1134 INotificationManager inm = NotificationManager.getService(); 1135 if (inm == null) { 1136 return; 1137 } 1138 try { 1139 inm.cancelNotification("android", 1140 R.string.heavy_weight_notification); 1141 } catch (RuntimeException e) { 1142 Slog.w(ActivityManagerService.TAG, 1143 "Error canceling notification for service", e); 1144 } catch (RemoteException e) { 1145 } 1146 } break; 1147 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1148 synchronized (ActivityManagerService.this) { 1149 checkExcessivePowerUsageLocked(true); 1150 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1151 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1152 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1153 } 1154 } break; 1155 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1156 synchronized (ActivityManagerService.this) { 1157 ActivityRecord ar = (ActivityRecord)msg.obj; 1158 if (mCompatModeDialog != null) { 1159 if (mCompatModeDialog.mAppInfo.packageName.equals( 1160 ar.info.applicationInfo.packageName)) { 1161 return; 1162 } 1163 mCompatModeDialog.dismiss(); 1164 mCompatModeDialog = null; 1165 } 1166 if (ar != null && false) { 1167 if (mCompatModePackages.getPackageAskCompatModeLocked( 1168 ar.packageName)) { 1169 int mode = mCompatModePackages.computeCompatModeLocked( 1170 ar.info.applicationInfo); 1171 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1172 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1173 mCompatModeDialog = new CompatModeDialog( 1174 ActivityManagerService.this, mContext, 1175 ar.info.applicationInfo); 1176 mCompatModeDialog.show(); 1177 } 1178 } 1179 } 1180 } 1181 break; 1182 } 1183 case DISPATCH_PROCESSES_CHANGED: { 1184 dispatchProcessesChanged(); 1185 break; 1186 } 1187 case DISPATCH_PROCESS_DIED: { 1188 final int pid = msg.arg1; 1189 final int uid = msg.arg2; 1190 dispatchProcessDied(pid, uid); 1191 break; 1192 } 1193 case REPORT_MEM_USAGE: { 1194 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1195 if (!isDebuggable) { 1196 return; 1197 } 1198 synchronized (ActivityManagerService.this) { 1199 long now = SystemClock.uptimeMillis(); 1200 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1201 // Don't report more than every 5 minutes to somewhat 1202 // avoid spamming. 1203 return; 1204 } 1205 mLastMemUsageReportTime = now; 1206 } 1207 Thread thread = new Thread() { 1208 @Override public void run() { 1209 StringBuilder dropBuilder = new StringBuilder(1024); 1210 StringBuilder logBuilder = new StringBuilder(1024); 1211 StringWriter oomSw = new StringWriter(); 1212 PrintWriter oomPw = new PrintWriter(oomSw); 1213 StringWriter catSw = new StringWriter(); 1214 PrintWriter catPw = new PrintWriter(catSw); 1215 String[] emptyArgs = new String[] { }; 1216 StringBuilder tag = new StringBuilder(128); 1217 StringBuilder stack = new StringBuilder(128); 1218 tag.append("Low on memory -- "); 1219 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1220 tag, stack); 1221 dropBuilder.append(stack); 1222 dropBuilder.append('\n'); 1223 dropBuilder.append('\n'); 1224 String oomString = oomSw.toString(); 1225 dropBuilder.append(oomString); 1226 dropBuilder.append('\n'); 1227 logBuilder.append(oomString); 1228 try { 1229 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1230 "procrank", }); 1231 final InputStreamReader converter = new InputStreamReader( 1232 proc.getInputStream()); 1233 BufferedReader in = new BufferedReader(converter); 1234 String line; 1235 while (true) { 1236 line = in.readLine(); 1237 if (line == null) { 1238 break; 1239 } 1240 if (line.length() > 0) { 1241 logBuilder.append(line); 1242 logBuilder.append('\n'); 1243 } 1244 dropBuilder.append(line); 1245 dropBuilder.append('\n'); 1246 } 1247 converter.close(); 1248 } catch (IOException e) { 1249 } 1250 synchronized (ActivityManagerService.this) { 1251 catPw.println(); 1252 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1253 catPw.println(); 1254 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1255 false, false, null); 1256 catPw.println(); 1257 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1258 } 1259 dropBuilder.append(catSw.toString()); 1260 addErrorToDropBox("lowmem", null, "system_server", null, 1261 null, tag.toString(), dropBuilder.toString(), null, null); 1262 Slog.i(TAG, logBuilder.toString()); 1263 synchronized (ActivityManagerService.this) { 1264 long now = SystemClock.uptimeMillis(); 1265 if (mLastMemUsageReportTime < now) { 1266 mLastMemUsageReportTime = now; 1267 } 1268 } 1269 } 1270 }; 1271 thread.start(); 1272 break; 1273 } 1274 } 1275 } 1276 }; 1277 1278 public static void setSystemProcess() { 1279 try { 1280 ActivityManagerService m = mSelf; 1281 1282 ServiceManager.addService("activity", m, true); 1283 ServiceManager.addService("meminfo", new MemBinder(m)); 1284 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1285 ServiceManager.addService("dbinfo", new DbBinder(m)); 1286 if (MONITOR_CPU_USAGE) { 1287 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1288 } 1289 ServiceManager.addService("permission", new PermissionController(m)); 1290 1291 ApplicationInfo info = 1292 mSelf.mContext.getPackageManager().getApplicationInfo( 1293 "android", STOCK_PM_FLAGS); 1294 mSystemThread.installSystemApplicationInfo(info); 1295 1296 synchronized (mSelf) { 1297 ProcessRecord app = mSelf.newProcessRecordLocked( 1298 mSystemThread.getApplicationThread(), info, 1299 info.processName, false); 1300 app.persistent = true; 1301 app.pid = MY_PID; 1302 app.maxAdj = ProcessList.SYSTEM_ADJ; 1303 mSelf.mProcessNames.put(app.processName, app.uid, app); 1304 synchronized (mSelf.mPidsSelfLocked) { 1305 mSelf.mPidsSelfLocked.put(app.pid, app); 1306 } 1307 mSelf.updateLruProcessLocked(app, true, true); 1308 } 1309 } catch (PackageManager.NameNotFoundException e) { 1310 throw new RuntimeException( 1311 "Unable to find android system package", e); 1312 } 1313 } 1314 1315 public void setWindowManager(WindowManagerService wm) { 1316 mWindowManager = wm; 1317 } 1318 1319 public static final Context main(int factoryTest) { 1320 AThread thr = new AThread(); 1321 thr.start(); 1322 1323 synchronized (thr) { 1324 while (thr.mService == null) { 1325 try { 1326 thr.wait(); 1327 } catch (InterruptedException e) { 1328 } 1329 } 1330 } 1331 1332 ActivityManagerService m = thr.mService; 1333 mSelf = m; 1334 ActivityThread at = ActivityThread.systemMain(); 1335 mSystemThread = at; 1336 Context context = at.getSystemContext(); 1337 context.setTheme(android.R.style.Theme_Holo); 1338 m.mContext = context; 1339 m.mFactoryTest = factoryTest; 1340 m.mMainStack = new ActivityStack(m, context, true); 1341 1342 m.mBatteryStatsService.publish(context); 1343 m.mUsageStatsService.publish(context); 1344 1345 synchronized (thr) { 1346 thr.mReady = true; 1347 thr.notifyAll(); 1348 } 1349 1350 m.startRunning(null, null, null, null); 1351 1352 return context; 1353 } 1354 1355 public static ActivityManagerService self() { 1356 return mSelf; 1357 } 1358 1359 static class AThread extends Thread { 1360 ActivityManagerService mService; 1361 boolean mReady = false; 1362 1363 public AThread() { 1364 super("ActivityManager"); 1365 } 1366 1367 public void run() { 1368 Looper.prepare(); 1369 1370 android.os.Process.setThreadPriority( 1371 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1372 android.os.Process.setCanSelfBackground(false); 1373 1374 ActivityManagerService m = new ActivityManagerService(); 1375 1376 synchronized (this) { 1377 mService = m; 1378 notifyAll(); 1379 } 1380 1381 synchronized (this) { 1382 while (!mReady) { 1383 try { 1384 wait(); 1385 } catch (InterruptedException e) { 1386 } 1387 } 1388 } 1389 1390 // For debug builds, log event loop stalls to dropbox for analysis. 1391 if (StrictMode.conditionallyEnableDebugLogging()) { 1392 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1393 } 1394 1395 Looper.loop(); 1396 } 1397 } 1398 1399 static class MemBinder extends Binder { 1400 ActivityManagerService mActivityManagerService; 1401 MemBinder(ActivityManagerService activityManagerService) { 1402 mActivityManagerService = activityManagerService; 1403 } 1404 1405 @Override 1406 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1407 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1408 != PackageManager.PERMISSION_GRANTED) { 1409 pw.println("Permission Denial: can't dump meminfo from from pid=" 1410 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1411 + " without permission " + android.Manifest.permission.DUMP); 1412 return; 1413 } 1414 1415 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1416 false, null, null, null); 1417 } 1418 } 1419 1420 static class GraphicsBinder extends Binder { 1421 ActivityManagerService mActivityManagerService; 1422 GraphicsBinder(ActivityManagerService activityManagerService) { 1423 mActivityManagerService = activityManagerService; 1424 } 1425 1426 @Override 1427 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1428 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1429 != PackageManager.PERMISSION_GRANTED) { 1430 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1431 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1432 + " without permission " + android.Manifest.permission.DUMP); 1433 return; 1434 } 1435 1436 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1437 } 1438 } 1439 1440 static class DbBinder extends Binder { 1441 ActivityManagerService mActivityManagerService; 1442 DbBinder(ActivityManagerService activityManagerService) { 1443 mActivityManagerService = activityManagerService; 1444 } 1445 1446 @Override 1447 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1448 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1449 != PackageManager.PERMISSION_GRANTED) { 1450 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1451 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1452 + " without permission " + android.Manifest.permission.DUMP); 1453 return; 1454 } 1455 1456 mActivityManagerService.dumpDbInfo(fd, pw, args); 1457 } 1458 } 1459 1460 static class CpuBinder extends Binder { 1461 ActivityManagerService mActivityManagerService; 1462 CpuBinder(ActivityManagerService activityManagerService) { 1463 mActivityManagerService = activityManagerService; 1464 } 1465 1466 @Override 1467 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1468 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1469 != PackageManager.PERMISSION_GRANTED) { 1470 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1471 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1472 + " without permission " + android.Manifest.permission.DUMP); 1473 return; 1474 } 1475 1476 synchronized (mActivityManagerService.mProcessStatsThread) { 1477 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1478 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1479 SystemClock.uptimeMillis())); 1480 } 1481 } 1482 } 1483 1484 private ActivityManagerService() { 1485 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1486 1487 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1488 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1489 mBroadcastQueues[0] = mFgBroadcastQueue; 1490 mBroadcastQueues[1] = mBgBroadcastQueue; 1491 1492 mServices = new ActiveServices(this); 1493 1494 File dataDir = Environment.getDataDirectory(); 1495 File systemDir = new File(dataDir, "system"); 1496 systemDir.mkdirs(); 1497 mBatteryStatsService = new BatteryStatsService(new File( 1498 systemDir, "batterystats.bin").toString()); 1499 mBatteryStatsService.getActiveStatistics().readLocked(); 1500 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1501 mOnBattery = DEBUG_POWER ? true 1502 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1503 mBatteryStatsService.getActiveStatistics().setCallback(this); 1504 1505 mUsageStatsService = new UsageStatsService(new File( 1506 systemDir, "usagestats").toString()); 1507 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1508 1509 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1510 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1511 1512 mConfiguration.setToDefaults(); 1513 mConfiguration.setLocale(Locale.getDefault()); 1514 1515 mConfigurationSeq = mConfiguration.seq = 1; 1516 mProcessStats.init(); 1517 1518 mCompatModePackages = new CompatModePackages(this, systemDir); 1519 1520 // Add ourself to the Watchdog monitors. 1521 Watchdog.getInstance().addMonitor(this); 1522 1523 mProcessStatsThread = new Thread("ProcessStats") { 1524 public void run() { 1525 while (true) { 1526 try { 1527 try { 1528 synchronized(this) { 1529 final long now = SystemClock.uptimeMillis(); 1530 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1531 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1532 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1533 // + ", write delay=" + nextWriteDelay); 1534 if (nextWriteDelay < nextCpuDelay) { 1535 nextCpuDelay = nextWriteDelay; 1536 } 1537 if (nextCpuDelay > 0) { 1538 mProcessStatsMutexFree.set(true); 1539 this.wait(nextCpuDelay); 1540 } 1541 } 1542 } catch (InterruptedException e) { 1543 } 1544 updateCpuStatsNow(); 1545 } catch (Exception e) { 1546 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1547 } 1548 } 1549 } 1550 }; 1551 mProcessStatsThread.start(); 1552 } 1553 1554 @Override 1555 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1556 throws RemoteException { 1557 if (code == SYSPROPS_TRANSACTION) { 1558 // We need to tell all apps about the system property change. 1559 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1560 synchronized(this) { 1561 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1562 final int NA = apps.size(); 1563 for (int ia=0; ia<NA; ia++) { 1564 ProcessRecord app = apps.valueAt(ia); 1565 if (app.thread != null) { 1566 procs.add(app.thread.asBinder()); 1567 } 1568 } 1569 } 1570 } 1571 1572 int N = procs.size(); 1573 for (int i=0; i<N; i++) { 1574 Parcel data2 = Parcel.obtain(); 1575 try { 1576 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1577 } catch (RemoteException e) { 1578 } 1579 data2.recycle(); 1580 } 1581 } 1582 try { 1583 return super.onTransact(code, data, reply, flags); 1584 } catch (RuntimeException e) { 1585 // The activity manager only throws security exceptions, so let's 1586 // log all others. 1587 if (!(e instanceof SecurityException)) { 1588 Slog.e(TAG, "Activity Manager Crash", e); 1589 } 1590 throw e; 1591 } 1592 } 1593 1594 void updateCpuStats() { 1595 final long now = SystemClock.uptimeMillis(); 1596 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1597 return; 1598 } 1599 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1600 synchronized (mProcessStatsThread) { 1601 mProcessStatsThread.notify(); 1602 } 1603 } 1604 } 1605 1606 void updateCpuStatsNow() { 1607 synchronized (mProcessStatsThread) { 1608 mProcessStatsMutexFree.set(false); 1609 final long now = SystemClock.uptimeMillis(); 1610 boolean haveNewCpuStats = false; 1611 1612 if (MONITOR_CPU_USAGE && 1613 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1614 mLastCpuTime.set(now); 1615 haveNewCpuStats = true; 1616 mProcessStats.update(); 1617 //Slog.i(TAG, mProcessStats.printCurrentState()); 1618 //Slog.i(TAG, "Total CPU usage: " 1619 // + mProcessStats.getTotalCpuPercent() + "%"); 1620 1621 // Slog the cpu usage if the property is set. 1622 if ("true".equals(SystemProperties.get("events.cpu"))) { 1623 int user = mProcessStats.getLastUserTime(); 1624 int system = mProcessStats.getLastSystemTime(); 1625 int iowait = mProcessStats.getLastIoWaitTime(); 1626 int irq = mProcessStats.getLastIrqTime(); 1627 int softIrq = mProcessStats.getLastSoftIrqTime(); 1628 int idle = mProcessStats.getLastIdleTime(); 1629 1630 int total = user + system + iowait + irq + softIrq + idle; 1631 if (total == 0) total = 1; 1632 1633 EventLog.writeEvent(EventLogTags.CPU, 1634 ((user+system+iowait+irq+softIrq) * 100) / total, 1635 (user * 100) / total, 1636 (system * 100) / total, 1637 (iowait * 100) / total, 1638 (irq * 100) / total, 1639 (softIrq * 100) / total); 1640 } 1641 } 1642 1643 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1644 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1645 synchronized(bstats) { 1646 synchronized(mPidsSelfLocked) { 1647 if (haveNewCpuStats) { 1648 if (mOnBattery) { 1649 int perc = bstats.startAddingCpuLocked(); 1650 int totalUTime = 0; 1651 int totalSTime = 0; 1652 final int N = mProcessStats.countStats(); 1653 for (int i=0; i<N; i++) { 1654 ProcessStats.Stats st = mProcessStats.getStats(i); 1655 if (!st.working) { 1656 continue; 1657 } 1658 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1659 int otherUTime = (st.rel_utime*perc)/100; 1660 int otherSTime = (st.rel_stime*perc)/100; 1661 totalUTime += otherUTime; 1662 totalSTime += otherSTime; 1663 if (pr != null) { 1664 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1665 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1666 st.rel_stime-otherSTime); 1667 ps.addSpeedStepTimes(cpuSpeedTimes); 1668 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1669 } else { 1670 BatteryStatsImpl.Uid.Proc ps = 1671 bstats.getProcessStatsLocked(st.name, st.pid); 1672 if (ps != null) { 1673 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1674 st.rel_stime-otherSTime); 1675 ps.addSpeedStepTimes(cpuSpeedTimes); 1676 } 1677 } 1678 } 1679 bstats.finishAddingCpuLocked(perc, totalUTime, 1680 totalSTime, cpuSpeedTimes); 1681 } 1682 } 1683 } 1684 1685 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1686 mLastWriteTime = now; 1687 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1688 } 1689 } 1690 } 1691 } 1692 1693 @Override 1694 public void batteryNeedsCpuUpdate() { 1695 updateCpuStatsNow(); 1696 } 1697 1698 @Override 1699 public void batteryPowerChanged(boolean onBattery) { 1700 // When plugging in, update the CPU stats first before changing 1701 // the plug state. 1702 updateCpuStatsNow(); 1703 synchronized (this) { 1704 synchronized(mPidsSelfLocked) { 1705 mOnBattery = DEBUG_POWER ? true : onBattery; 1706 } 1707 } 1708 } 1709 1710 /** 1711 * Initialize the application bind args. These are passed to each 1712 * process when the bindApplication() IPC is sent to the process. They're 1713 * lazily setup to make sure the services are running when they're asked for. 1714 */ 1715 private HashMap<String, IBinder> getCommonServicesLocked() { 1716 if (mAppBindArgs == null) { 1717 mAppBindArgs = new HashMap<String, IBinder>(); 1718 1719 // Setup the application init args 1720 mAppBindArgs.put("package", ServiceManager.getService("package")); 1721 mAppBindArgs.put("window", ServiceManager.getService("window")); 1722 mAppBindArgs.put(Context.ALARM_SERVICE, 1723 ServiceManager.getService(Context.ALARM_SERVICE)); 1724 } 1725 return mAppBindArgs; 1726 } 1727 1728 final void setFocusedActivityLocked(ActivityRecord r) { 1729 if (mFocusedActivity != r) { 1730 mFocusedActivity = r; 1731 if (r != null) { 1732 mWindowManager.setFocusedApp(r.appToken, true); 1733 } 1734 } 1735 } 1736 1737 private final void updateLruProcessInternalLocked(ProcessRecord app, 1738 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1739 // put it on the LRU to keep track of when it should be exited. 1740 int lrui = mLruProcesses.indexOf(app); 1741 if (lrui >= 0) mLruProcesses.remove(lrui); 1742 1743 int i = mLruProcesses.size()-1; 1744 int skipTop = 0; 1745 1746 app.lruSeq = mLruSeq; 1747 1748 // compute the new weight for this process. 1749 if (updateActivityTime) { 1750 app.lastActivityTime = SystemClock.uptimeMillis(); 1751 } 1752 if (app.activities.size() > 0) { 1753 // If this process has activities, we more strongly want to keep 1754 // it around. 1755 app.lruWeight = app.lastActivityTime; 1756 } else if (app.pubProviders.size() > 0) { 1757 // If this process contains content providers, we want to keep 1758 // it a little more strongly. 1759 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1760 // Also don't let it kick out the first few "real" hidden processes. 1761 skipTop = ProcessList.MIN_HIDDEN_APPS; 1762 } else { 1763 // If this process doesn't have activities, we less strongly 1764 // want to keep it around, and generally want to avoid getting 1765 // in front of any very recently used activities. 1766 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1767 // Also don't let it kick out the first few "real" hidden processes. 1768 skipTop = ProcessList.MIN_HIDDEN_APPS; 1769 } 1770 1771 while (i >= 0) { 1772 ProcessRecord p = mLruProcesses.get(i); 1773 // If this app shouldn't be in front of the first N background 1774 // apps, then skip over that many that are currently hidden. 1775 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1776 skipTop--; 1777 } 1778 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1779 mLruProcesses.add(i+1, app); 1780 break; 1781 } 1782 i--; 1783 } 1784 if (i < 0) { 1785 mLruProcesses.add(0, app); 1786 } 1787 1788 // If the app is currently using a content provider or service, 1789 // bump those processes as well. 1790 if (app.connections.size() > 0) { 1791 for (ConnectionRecord cr : app.connections) { 1792 if (cr.binding != null && cr.binding.service != null 1793 && cr.binding.service.app != null 1794 && cr.binding.service.app.lruSeq != mLruSeq) { 1795 updateLruProcessInternalLocked(cr.binding.service.app, false, 1796 updateActivityTime, i+1); 1797 } 1798 } 1799 } 1800 for (int j=app.conProviders.size()-1; j>=0; j--) { 1801 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1802 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1803 updateLruProcessInternalLocked(cpr.proc, false, 1804 updateActivityTime, i+1); 1805 } 1806 } 1807 1808 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1809 if (oomAdj) { 1810 updateOomAdjLocked(); 1811 } 1812 } 1813 1814 final void updateLruProcessLocked(ProcessRecord app, 1815 boolean oomAdj, boolean updateActivityTime) { 1816 mLruSeq++; 1817 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1818 } 1819 1820 final ProcessRecord getProcessRecordLocked( 1821 String processName, int uid) { 1822 if (uid == Process.SYSTEM_UID) { 1823 // The system gets to run in any process. If there are multiple 1824 // processes with the same uid, just pick the first (this 1825 // should never happen). 1826 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1827 processName); 1828 if (procs == null) return null; 1829 final int N = procs.size(); 1830 for (int i = 0; i < N; i++) { 1831 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1832 } 1833 } 1834 ProcessRecord proc = mProcessNames.get(processName, uid); 1835 return proc; 1836 } 1837 1838 void ensurePackageDexOpt(String packageName) { 1839 IPackageManager pm = AppGlobals.getPackageManager(); 1840 try { 1841 if (pm.performDexOpt(packageName)) { 1842 mDidDexOpt = true; 1843 } 1844 } catch (RemoteException e) { 1845 } 1846 } 1847 1848 boolean isNextTransitionForward() { 1849 int transit = mWindowManager.getPendingAppTransition(); 1850 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1851 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1852 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1853 } 1854 1855 final ProcessRecord startProcessLocked(String processName, 1856 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1857 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1858 boolean isolated) { 1859 ProcessRecord app; 1860 if (!isolated) { 1861 app = getProcessRecordLocked(processName, info.uid); 1862 } else { 1863 // If this is an isolated process, it can't re-use an existing process. 1864 app = null; 1865 } 1866 // We don't have to do anything more if: 1867 // (1) There is an existing application record; and 1868 // (2) The caller doesn't think it is dead, OR there is no thread 1869 // object attached to it so we know it couldn't have crashed; and 1870 // (3) There is a pid assigned to it, so it is either starting or 1871 // already running. 1872 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1873 + " app=" + app + " knownToBeDead=" + knownToBeDead 1874 + " thread=" + (app != null ? app.thread : null) 1875 + " pid=" + (app != null ? app.pid : -1)); 1876 if (app != null && app.pid > 0) { 1877 if (!knownToBeDead || app.thread == null) { 1878 // We already have the app running, or are waiting for it to 1879 // come up (we have a pid but not yet its thread), so keep it. 1880 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1881 // If this is a new package in the process, add the package to the list 1882 app.addPackage(info.packageName); 1883 return app; 1884 } else { 1885 // An application record is attached to a previous process, 1886 // clean it up now. 1887 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1888 handleAppDiedLocked(app, true, true); 1889 } 1890 } 1891 1892 String hostingNameStr = hostingName != null 1893 ? hostingName.flattenToShortString() : null; 1894 1895 if (!isolated) { 1896 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1897 // If we are in the background, then check to see if this process 1898 // is bad. If so, we will just silently fail. 1899 if (mBadProcesses.get(info.processName, info.uid) != null) { 1900 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1901 + "/" + info.processName); 1902 return null; 1903 } 1904 } else { 1905 // When the user is explicitly starting a process, then clear its 1906 // crash count so that we won't make it bad until they see at 1907 // least one crash dialog again, and make the process good again 1908 // if it had been bad. 1909 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1910 + "/" + info.processName); 1911 mProcessCrashTimes.remove(info.processName, info.uid); 1912 if (mBadProcesses.get(info.processName, info.uid) != null) { 1913 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1914 info.processName); 1915 mBadProcesses.remove(info.processName, info.uid); 1916 if (app != null) { 1917 app.bad = false; 1918 } 1919 } 1920 } 1921 } 1922 1923 if (app == null) { 1924 app = newProcessRecordLocked(null, info, processName, isolated); 1925 if (app == null) { 1926 Slog.w(TAG, "Failed making new process record for " 1927 + processName + "/" + info.uid + " isolated=" + isolated); 1928 return null; 1929 } 1930 mProcessNames.put(processName, app.uid, app); 1931 if (isolated) { 1932 mIsolatedProcesses.put(app.uid, app); 1933 } 1934 } else { 1935 // If this is a new package in the process, add the package to the list 1936 app.addPackage(info.packageName); 1937 } 1938 1939 // If the system is not ready yet, then hold off on starting this 1940 // process until it is. 1941 if (!mProcessesReady 1942 && !isAllowedWhileBooting(info) 1943 && !allowWhileBooting) { 1944 if (!mProcessesOnHold.contains(app)) { 1945 mProcessesOnHold.add(app); 1946 } 1947 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1948 return app; 1949 } 1950 1951 startProcessLocked(app, hostingType, hostingNameStr); 1952 return (app.pid != 0) ? app : null; 1953 } 1954 1955 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1956 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1957 } 1958 1959 private final void startProcessLocked(ProcessRecord app, 1960 String hostingType, String hostingNameStr) { 1961 if (app.pid > 0 && app.pid != MY_PID) { 1962 synchronized (mPidsSelfLocked) { 1963 mPidsSelfLocked.remove(app.pid); 1964 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1965 } 1966 app.setPid(0); 1967 } 1968 1969 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1970 "startProcessLocked removing on hold: " + app); 1971 mProcessesOnHold.remove(app); 1972 1973 updateCpuStats(); 1974 1975 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1976 mProcDeaths[0] = 0; 1977 1978 try { 1979 int uid = app.uid; 1980 1981 int[] gids = null; 1982 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1983 if (!app.isolated) { 1984 try { 1985 final PackageManager pm = mContext.getPackageManager(); 1986 gids = pm.getPackageGids(app.info.packageName); 1987 if (pm.checkPermission( 1988 android.Manifest.permission.READ_EXTERNAL_STORAGE, app.info.packageName) 1989 == PERMISSION_GRANTED) { 1990 if (Environment.isExternalStorageEmulated()) { 1991 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 1992 } else { 1993 mountExternal = Zygote.MOUNT_EXTERNAL_SINGLEUSER; 1994 } 1995 } 1996 } catch (PackageManager.NameNotFoundException e) { 1997 Slog.w(TAG, "Unable to retrieve gids", e); 1998 } 1999 } 2000 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2001 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2002 && mTopComponent != null 2003 && app.processName.equals(mTopComponent.getPackageName())) { 2004 uid = 0; 2005 } 2006 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2007 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2008 uid = 0; 2009 } 2010 } 2011 int debugFlags = 0; 2012 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2013 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2014 // Also turn on CheckJNI for debuggable apps. It's quite 2015 // awkward to turn on otherwise. 2016 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2017 } 2018 // Run the app in safe mode if its manifest requests so or the 2019 // system is booted in safe mode. 2020 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2021 Zygote.systemInSafeMode == true) { 2022 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2023 } 2024 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2025 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2026 } 2027 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2028 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2029 } 2030 if ("1".equals(SystemProperties.get("debug.assert"))) { 2031 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2032 } 2033 2034 // Start the process. It will either succeed and return a result containing 2035 // the PID of the new process, or else throw a RuntimeException. 2036 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2037 app.processName, uid, uid, gids, debugFlags, mountExternal, 2038 app.info.targetSdkVersion, null, null); 2039 2040 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2041 synchronized (bs) { 2042 if (bs.isOnBattery()) { 2043 app.batteryStats.incStartsLocked(); 2044 } 2045 } 2046 2047 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2048 app.processName, hostingType, 2049 hostingNameStr != null ? hostingNameStr : ""); 2050 2051 if (app.persistent) { 2052 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2053 } 2054 2055 StringBuilder buf = mStringBuilder; 2056 buf.setLength(0); 2057 buf.append("Start proc "); 2058 buf.append(app.processName); 2059 buf.append(" for "); 2060 buf.append(hostingType); 2061 if (hostingNameStr != null) { 2062 buf.append(" "); 2063 buf.append(hostingNameStr); 2064 } 2065 buf.append(": pid="); 2066 buf.append(startResult.pid); 2067 buf.append(" uid="); 2068 buf.append(uid); 2069 buf.append(" gids={"); 2070 if (gids != null) { 2071 for (int gi=0; gi<gids.length; gi++) { 2072 if (gi != 0) buf.append(", "); 2073 buf.append(gids[gi]); 2074 2075 } 2076 } 2077 buf.append("}"); 2078 Slog.i(TAG, buf.toString()); 2079 app.setPid(startResult.pid); 2080 app.usingWrapper = startResult.usingWrapper; 2081 app.removed = false; 2082 synchronized (mPidsSelfLocked) { 2083 this.mPidsSelfLocked.put(startResult.pid, app); 2084 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2085 msg.obj = app; 2086 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2087 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2088 } 2089 } catch (RuntimeException e) { 2090 // XXX do better error recovery. 2091 app.setPid(0); 2092 Slog.e(TAG, "Failure starting process " + app.processName, e); 2093 } 2094 } 2095 2096 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2097 if (resumed) { 2098 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2099 } else { 2100 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2101 } 2102 } 2103 2104 boolean startHomeActivityLocked(int userId) { 2105 if (mHeadless) { 2106 // Added because none of the other calls to ensureBootCompleted seem to fire 2107 // when running headless. 2108 ensureBootCompleted(); 2109 return false; 2110 } 2111 2112 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2113 && mTopAction == null) { 2114 // We are running in factory test mode, but unable to find 2115 // the factory test app, so just sit around displaying the 2116 // error message and don't try to start anything. 2117 return false; 2118 } 2119 Intent intent = new Intent( 2120 mTopAction, 2121 mTopData != null ? Uri.parse(mTopData) : null); 2122 intent.setComponent(mTopComponent); 2123 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2124 intent.addCategory(Intent.CATEGORY_HOME); 2125 } 2126 ActivityInfo aInfo = 2127 intent.resolveActivityInfo(mContext.getPackageManager(), 2128 STOCK_PM_FLAGS); 2129 if (aInfo != null) { 2130 intent.setComponent(new ComponentName( 2131 aInfo.applicationInfo.packageName, aInfo.name)); 2132 // Don't do this if the home app is currently being 2133 // instrumented. 2134 aInfo = new ActivityInfo(aInfo); 2135 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2136 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2137 aInfo.applicationInfo.uid); 2138 if (app == null || app.instrumentationClass == null) { 2139 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2140 mMainStack.startActivityLocked(null, intent, null, aInfo, 2141 null, null, 0, 0, 0, 0, null, false, null); 2142 } 2143 } 2144 2145 return true; 2146 } 2147 2148 /** 2149 * Starts the "new version setup screen" if appropriate. 2150 */ 2151 void startSetupActivityLocked() { 2152 // Only do this once per boot. 2153 if (mCheckedForSetup) { 2154 return; 2155 } 2156 2157 // We will show this screen if the current one is a different 2158 // version than the last one shown, and we are not running in 2159 // low-level factory test mode. 2160 final ContentResolver resolver = mContext.getContentResolver(); 2161 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2162 Settings.Secure.getInt(resolver, 2163 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2164 mCheckedForSetup = true; 2165 2166 // See if we should be showing the platform update setup UI. 2167 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2168 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2169 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2170 2171 // We don't allow third party apps to replace this. 2172 ResolveInfo ri = null; 2173 for (int i=0; ris != null && i<ris.size(); i++) { 2174 if ((ris.get(i).activityInfo.applicationInfo.flags 2175 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2176 ri = ris.get(i); 2177 break; 2178 } 2179 } 2180 2181 if (ri != null) { 2182 String vers = ri.activityInfo.metaData != null 2183 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2184 : null; 2185 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2186 vers = ri.activityInfo.applicationInfo.metaData.getString( 2187 Intent.METADATA_SETUP_VERSION); 2188 } 2189 String lastVers = Settings.Secure.getString( 2190 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2191 if (vers != null && !vers.equals(lastVers)) { 2192 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2193 intent.setComponent(new ComponentName( 2194 ri.activityInfo.packageName, ri.activityInfo.name)); 2195 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2196 null, null, 0, 0, 0, 0, null, false, null); 2197 } 2198 } 2199 } 2200 } 2201 2202 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2203 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2204 } 2205 2206 void enforceNotIsolatedCaller(String caller) { 2207 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2208 throw new SecurityException("Isolated process not allowed to call " + caller); 2209 } 2210 } 2211 2212 public int getFrontActivityScreenCompatMode() { 2213 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2214 synchronized (this) { 2215 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2216 } 2217 } 2218 2219 public void setFrontActivityScreenCompatMode(int mode) { 2220 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2221 "setFrontActivityScreenCompatMode"); 2222 synchronized (this) { 2223 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2224 } 2225 } 2226 2227 public int getPackageScreenCompatMode(String packageName) { 2228 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2229 synchronized (this) { 2230 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2231 } 2232 } 2233 2234 public void setPackageScreenCompatMode(String packageName, int mode) { 2235 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2236 "setPackageScreenCompatMode"); 2237 synchronized (this) { 2238 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2239 } 2240 } 2241 2242 public boolean getPackageAskScreenCompat(String packageName) { 2243 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2244 synchronized (this) { 2245 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2246 } 2247 } 2248 2249 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2250 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2251 "setPackageAskScreenCompat"); 2252 synchronized (this) { 2253 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2254 } 2255 } 2256 2257 void reportResumedActivityLocked(ActivityRecord r) { 2258 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2259 updateUsageStats(r, true); 2260 } 2261 2262 private void dispatchProcessesChanged() { 2263 int N; 2264 synchronized (this) { 2265 N = mPendingProcessChanges.size(); 2266 if (mActiveProcessChanges.length < N) { 2267 mActiveProcessChanges = new ProcessChangeItem[N]; 2268 } 2269 mPendingProcessChanges.toArray(mActiveProcessChanges); 2270 mAvailProcessChanges.addAll(mPendingProcessChanges); 2271 mPendingProcessChanges.clear(); 2272 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2273 } 2274 int i = mProcessObservers.beginBroadcast(); 2275 while (i > 0) { 2276 i--; 2277 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2278 if (observer != null) { 2279 try { 2280 for (int j=0; j<N; j++) { 2281 ProcessChangeItem item = mActiveProcessChanges[j]; 2282 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2283 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2284 + item.pid + " uid=" + item.uid + ": " 2285 + item.foregroundActivities); 2286 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2287 item.foregroundActivities); 2288 } 2289 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2290 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2291 + item.pid + " uid=" + item.uid + ": " + item.importance); 2292 observer.onImportanceChanged(item.pid, item.uid, 2293 item.importance); 2294 } 2295 } 2296 } catch (RemoteException e) { 2297 } 2298 } 2299 } 2300 mProcessObservers.finishBroadcast(); 2301 } 2302 2303 private void dispatchProcessDied(int pid, int uid) { 2304 int i = mProcessObservers.beginBroadcast(); 2305 while (i > 0) { 2306 i--; 2307 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2308 if (observer != null) { 2309 try { 2310 observer.onProcessDied(pid, uid); 2311 } catch (RemoteException e) { 2312 } 2313 } 2314 } 2315 mProcessObservers.finishBroadcast(); 2316 } 2317 2318 final void doPendingActivityLaunchesLocked(boolean doResume) { 2319 final int N = mPendingActivityLaunches.size(); 2320 if (N <= 0) { 2321 return; 2322 } 2323 for (int i=0; i<N; i++) { 2324 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2325 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2326 pal.startFlags, doResume && i == (N-1), null); 2327 } 2328 mPendingActivityLaunches.clear(); 2329 } 2330 2331 public final int startActivity(IApplicationThread caller, 2332 Intent intent, String resolvedType, IBinder resultTo, 2333 String resultWho, int requestCode, int startFlags, 2334 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2335 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2336 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2337 } 2338 2339 public final int startActivityAsUser(IApplicationThread caller, 2340 Intent intent, String resolvedType, IBinder resultTo, 2341 String resultWho, int requestCode, int startFlags, 2342 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2343 enforceNotIsolatedCaller("startActivity"); 2344 if (userId != UserHandle.getCallingUserId()) { 2345 // Requesting a different user, make sure that they have the permission 2346 if (checkComponentPermission( 2347 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2348 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 2349 == PackageManager.PERMISSION_GRANTED) { 2350 // Translate to the current user id, if caller wasn't aware 2351 if (userId == UserHandle.USER_CURRENT) { 2352 userId = mCurrentUserId; 2353 } 2354 } else { 2355 String msg = "Permission Denial: " 2356 + "Request to startActivity as user " + userId 2357 + " but is calling from user " + UserHandle.getCallingUserId() 2358 + "; this requires " 2359 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 2360 Slog.w(TAG, msg); 2361 throw new SecurityException(msg); 2362 } 2363 } else { 2364 if (intent.getCategories() != null 2365 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2366 // Requesting home, set the identity to the current user 2367 // HACK! 2368 userId = mCurrentUserId; 2369 } else { 2370 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2371 // the current user's userId 2372 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2373 userId = 0; 2374 } else { 2375 userId = Binder.getOrigCallingUser(); 2376 } 2377 } 2378 } 2379 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2380 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2381 null, null, options, userId); 2382 } 2383 2384 public final WaitResult startActivityAndWait(IApplicationThread caller, 2385 Intent intent, String resolvedType, IBinder resultTo, 2386 String resultWho, int requestCode, int startFlags, String profileFile, 2387 ParcelFileDescriptor profileFd, Bundle options) { 2388 enforceNotIsolatedCaller("startActivityAndWait"); 2389 WaitResult res = new WaitResult(); 2390 int userId = Binder.getOrigCallingUser(); 2391 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2392 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2393 res, null, options, userId); 2394 return res; 2395 } 2396 2397 public final int startActivityWithConfig(IApplicationThread caller, 2398 Intent intent, String resolvedType, IBinder resultTo, 2399 String resultWho, int requestCode, int startFlags, Configuration config, 2400 Bundle options) { 2401 enforceNotIsolatedCaller("startActivityWithConfig"); 2402 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2403 resultTo, resultWho, requestCode, startFlags, 2404 null, null, null, config, options, Binder.getOrigCallingUser()); 2405 return ret; 2406 } 2407 2408 public int startActivityIntentSender(IApplicationThread caller, 2409 IntentSender intent, Intent fillInIntent, String resolvedType, 2410 IBinder resultTo, String resultWho, int requestCode, 2411 int flagsMask, int flagsValues, Bundle options) { 2412 enforceNotIsolatedCaller("startActivityIntentSender"); 2413 // Refuse possible leaked file descriptors 2414 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2415 throw new IllegalArgumentException("File descriptors passed in Intent"); 2416 } 2417 2418 IIntentSender sender = intent.getTarget(); 2419 if (!(sender instanceof PendingIntentRecord)) { 2420 throw new IllegalArgumentException("Bad PendingIntent object"); 2421 } 2422 2423 PendingIntentRecord pir = (PendingIntentRecord)sender; 2424 2425 synchronized (this) { 2426 // If this is coming from the currently resumed activity, it is 2427 // effectively saying that app switches are allowed at this point. 2428 if (mMainStack.mResumedActivity != null 2429 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2430 Binder.getCallingUid()) { 2431 mAppSwitchesAllowedTime = 0; 2432 } 2433 } 2434 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2435 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2436 return ret; 2437 } 2438 2439 public boolean startNextMatchingActivity(IBinder callingActivity, 2440 Intent intent, Bundle options) { 2441 // Refuse possible leaked file descriptors 2442 if (intent != null && intent.hasFileDescriptors() == true) { 2443 throw new IllegalArgumentException("File descriptors passed in Intent"); 2444 } 2445 2446 synchronized (this) { 2447 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2448 if (r == null) { 2449 ActivityOptions.abort(options); 2450 return false; 2451 } 2452 if (r.app == null || r.app.thread == null) { 2453 // The caller is not running... d'oh! 2454 ActivityOptions.abort(options); 2455 return false; 2456 } 2457 intent = new Intent(intent); 2458 // The caller is not allowed to change the data. 2459 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2460 // And we are resetting to find the next component... 2461 intent.setComponent(null); 2462 2463 ActivityInfo aInfo = null; 2464 try { 2465 List<ResolveInfo> resolves = 2466 AppGlobals.getPackageManager().queryIntentActivities( 2467 intent, r.resolvedType, 2468 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2469 UserHandle.getCallingUserId()); 2470 2471 // Look for the original activity in the list... 2472 final int N = resolves != null ? resolves.size() : 0; 2473 for (int i=0; i<N; i++) { 2474 ResolveInfo rInfo = resolves.get(i); 2475 if (rInfo.activityInfo.packageName.equals(r.packageName) 2476 && rInfo.activityInfo.name.equals(r.info.name)) { 2477 // We found the current one... the next matching is 2478 // after it. 2479 i++; 2480 if (i<N) { 2481 aInfo = resolves.get(i).activityInfo; 2482 } 2483 break; 2484 } 2485 } 2486 } catch (RemoteException e) { 2487 } 2488 2489 if (aInfo == null) { 2490 // Nobody who is next! 2491 ActivityOptions.abort(options); 2492 return false; 2493 } 2494 2495 intent.setComponent(new ComponentName( 2496 aInfo.applicationInfo.packageName, aInfo.name)); 2497 intent.setFlags(intent.getFlags()&~( 2498 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2499 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2500 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2501 Intent.FLAG_ACTIVITY_NEW_TASK)); 2502 2503 // Okay now we need to start the new activity, replacing the 2504 // currently running activity. This is a little tricky because 2505 // we want to start the new one as if the current one is finished, 2506 // but not finish the current one first so that there is no flicker. 2507 // And thus... 2508 final boolean wasFinishing = r.finishing; 2509 r.finishing = true; 2510 2511 // Propagate reply information over to the new activity. 2512 final ActivityRecord resultTo = r.resultTo; 2513 final String resultWho = r.resultWho; 2514 final int requestCode = r.requestCode; 2515 r.resultTo = null; 2516 if (resultTo != null) { 2517 resultTo.removeResultsLocked(r, resultWho, requestCode); 2518 } 2519 2520 final long origId = Binder.clearCallingIdentity(); 2521 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2522 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2523 resultWho, requestCode, -1, r.launchedFromUid, 0, 2524 options, false, null); 2525 Binder.restoreCallingIdentity(origId); 2526 2527 r.finishing = wasFinishing; 2528 if (res != ActivityManager.START_SUCCESS) { 2529 return false; 2530 } 2531 return true; 2532 } 2533 } 2534 2535 public final int startActivityInPackage(int uid, 2536 Intent intent, String resolvedType, IBinder resultTo, 2537 String resultWho, int requestCode, int startFlags, Bundle options) { 2538 2539 // This is so super not safe, that only the system (or okay root) 2540 // can do it. 2541 final int callingUid = Binder.getCallingUid(); 2542 if (callingUid != 0 && callingUid != Process.myUid()) { 2543 throw new SecurityException( 2544 "startActivityInPackage only available to the system"); 2545 } 2546 2547 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2548 resultTo, resultWho, requestCode, startFlags, 2549 null, null, null, null, options, UserHandle.getUserId(uid)); 2550 return ret; 2551 } 2552 2553 public final int startActivities(IApplicationThread caller, 2554 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2555 enforceNotIsolatedCaller("startActivities"); 2556 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2557 options, Binder.getOrigCallingUser()); 2558 return ret; 2559 } 2560 2561 public final int startActivitiesInPackage(int uid, 2562 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2563 Bundle options) { 2564 2565 // This is so super not safe, that only the system (or okay root) 2566 // can do it. 2567 final int callingUid = Binder.getCallingUid(); 2568 if (callingUid != 0 && callingUid != Process.myUid()) { 2569 throw new SecurityException( 2570 "startActivityInPackage only available to the system"); 2571 } 2572 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2573 options, UserHandle.getUserId(uid)); 2574 return ret; 2575 } 2576 2577 final void addRecentTaskLocked(TaskRecord task) { 2578 int N = mRecentTasks.size(); 2579 // Quick case: check if the top-most recent task is the same. 2580 if (N > 0 && mRecentTasks.get(0) == task) { 2581 return; 2582 } 2583 // Remove any existing entries that are the same kind of task. 2584 for (int i=0; i<N; i++) { 2585 TaskRecord tr = mRecentTasks.get(i); 2586 if (task.userId == tr.userId 2587 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2588 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2589 mRecentTasks.remove(i); 2590 i--; 2591 N--; 2592 if (task.intent == null) { 2593 // If the new recent task we are adding is not fully 2594 // specified, then replace it with the existing recent task. 2595 task = tr; 2596 } 2597 } 2598 } 2599 if (N >= MAX_RECENT_TASKS) { 2600 mRecentTasks.remove(N-1); 2601 } 2602 mRecentTasks.add(0, task); 2603 } 2604 2605 public void setRequestedOrientation(IBinder token, 2606 int requestedOrientation) { 2607 synchronized (this) { 2608 ActivityRecord r = mMainStack.isInStackLocked(token); 2609 if (r == null) { 2610 return; 2611 } 2612 final long origId = Binder.clearCallingIdentity(); 2613 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2614 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2615 mConfiguration, 2616 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2617 if (config != null) { 2618 r.frozenBeforeDestroy = true; 2619 if (!updateConfigurationLocked(config, r, false, false)) { 2620 mMainStack.resumeTopActivityLocked(null); 2621 } 2622 } 2623 Binder.restoreCallingIdentity(origId); 2624 } 2625 } 2626 2627 public int getRequestedOrientation(IBinder token) { 2628 synchronized (this) { 2629 ActivityRecord r = mMainStack.isInStackLocked(token); 2630 if (r == null) { 2631 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2632 } 2633 return mWindowManager.getAppOrientation(r.appToken); 2634 } 2635 } 2636 2637 /** 2638 * This is the internal entry point for handling Activity.finish(). 2639 * 2640 * @param token The Binder token referencing the Activity we want to finish. 2641 * @param resultCode Result code, if any, from this Activity. 2642 * @param resultData Result data (Intent), if any, from this Activity. 2643 * 2644 * @return Returns true if the activity successfully finished, or false if it is still running. 2645 */ 2646 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2647 // Refuse possible leaked file descriptors 2648 if (resultData != null && resultData.hasFileDescriptors() == true) { 2649 throw new IllegalArgumentException("File descriptors passed in Intent"); 2650 } 2651 2652 synchronized(this) { 2653 if (mController != null) { 2654 // Find the first activity that is not finishing. 2655 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2656 if (next != null) { 2657 // ask watcher if this is allowed 2658 boolean resumeOK = true; 2659 try { 2660 resumeOK = mController.activityResuming(next.packageName); 2661 } catch (RemoteException e) { 2662 mController = null; 2663 } 2664 2665 if (!resumeOK) { 2666 return false; 2667 } 2668 } 2669 } 2670 final long origId = Binder.clearCallingIdentity(); 2671 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2672 resultData, "app-request"); 2673 Binder.restoreCallingIdentity(origId); 2674 return res; 2675 } 2676 } 2677 2678 public final void finishHeavyWeightApp() { 2679 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2680 != PackageManager.PERMISSION_GRANTED) { 2681 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2682 + Binder.getCallingPid() 2683 + ", uid=" + Binder.getCallingUid() 2684 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2685 Slog.w(TAG, msg); 2686 throw new SecurityException(msg); 2687 } 2688 2689 synchronized(this) { 2690 if (mHeavyWeightProcess == null) { 2691 return; 2692 } 2693 2694 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2695 mHeavyWeightProcess.activities); 2696 for (int i=0; i<activities.size(); i++) { 2697 ActivityRecord r = activities.get(i); 2698 if (!r.finishing) { 2699 int index = mMainStack.indexOfTokenLocked(r.appToken); 2700 if (index >= 0) { 2701 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2702 null, "finish-heavy"); 2703 } 2704 } 2705 } 2706 2707 mHeavyWeightProcess = null; 2708 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2709 } 2710 } 2711 2712 public void crashApplication(int uid, int initialPid, String packageName, 2713 String message) { 2714 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2715 != PackageManager.PERMISSION_GRANTED) { 2716 String msg = "Permission Denial: crashApplication() from pid=" 2717 + Binder.getCallingPid() 2718 + ", uid=" + Binder.getCallingUid() 2719 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2720 Slog.w(TAG, msg); 2721 throw new SecurityException(msg); 2722 } 2723 2724 synchronized(this) { 2725 ProcessRecord proc = null; 2726 2727 // Figure out which process to kill. We don't trust that initialPid 2728 // still has any relation to current pids, so must scan through the 2729 // list. 2730 synchronized (mPidsSelfLocked) { 2731 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2732 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2733 if (p.uid != uid) { 2734 continue; 2735 } 2736 if (p.pid == initialPid) { 2737 proc = p; 2738 break; 2739 } 2740 for (String str : p.pkgList) { 2741 if (str.equals(packageName)) { 2742 proc = p; 2743 } 2744 } 2745 } 2746 } 2747 2748 if (proc == null) { 2749 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2750 + " initialPid=" + initialPid 2751 + " packageName=" + packageName); 2752 return; 2753 } 2754 2755 if (proc.thread != null) { 2756 if (proc.pid == Process.myPid()) { 2757 Log.w(TAG, "crashApplication: trying to crash self!"); 2758 return; 2759 } 2760 long ident = Binder.clearCallingIdentity(); 2761 try { 2762 proc.thread.scheduleCrash(message); 2763 } catch (RemoteException e) { 2764 } 2765 Binder.restoreCallingIdentity(ident); 2766 } 2767 } 2768 } 2769 2770 public final void finishSubActivity(IBinder token, String resultWho, 2771 int requestCode) { 2772 synchronized(this) { 2773 final long origId = Binder.clearCallingIdentity(); 2774 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2775 Binder.restoreCallingIdentity(origId); 2776 } 2777 } 2778 2779 public boolean finishActivityAffinity(IBinder token) { 2780 synchronized(this) { 2781 final long origId = Binder.clearCallingIdentity(); 2782 boolean res = mMainStack.finishActivityAffinityLocked(token); 2783 Binder.restoreCallingIdentity(origId); 2784 return res; 2785 } 2786 } 2787 2788 public boolean willActivityBeVisible(IBinder token) { 2789 synchronized(this) { 2790 int i; 2791 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2792 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2793 if (r.appToken == token) { 2794 return true; 2795 } 2796 if (r.fullscreen && !r.finishing) { 2797 return false; 2798 } 2799 } 2800 return true; 2801 } 2802 } 2803 2804 public void overridePendingTransition(IBinder token, String packageName, 2805 int enterAnim, int exitAnim) { 2806 synchronized(this) { 2807 ActivityRecord self = mMainStack.isInStackLocked(token); 2808 if (self == null) { 2809 return; 2810 } 2811 2812 final long origId = Binder.clearCallingIdentity(); 2813 2814 if (self.state == ActivityState.RESUMED 2815 || self.state == ActivityState.PAUSING) { 2816 mWindowManager.overridePendingAppTransition(packageName, 2817 enterAnim, exitAnim, null); 2818 } 2819 2820 Binder.restoreCallingIdentity(origId); 2821 } 2822 } 2823 2824 /** 2825 * Main function for removing an existing process from the activity manager 2826 * as a result of that process going away. Clears out all connections 2827 * to the process. 2828 */ 2829 private final void handleAppDiedLocked(ProcessRecord app, 2830 boolean restarting, boolean allowRestart) { 2831 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2832 if (!restarting) { 2833 mLruProcesses.remove(app); 2834 } 2835 2836 if (mProfileProc == app) { 2837 clearProfilerLocked(); 2838 } 2839 2840 // Just in case... 2841 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2842 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2843 mMainStack.mPausingActivity = null; 2844 } 2845 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2846 mMainStack.mLastPausedActivity = null; 2847 } 2848 2849 // Remove this application's activities from active lists. 2850 mMainStack.removeHistoryRecordsForAppLocked(app); 2851 2852 boolean atTop = true; 2853 boolean hasVisibleActivities = false; 2854 2855 // Clean out the history list. 2856 int i = mMainStack.mHistory.size(); 2857 if (localLOGV) Slog.v( 2858 TAG, "Removing app " + app + " from history with " + i + " entries"); 2859 while (i > 0) { 2860 i--; 2861 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2862 if (localLOGV) Slog.v( 2863 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2864 if (r.app == app) { 2865 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2866 if (ActivityStack.DEBUG_ADD_REMOVE) { 2867 RuntimeException here = new RuntimeException("here"); 2868 here.fillInStackTrace(); 2869 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2870 + ": haveState=" + r.haveState 2871 + " stateNotNeeded=" + r.stateNotNeeded 2872 + " finishing=" + r.finishing 2873 + " state=" + r.state, here); 2874 } 2875 if (!r.finishing) { 2876 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2877 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2878 System.identityHashCode(r), 2879 r.task.taskId, r.shortComponentName, 2880 "proc died without state saved"); 2881 } 2882 mMainStack.removeActivityFromHistoryLocked(r); 2883 2884 } else { 2885 // We have the current state for this activity, so 2886 // it can be restarted later when needed. 2887 if (localLOGV) Slog.v( 2888 TAG, "Keeping entry, setting app to null"); 2889 if (r.visible) { 2890 hasVisibleActivities = true; 2891 } 2892 r.app = null; 2893 r.nowVisible = false; 2894 if (!r.haveState) { 2895 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2896 "App died, clearing saved state of " + r); 2897 r.icicle = null; 2898 } 2899 } 2900 2901 r.stack.cleanUpActivityLocked(r, true, true); 2902 } 2903 atTop = false; 2904 } 2905 2906 app.activities.clear(); 2907 2908 if (app.instrumentationClass != null) { 2909 Slog.w(TAG, "Crash of app " + app.processName 2910 + " running instrumentation " + app.instrumentationClass); 2911 Bundle info = new Bundle(); 2912 info.putString("shortMsg", "Process crashed."); 2913 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2914 } 2915 2916 if (!restarting) { 2917 if (!mMainStack.resumeTopActivityLocked(null)) { 2918 // If there was nothing to resume, and we are not already 2919 // restarting this process, but there is a visible activity that 2920 // is hosted by the process... then make sure all visible 2921 // activities are running, taking care of restarting this 2922 // process. 2923 if (hasVisibleActivities) { 2924 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2925 } 2926 } 2927 } 2928 } 2929 2930 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2931 IBinder threadBinder = thread.asBinder(); 2932 // Find the application record. 2933 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2934 ProcessRecord rec = mLruProcesses.get(i); 2935 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2936 return i; 2937 } 2938 } 2939 return -1; 2940 } 2941 2942 final ProcessRecord getRecordForAppLocked( 2943 IApplicationThread thread) { 2944 if (thread == null) { 2945 return null; 2946 } 2947 2948 int appIndex = getLRURecordIndexForAppLocked(thread); 2949 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2950 } 2951 2952 final void appDiedLocked(ProcessRecord app, int pid, 2953 IApplicationThread thread) { 2954 2955 mProcDeaths[0]++; 2956 2957 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2958 synchronized (stats) { 2959 stats.noteProcessDiedLocked(app.info.uid, pid); 2960 } 2961 2962 // Clean up already done if the process has been re-started. 2963 if (app.pid == pid && app.thread != null && 2964 app.thread.asBinder() == thread.asBinder()) { 2965 if (!app.killedBackground) { 2966 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2967 + ") has died."); 2968 } 2969 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2970 if (localLOGV) Slog.v( 2971 TAG, "Dying app: " + app + ", pid: " + pid 2972 + ", thread: " + thread.asBinder()); 2973 boolean doLowMem = app.instrumentationClass == null; 2974 handleAppDiedLocked(app, false, true); 2975 2976 if (doLowMem) { 2977 // If there are no longer any background processes running, 2978 // and the app that died was not running instrumentation, 2979 // then tell everyone we are now low on memory. 2980 boolean haveBg = false; 2981 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2982 ProcessRecord rec = mLruProcesses.get(i); 2983 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2984 haveBg = true; 2985 break; 2986 } 2987 } 2988 2989 if (!haveBg) { 2990 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2991 long now = SystemClock.uptimeMillis(); 2992 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2993 ProcessRecord rec = mLruProcesses.get(i); 2994 if (rec != app && rec.thread != null && 2995 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2996 // The low memory report is overriding any current 2997 // state for a GC request. Make sure to do 2998 // heavy/important/visible/foreground processes first. 2999 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3000 rec.lastRequestedGc = 0; 3001 } else { 3002 rec.lastRequestedGc = rec.lastLowMemory; 3003 } 3004 rec.reportLowMemory = true; 3005 rec.lastLowMemory = now; 3006 mProcessesToGc.remove(rec); 3007 addProcessToGcListLocked(rec); 3008 } 3009 } 3010 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3011 scheduleAppGcsLocked(); 3012 } 3013 } 3014 } else if (app.pid != pid) { 3015 // A new process has already been started. 3016 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3017 + ") has died and restarted (pid " + app.pid + ")."); 3018 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3019 } else if (DEBUG_PROCESSES) { 3020 Slog.d(TAG, "Received spurious death notification for thread " 3021 + thread.asBinder()); 3022 } 3023 } 3024 3025 /** 3026 * If a stack trace dump file is configured, dump process stack traces. 3027 * @param clearTraces causes the dump file to be erased prior to the new 3028 * traces being written, if true; when false, the new traces will be 3029 * appended to any existing file content. 3030 * @param firstPids of dalvik VM processes to dump stack traces for first 3031 * @param lastPids of dalvik VM processes to dump stack traces for last 3032 * @param nativeProcs optional list of native process names to dump stack crawls 3033 * @return file containing stack traces, or null if no dump file is configured 3034 */ 3035 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3036 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3037 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3038 if (tracesPath == null || tracesPath.length() == 0) { 3039 return null; 3040 } 3041 3042 File tracesFile = new File(tracesPath); 3043 try { 3044 File tracesDir = tracesFile.getParentFile(); 3045 if (!tracesDir.exists()) tracesFile.mkdirs(); 3046 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3047 3048 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3049 tracesFile.createNewFile(); 3050 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3051 } catch (IOException e) { 3052 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3053 return null; 3054 } 3055 3056 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3057 return tracesFile; 3058 } 3059 3060 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3061 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3062 // Use a FileObserver to detect when traces finish writing. 3063 // The order of traces is considered important to maintain for legibility. 3064 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3065 public synchronized void onEvent(int event, String path) { notify(); } 3066 }; 3067 3068 try { 3069 observer.startWatching(); 3070 3071 // First collect all of the stacks of the most important pids. 3072 if (firstPids != null) { 3073 try { 3074 int num = firstPids.size(); 3075 for (int i = 0; i < num; i++) { 3076 synchronized (observer) { 3077 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3078 observer.wait(200); // Wait for write-close, give up after 200msec 3079 } 3080 } 3081 } catch (InterruptedException e) { 3082 Log.wtf(TAG, e); 3083 } 3084 } 3085 3086 // Next measure CPU usage. 3087 if (processStats != null) { 3088 processStats.init(); 3089 System.gc(); 3090 processStats.update(); 3091 try { 3092 synchronized (processStats) { 3093 processStats.wait(500); // measure over 1/2 second. 3094 } 3095 } catch (InterruptedException e) { 3096 } 3097 processStats.update(); 3098 3099 // We'll take the stack crawls of just the top apps using CPU. 3100 final int N = processStats.countWorkingStats(); 3101 int numProcs = 0; 3102 for (int i=0; i<N && numProcs<5; i++) { 3103 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3104 if (lastPids.indexOfKey(stats.pid) >= 0) { 3105 numProcs++; 3106 try { 3107 synchronized (observer) { 3108 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3109 observer.wait(200); // Wait for write-close, give up after 200msec 3110 } 3111 } catch (InterruptedException e) { 3112 Log.wtf(TAG, e); 3113 } 3114 3115 } 3116 } 3117 } 3118 3119 } finally { 3120 observer.stopWatching(); 3121 } 3122 3123 if (nativeProcs != null) { 3124 int[] pids = Process.getPidsForCommands(nativeProcs); 3125 if (pids != null) { 3126 for (int pid : pids) { 3127 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3128 } 3129 } 3130 } 3131 } 3132 3133 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3134 if (true || IS_USER_BUILD) { 3135 return; 3136 } 3137 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3138 if (tracesPath == null || tracesPath.length() == 0) { 3139 return; 3140 } 3141 3142 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3143 StrictMode.allowThreadDiskWrites(); 3144 try { 3145 final File tracesFile = new File(tracesPath); 3146 final File tracesDir = tracesFile.getParentFile(); 3147 final File tracesTmp = new File(tracesDir, "__tmp__"); 3148 try { 3149 if (!tracesDir.exists()) tracesFile.mkdirs(); 3150 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3151 3152 if (tracesFile.exists()) { 3153 tracesTmp.delete(); 3154 tracesFile.renameTo(tracesTmp); 3155 } 3156 StringBuilder sb = new StringBuilder(); 3157 Time tobj = new Time(); 3158 tobj.set(System.currentTimeMillis()); 3159 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3160 sb.append(": "); 3161 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3162 sb.append(" since "); 3163 sb.append(msg); 3164 FileOutputStream fos = new FileOutputStream(tracesFile); 3165 fos.write(sb.toString().getBytes()); 3166 if (app == null) { 3167 fos.write("\n*** No application process!".getBytes()); 3168 } 3169 fos.close(); 3170 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3171 } catch (IOException e) { 3172 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3173 return; 3174 } 3175 3176 if (app != null) { 3177 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3178 firstPids.add(app.pid); 3179 dumpStackTraces(tracesPath, firstPids, null, null, null); 3180 } 3181 3182 File lastTracesFile = null; 3183 File curTracesFile = null; 3184 for (int i=9; i>=0; i--) { 3185 String name = String.format("slow%02d.txt", i); 3186 curTracesFile = new File(tracesDir, name); 3187 if (curTracesFile.exists()) { 3188 if (lastTracesFile != null) { 3189 curTracesFile.renameTo(lastTracesFile); 3190 } else { 3191 curTracesFile.delete(); 3192 } 3193 } 3194 lastTracesFile = curTracesFile; 3195 } 3196 tracesFile.renameTo(curTracesFile); 3197 if (tracesTmp.exists()) { 3198 tracesTmp.renameTo(tracesFile); 3199 } 3200 } finally { 3201 StrictMode.setThreadPolicy(oldPolicy); 3202 } 3203 } 3204 3205 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3206 ActivityRecord parent, final String annotation) { 3207 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3208 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3209 3210 if (mController != null) { 3211 try { 3212 // 0 == continue, -1 = kill process immediately 3213 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3214 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3215 } catch (RemoteException e) { 3216 mController = null; 3217 } 3218 } 3219 3220 long anrTime = SystemClock.uptimeMillis(); 3221 if (MONITOR_CPU_USAGE) { 3222 updateCpuStatsNow(); 3223 } 3224 3225 synchronized (this) { 3226 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3227 if (mShuttingDown) { 3228 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3229 return; 3230 } else if (app.notResponding) { 3231 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3232 return; 3233 } else if (app.crashing) { 3234 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3235 return; 3236 } 3237 3238 // In case we come through here for the same app before completing 3239 // this one, mark as anring now so we will bail out. 3240 app.notResponding = true; 3241 3242 // Log the ANR to the event log. 3243 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3244 annotation); 3245 3246 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3247 firstPids.add(app.pid); 3248 3249 int parentPid = app.pid; 3250 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3251 if (parentPid != app.pid) firstPids.add(parentPid); 3252 3253 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3254 3255 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3256 ProcessRecord r = mLruProcesses.get(i); 3257 if (r != null && r.thread != null) { 3258 int pid = r.pid; 3259 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3260 if (r.persistent) { 3261 firstPids.add(pid); 3262 } else { 3263 lastPids.put(pid, Boolean.TRUE); 3264 } 3265 } 3266 } 3267 } 3268 } 3269 3270 // Log the ANR to the main log. 3271 StringBuilder info = new StringBuilder(); 3272 info.setLength(0); 3273 info.append("ANR in ").append(app.processName); 3274 if (activity != null && activity.shortComponentName != null) { 3275 info.append(" (").append(activity.shortComponentName).append(")"); 3276 } 3277 info.append("\n"); 3278 if (annotation != null) { 3279 info.append("Reason: ").append(annotation).append("\n"); 3280 } 3281 if (parent != null && parent != activity) { 3282 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3283 } 3284 3285 final ProcessStats processStats = new ProcessStats(true); 3286 3287 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3288 3289 String cpuInfo = null; 3290 if (MONITOR_CPU_USAGE) { 3291 updateCpuStatsNow(); 3292 synchronized (mProcessStatsThread) { 3293 cpuInfo = mProcessStats.printCurrentState(anrTime); 3294 } 3295 info.append(processStats.printCurrentLoad()); 3296 info.append(cpuInfo); 3297 } 3298 3299 info.append(processStats.printCurrentState(anrTime)); 3300 3301 Slog.e(TAG, info.toString()); 3302 if (tracesFile == null) { 3303 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3304 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3305 } 3306 3307 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3308 cpuInfo, tracesFile, null); 3309 3310 if (mController != null) { 3311 try { 3312 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3313 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3314 if (res != 0) { 3315 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3316 return; 3317 } 3318 } catch (RemoteException e) { 3319 mController = null; 3320 } 3321 } 3322 3323 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3324 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3325 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3326 3327 synchronized (this) { 3328 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3329 Slog.w(TAG, "Killing " + app + ": background ANR"); 3330 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3331 app.processName, app.setAdj, "background ANR"); 3332 Process.killProcessQuiet(app.pid); 3333 return; 3334 } 3335 3336 // Set the app's notResponding state, and look up the errorReportReceiver 3337 makeAppNotRespondingLocked(app, 3338 activity != null ? activity.shortComponentName : null, 3339 annotation != null ? "ANR " + annotation : "ANR", 3340 info.toString()); 3341 3342 // Bring up the infamous App Not Responding dialog 3343 Message msg = Message.obtain(); 3344 HashMap map = new HashMap(); 3345 msg.what = SHOW_NOT_RESPONDING_MSG; 3346 msg.obj = map; 3347 map.put("app", app); 3348 if (activity != null) { 3349 map.put("activity", activity); 3350 } 3351 3352 mHandler.sendMessage(msg); 3353 } 3354 } 3355 3356 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3357 if (!mLaunchWarningShown) { 3358 mLaunchWarningShown = true; 3359 mHandler.post(new Runnable() { 3360 @Override 3361 public void run() { 3362 synchronized (ActivityManagerService.this) { 3363 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3364 d.show(); 3365 mHandler.postDelayed(new Runnable() { 3366 @Override 3367 public void run() { 3368 synchronized (ActivityManagerService.this) { 3369 d.dismiss(); 3370 mLaunchWarningShown = false; 3371 } 3372 } 3373 }, 4000); 3374 } 3375 } 3376 }); 3377 } 3378 } 3379 3380 public boolean clearApplicationUserData(final String packageName, 3381 final IPackageDataObserver observer, final int userId) { 3382 enforceNotIsolatedCaller("clearApplicationUserData"); 3383 int uid = Binder.getCallingUid(); 3384 int pid = Binder.getCallingPid(); 3385 long callingId = Binder.clearCallingIdentity(); 3386 try { 3387 IPackageManager pm = AppGlobals.getPackageManager(); 3388 int pkgUid = -1; 3389 synchronized(this) { 3390 try { 3391 pkgUid = pm.getPackageUid(packageName, userId); 3392 } catch (RemoteException e) { 3393 } 3394 if (pkgUid == -1) { 3395 Slog.w(TAG, "Invalid packageName:" + packageName); 3396 return false; 3397 } 3398 if (uid == pkgUid || checkComponentPermission( 3399 android.Manifest.permission.CLEAR_APP_USER_DATA, 3400 pid, uid, -1, true) 3401 == PackageManager.PERMISSION_GRANTED) { 3402 forceStopPackageLocked(packageName, pkgUid); 3403 } else { 3404 throw new SecurityException(pid+" does not have permission:"+ 3405 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3406 "for process:"+packageName); 3407 } 3408 } 3409 3410 try { 3411 //clear application user data 3412 pm.clearApplicationUserData(packageName, observer, userId); 3413 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3414 Uri.fromParts("package", packageName, null)); 3415 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3416 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3417 null, null, 0, null, null, null, false, false, userId); 3418 } catch (RemoteException e) { 3419 } 3420 } finally { 3421 Binder.restoreCallingIdentity(callingId); 3422 } 3423 return true; 3424 } 3425 3426 public void killBackgroundProcesses(final String packageName) { 3427 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3428 != PackageManager.PERMISSION_GRANTED && 3429 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3430 != PackageManager.PERMISSION_GRANTED) { 3431 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3432 + Binder.getCallingPid() 3433 + ", uid=" + Binder.getCallingUid() 3434 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3435 Slog.w(TAG, msg); 3436 throw new SecurityException(msg); 3437 } 3438 3439 int userId = UserHandle.getCallingUserId(); 3440 long callingId = Binder.clearCallingIdentity(); 3441 try { 3442 IPackageManager pm = AppGlobals.getPackageManager(); 3443 int pkgUid = -1; 3444 synchronized(this) { 3445 try { 3446 pkgUid = pm.getPackageUid(packageName, userId); 3447 } catch (RemoteException e) { 3448 } 3449 if (pkgUid == -1) { 3450 Slog.w(TAG, "Invalid packageName: " + packageName); 3451 return; 3452 } 3453 killPackageProcessesLocked(packageName, pkgUid, 3454 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3455 } 3456 } finally { 3457 Binder.restoreCallingIdentity(callingId); 3458 } 3459 } 3460 3461 public void killAllBackgroundProcesses() { 3462 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3463 != PackageManager.PERMISSION_GRANTED) { 3464 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3465 + Binder.getCallingPid() 3466 + ", uid=" + Binder.getCallingUid() 3467 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3468 Slog.w(TAG, msg); 3469 throw new SecurityException(msg); 3470 } 3471 3472 long callingId = Binder.clearCallingIdentity(); 3473 try { 3474 synchronized(this) { 3475 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3476 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3477 final int NA = apps.size(); 3478 for (int ia=0; ia<NA; ia++) { 3479 ProcessRecord app = apps.valueAt(ia); 3480 if (app.persistent) { 3481 // we don't kill persistent processes 3482 continue; 3483 } 3484 if (app.removed) { 3485 procs.add(app); 3486 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3487 app.removed = true; 3488 procs.add(app); 3489 } 3490 } 3491 } 3492 3493 int N = procs.size(); 3494 for (int i=0; i<N; i++) { 3495 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3496 } 3497 } 3498 } finally { 3499 Binder.restoreCallingIdentity(callingId); 3500 } 3501 } 3502 3503 public void forceStopPackage(final String packageName) { 3504 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3505 != PackageManager.PERMISSION_GRANTED) { 3506 String msg = "Permission Denial: forceStopPackage() from pid=" 3507 + Binder.getCallingPid() 3508 + ", uid=" + Binder.getCallingUid() 3509 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3510 Slog.w(TAG, msg); 3511 throw new SecurityException(msg); 3512 } 3513 final int userId = UserHandle.getCallingUserId(); 3514 long callingId = Binder.clearCallingIdentity(); 3515 try { 3516 IPackageManager pm = AppGlobals.getPackageManager(); 3517 int pkgUid = -1; 3518 synchronized(this) { 3519 try { 3520 pkgUid = pm.getPackageUid(packageName, userId); 3521 } catch (RemoteException e) { 3522 } 3523 if (pkgUid == -1) { 3524 Slog.w(TAG, "Invalid packageName: " + packageName); 3525 return; 3526 } 3527 forceStopPackageLocked(packageName, pkgUid); 3528 try { 3529 pm.setPackageStoppedState(packageName, true, userId); 3530 } catch (RemoteException e) { 3531 } catch (IllegalArgumentException e) { 3532 Slog.w(TAG, "Failed trying to unstop package " 3533 + packageName + ": " + e); 3534 } 3535 } 3536 } finally { 3537 Binder.restoreCallingIdentity(callingId); 3538 } 3539 } 3540 3541 /* 3542 * The pkg name and uid have to be specified. 3543 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3544 */ 3545 public void killApplicationWithUid(String pkg, int uid) { 3546 if (pkg == null) { 3547 return; 3548 } 3549 // Make sure the uid is valid. 3550 if (uid < 0) { 3551 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3552 return; 3553 } 3554 int callerUid = Binder.getCallingUid(); 3555 // Only the system server can kill an application 3556 if (callerUid == Process.SYSTEM_UID) { 3557 // Post an aysnc message to kill the application 3558 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3559 msg.arg1 = uid; 3560 msg.arg2 = 0; 3561 msg.obj = pkg; 3562 mHandler.sendMessage(msg); 3563 } else { 3564 throw new SecurityException(callerUid + " cannot kill pkg: " + 3565 pkg); 3566 } 3567 } 3568 3569 public void closeSystemDialogs(String reason) { 3570 enforceNotIsolatedCaller("closeSystemDialogs"); 3571 3572 final int uid = Binder.getCallingUid(); 3573 final long origId = Binder.clearCallingIdentity(); 3574 synchronized (this) { 3575 closeSystemDialogsLocked(uid, reason); 3576 } 3577 Binder.restoreCallingIdentity(origId); 3578 } 3579 3580 void closeSystemDialogsLocked(int callingUid, String reason) { 3581 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3582 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3583 if (reason != null) { 3584 intent.putExtra("reason", reason); 3585 } 3586 mWindowManager.closeSystemDialogs(reason); 3587 3588 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3589 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3590 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3591 r.stack.finishActivityLocked(r, i, 3592 Activity.RESULT_CANCELED, null, "close-sys"); 3593 } 3594 } 3595 3596 broadcastIntentLocked(null, null, intent, null, 3597 null, 0, null, null, null, false, false, -1, 3598 callingUid, 0 /* TODO: Verify */); 3599 } 3600 3601 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3602 throws RemoteException { 3603 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3604 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3605 for (int i=pids.length-1; i>=0; i--) { 3606 infos[i] = new Debug.MemoryInfo(); 3607 Debug.getMemoryInfo(pids[i], infos[i]); 3608 } 3609 return infos; 3610 } 3611 3612 public long[] getProcessPss(int[] pids) throws RemoteException { 3613 enforceNotIsolatedCaller("getProcessPss"); 3614 long[] pss = new long[pids.length]; 3615 for (int i=pids.length-1; i>=0; i--) { 3616 pss[i] = Debug.getPss(pids[i]); 3617 } 3618 return pss; 3619 } 3620 3621 public void killApplicationProcess(String processName, int uid) { 3622 if (processName == null) { 3623 return; 3624 } 3625 3626 int callerUid = Binder.getCallingUid(); 3627 // Only the system server can kill an application 3628 if (callerUid == Process.SYSTEM_UID) { 3629 synchronized (this) { 3630 ProcessRecord app = getProcessRecordLocked(processName, uid); 3631 if (app != null && app.thread != null) { 3632 try { 3633 app.thread.scheduleSuicide(); 3634 } catch (RemoteException e) { 3635 // If the other end already died, then our work here is done. 3636 } 3637 } else { 3638 Slog.w(TAG, "Process/uid not found attempting kill of " 3639 + processName + " / " + uid); 3640 } 3641 } 3642 } else { 3643 throw new SecurityException(callerUid + " cannot kill app process: " + 3644 processName); 3645 } 3646 } 3647 3648 private void forceStopPackageLocked(final String packageName, int uid) { 3649 forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid)); 3650 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3651 Uri.fromParts("package", packageName, null)); 3652 if (!mProcessesReady) { 3653 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3654 } 3655 intent.putExtra(Intent.EXTRA_UID, uid); 3656 broadcastIntentLocked(null, null, intent, 3657 null, null, 0, null, null, null, 3658 false, false, 3659 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3660 } 3661 3662 private final boolean killPackageProcessesLocked(String packageName, int uid, 3663 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3664 boolean evenPersistent, String reason) { 3665 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3666 3667 // Remove all processes this package may have touched: all with the 3668 // same UID (except for the system or root user), and all whose name 3669 // matches the package name. 3670 final String procNamePrefix = packageName + ":"; 3671 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3672 final int NA = apps.size(); 3673 for (int ia=0; ia<NA; ia++) { 3674 ProcessRecord app = apps.valueAt(ia); 3675 if (app.persistent && !evenPersistent) { 3676 // we don't kill persistent processes 3677 continue; 3678 } 3679 if (app.removed) { 3680 if (doit) { 3681 procs.add(app); 3682 } 3683 // If uid is specified and the uid and process name match 3684 // Or, the uid is not specified and the process name matches 3685 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3686 || ((app.processName.equals(packageName) 3687 || app.processName.startsWith(procNamePrefix)) 3688 && uid < 0))) { 3689 if (app.setAdj >= minOomAdj) { 3690 if (!doit) { 3691 return true; 3692 } 3693 app.removed = true; 3694 procs.add(app); 3695 } 3696 } 3697 } 3698 } 3699 3700 int N = procs.size(); 3701 for (int i=0; i<N; i++) { 3702 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3703 } 3704 return N > 0; 3705 } 3706 3707 private final boolean forceStopPackageLocked(String name, int uid, 3708 boolean callerWillRestart, boolean purgeCache, boolean doit, 3709 boolean evenPersistent, int userId) { 3710 int i; 3711 int N; 3712 3713 if (uid < 0) { 3714 try { 3715 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3716 } catch (RemoteException e) { 3717 } 3718 } 3719 3720 if (doit) { 3721 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3722 3723 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3724 while (badApps.hasNext()) { 3725 SparseArray<Long> ba = badApps.next(); 3726 if (ba.get(uid) != null) { 3727 badApps.remove(); 3728 } 3729 } 3730 } 3731 3732 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3733 callerWillRestart, false, doit, evenPersistent, "force stop"); 3734 3735 TaskRecord lastTask = null; 3736 for (i=0; i<mMainStack.mHistory.size(); i++) { 3737 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3738 final boolean samePackage = r.packageName.equals(name); 3739 if (r.userId == userId 3740 && (samePackage || r.task == lastTask) 3741 && (r.app == null || evenPersistent || !r.app.persistent)) { 3742 if (!doit) { 3743 if (r.finishing) { 3744 // If this activity is just finishing, then it is not 3745 // interesting as far as something to stop. 3746 continue; 3747 } 3748 return true; 3749 } 3750 didSomething = true; 3751 Slog.i(TAG, " Force finishing activity " + r); 3752 if (samePackage) { 3753 if (r.app != null) { 3754 r.app.removed = true; 3755 } 3756 r.app = null; 3757 } 3758 lastTask = r.task; 3759 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3760 null, "force-stop", true)) { 3761 i--; 3762 } 3763 } 3764 } 3765 3766 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3767 if (!doit) { 3768 return true; 3769 } 3770 didSomething = true; 3771 } 3772 3773 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3774 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3775 if (provider.info.packageName.equals(name) 3776 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3777 if (!doit) { 3778 return true; 3779 } 3780 didSomething = true; 3781 providers.add(provider); 3782 } 3783 } 3784 3785 N = providers.size(); 3786 for (i=0; i<N; i++) { 3787 removeDyingProviderLocked(null, providers.get(i), true); 3788 } 3789 3790 if (doit) { 3791 if (purgeCache) { 3792 AttributeCache ac = AttributeCache.instance(); 3793 if (ac != null) { 3794 ac.removePackage(name); 3795 } 3796 } 3797 if (mBooted) { 3798 mMainStack.resumeTopActivityLocked(null); 3799 mMainStack.scheduleIdleLocked(); 3800 } 3801 } 3802 3803 return didSomething; 3804 } 3805 3806 private final boolean removeProcessLocked(ProcessRecord app, 3807 boolean callerWillRestart, boolean allowRestart, String reason) { 3808 final String name = app.processName; 3809 final int uid = app.uid; 3810 if (DEBUG_PROCESSES) Slog.d( 3811 TAG, "Force removing proc " + app.toShortString() + " (" + name 3812 + "/" + uid + ")"); 3813 3814 mProcessNames.remove(name, uid); 3815 mIsolatedProcesses.remove(app.uid); 3816 if (mHeavyWeightProcess == app) { 3817 mHeavyWeightProcess = null; 3818 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3819 } 3820 boolean needRestart = false; 3821 if (app.pid > 0 && app.pid != MY_PID) { 3822 int pid = app.pid; 3823 synchronized (mPidsSelfLocked) { 3824 mPidsSelfLocked.remove(pid); 3825 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3826 } 3827 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3828 handleAppDiedLocked(app, true, allowRestart); 3829 mLruProcesses.remove(app); 3830 Process.killProcessQuiet(pid); 3831 3832 if (app.persistent && !app.isolated) { 3833 if (!callerWillRestart) { 3834 addAppLocked(app.info, false); 3835 } else { 3836 needRestart = true; 3837 } 3838 } 3839 } else { 3840 mRemovedProcesses.add(app); 3841 } 3842 3843 return needRestart; 3844 } 3845 3846 private final void processStartTimedOutLocked(ProcessRecord app) { 3847 final int pid = app.pid; 3848 boolean gone = false; 3849 synchronized (mPidsSelfLocked) { 3850 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3851 if (knownApp != null && knownApp.thread == null) { 3852 mPidsSelfLocked.remove(pid); 3853 gone = true; 3854 } 3855 } 3856 3857 if (gone) { 3858 Slog.w(TAG, "Process " + app + " failed to attach"); 3859 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3860 app.processName); 3861 mProcessNames.remove(app.processName, app.uid); 3862 mIsolatedProcesses.remove(app.uid); 3863 if (mHeavyWeightProcess == app) { 3864 mHeavyWeightProcess = null; 3865 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3866 } 3867 // Take care of any launching providers waiting for this process. 3868 checkAppInLaunchingProvidersLocked(app, true); 3869 // Take care of any services that are waiting for the process. 3870 mServices.processStartTimedOutLocked(app); 3871 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3872 app.processName, app.setAdj, "start timeout"); 3873 Process.killProcessQuiet(pid); 3874 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3875 Slog.w(TAG, "Unattached app died before backup, skipping"); 3876 try { 3877 IBackupManager bm = IBackupManager.Stub.asInterface( 3878 ServiceManager.getService(Context.BACKUP_SERVICE)); 3879 bm.agentDisconnected(app.info.packageName); 3880 } catch (RemoteException e) { 3881 // Can't happen; the backup manager is local 3882 } 3883 } 3884 if (isPendingBroadcastProcessLocked(pid)) { 3885 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3886 skipPendingBroadcastLocked(pid); 3887 } 3888 } else { 3889 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3890 } 3891 } 3892 3893 private final boolean attachApplicationLocked(IApplicationThread thread, 3894 int pid) { 3895 3896 // Find the application record that is being attached... either via 3897 // the pid if we are running in multiple processes, or just pull the 3898 // next app record if we are emulating process with anonymous threads. 3899 ProcessRecord app; 3900 if (pid != MY_PID && pid >= 0) { 3901 synchronized (mPidsSelfLocked) { 3902 app = mPidsSelfLocked.get(pid); 3903 } 3904 } else { 3905 app = null; 3906 } 3907 3908 if (app == null) { 3909 Slog.w(TAG, "No pending application record for pid " + pid 3910 + " (IApplicationThread " + thread + "); dropping process"); 3911 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3912 if (pid > 0 && pid != MY_PID) { 3913 Process.killProcessQuiet(pid); 3914 } else { 3915 try { 3916 thread.scheduleExit(); 3917 } catch (Exception e) { 3918 // Ignore exceptions. 3919 } 3920 } 3921 return false; 3922 } 3923 3924 // If this application record is still attached to a previous 3925 // process, clean it up now. 3926 if (app.thread != null) { 3927 handleAppDiedLocked(app, true, true); 3928 } 3929 3930 // Tell the process all about itself. 3931 3932 if (localLOGV) Slog.v( 3933 TAG, "Binding process pid " + pid + " to record " + app); 3934 3935 String processName = app.processName; 3936 try { 3937 AppDeathRecipient adr = new AppDeathRecipient( 3938 app, pid, thread); 3939 thread.asBinder().linkToDeath(adr, 0); 3940 app.deathRecipient = adr; 3941 } catch (RemoteException e) { 3942 app.resetPackageList(); 3943 startProcessLocked(app, "link fail", processName); 3944 return false; 3945 } 3946 3947 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3948 3949 app.thread = thread; 3950 app.curAdj = app.setAdj = -100; 3951 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3952 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3953 app.forcingToForeground = null; 3954 app.foregroundServices = false; 3955 app.hasShownUi = false; 3956 app.debugging = false; 3957 3958 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3959 3960 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3961 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3962 3963 if (!normalMode) { 3964 Slog.i(TAG, "Launching preboot mode app: " + app); 3965 } 3966 3967 if (localLOGV) Slog.v( 3968 TAG, "New app record " + app 3969 + " thread=" + thread.asBinder() + " pid=" + pid); 3970 try { 3971 int testMode = IApplicationThread.DEBUG_OFF; 3972 if (mDebugApp != null && mDebugApp.equals(processName)) { 3973 testMode = mWaitForDebugger 3974 ? IApplicationThread.DEBUG_WAIT 3975 : IApplicationThread.DEBUG_ON; 3976 app.debugging = true; 3977 if (mDebugTransient) { 3978 mDebugApp = mOrigDebugApp; 3979 mWaitForDebugger = mOrigWaitForDebugger; 3980 } 3981 } 3982 String profileFile = app.instrumentationProfileFile; 3983 ParcelFileDescriptor profileFd = null; 3984 boolean profileAutoStop = false; 3985 if (mProfileApp != null && mProfileApp.equals(processName)) { 3986 mProfileProc = app; 3987 profileFile = mProfileFile; 3988 profileFd = mProfileFd; 3989 profileAutoStop = mAutoStopProfiler; 3990 } 3991 boolean enableOpenGlTrace = false; 3992 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 3993 enableOpenGlTrace = true; 3994 mOpenGlTraceApp = null; 3995 } 3996 3997 // If the app is being launched for restore or full backup, set it up specially 3998 boolean isRestrictedBackupMode = false; 3999 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4000 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4001 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4002 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4003 } 4004 4005 ensurePackageDexOpt(app.instrumentationInfo != null 4006 ? app.instrumentationInfo.packageName 4007 : app.info.packageName); 4008 if (app.instrumentationClass != null) { 4009 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4010 } 4011 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4012 + processName + " with config " + mConfiguration); 4013 ApplicationInfo appInfo = app.instrumentationInfo != null 4014 ? app.instrumentationInfo : app.info; 4015 app.compat = compatibilityInfoForPackageLocked(appInfo); 4016 if (profileFd != null) { 4017 profileFd = profileFd.dup(); 4018 } 4019 thread.bindApplication(processName, appInfo, providers, 4020 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4021 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4022 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4023 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4024 mCoreSettingsObserver.getCoreSettingsLocked()); 4025 updateLruProcessLocked(app, false, true); 4026 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4027 } catch (Exception e) { 4028 // todo: Yikes! What should we do? For now we will try to 4029 // start another process, but that could easily get us in 4030 // an infinite loop of restarting processes... 4031 Slog.w(TAG, "Exception thrown during bind!", e); 4032 4033 app.resetPackageList(); 4034 app.unlinkDeathRecipient(); 4035 startProcessLocked(app, "bind fail", processName); 4036 return false; 4037 } 4038 4039 // Remove this record from the list of starting applications. 4040 mPersistentStartingProcesses.remove(app); 4041 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4042 "Attach application locked removing on hold: " + app); 4043 mProcessesOnHold.remove(app); 4044 4045 boolean badApp = false; 4046 boolean didSomething = false; 4047 4048 // See if the top visible activity is waiting to run in this process... 4049 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4050 if (hr != null && normalMode) { 4051 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4052 && processName.equals(hr.processName)) { 4053 try { 4054 if (mHeadless) { 4055 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4056 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4057 didSomething = true; 4058 } 4059 } catch (Exception e) { 4060 Slog.w(TAG, "Exception in new application when starting activity " 4061 + hr.intent.getComponent().flattenToShortString(), e); 4062 badApp = true; 4063 } 4064 } else { 4065 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4066 } 4067 } 4068 4069 // Find any services that should be running in this process... 4070 if (!badApp) { 4071 try { 4072 didSomething |= mServices.attachApplicationLocked(app, processName); 4073 } catch (Exception e) { 4074 badApp = true; 4075 } 4076 } 4077 4078 // Check if a next-broadcast receiver is in this process... 4079 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4080 try { 4081 didSomething = sendPendingBroadcastsLocked(app); 4082 } catch (Exception e) { 4083 // If the app died trying to launch the receiver we declare it 'bad' 4084 badApp = true; 4085 } 4086 } 4087 4088 // Check whether the next backup agent is in this process... 4089 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4090 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4091 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4092 try { 4093 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4094 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4095 mBackupTarget.backupMode); 4096 } catch (Exception e) { 4097 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4098 e.printStackTrace(); 4099 } 4100 } 4101 4102 if (badApp) { 4103 // todo: Also need to kill application to deal with all 4104 // kinds of exceptions. 4105 handleAppDiedLocked(app, false, true); 4106 return false; 4107 } 4108 4109 if (!didSomething) { 4110 updateOomAdjLocked(); 4111 } 4112 4113 return true; 4114 } 4115 4116 public final void attachApplication(IApplicationThread thread) { 4117 synchronized (this) { 4118 int callingPid = Binder.getCallingPid(); 4119 final long origId = Binder.clearCallingIdentity(); 4120 attachApplicationLocked(thread, callingPid); 4121 Binder.restoreCallingIdentity(origId); 4122 } 4123 } 4124 4125 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4126 final long origId = Binder.clearCallingIdentity(); 4127 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4128 if (stopProfiling) { 4129 synchronized (this) { 4130 if (mProfileProc == r.app) { 4131 if (mProfileFd != null) { 4132 try { 4133 mProfileFd.close(); 4134 } catch (IOException e) { 4135 } 4136 clearProfilerLocked(); 4137 } 4138 } 4139 } 4140 } 4141 Binder.restoreCallingIdentity(origId); 4142 } 4143 4144 void enableScreenAfterBoot() { 4145 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4146 SystemClock.uptimeMillis()); 4147 mWindowManager.enableScreenAfterBoot(); 4148 4149 synchronized (this) { 4150 updateEventDispatchingLocked(); 4151 } 4152 } 4153 4154 public void showBootMessage(final CharSequence msg, final boolean always) { 4155 enforceNotIsolatedCaller("showBootMessage"); 4156 mWindowManager.showBootMessage(msg, always); 4157 } 4158 4159 public void dismissKeyguardOnNextActivity() { 4160 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4161 final long token = Binder.clearCallingIdentity(); 4162 try { 4163 synchronized (this) { 4164 if (mLockScreenShown) { 4165 mLockScreenShown = false; 4166 comeOutOfSleepIfNeededLocked(); 4167 } 4168 mMainStack.dismissKeyguardOnNextActivityLocked(); 4169 } 4170 } finally { 4171 Binder.restoreCallingIdentity(token); 4172 } 4173 } 4174 4175 final void finishBooting() { 4176 IntentFilter pkgFilter = new IntentFilter(); 4177 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4178 pkgFilter.addDataScheme("package"); 4179 mContext.registerReceiver(new BroadcastReceiver() { 4180 @Override 4181 public void onReceive(Context context, Intent intent) { 4182 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4183 if (pkgs != null) { 4184 for (String pkg : pkgs) { 4185 synchronized (ActivityManagerService.this) { 4186 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4187 setResultCode(Activity.RESULT_OK); 4188 return; 4189 } 4190 } 4191 } 4192 } 4193 } 4194 }, pkgFilter); 4195 4196 IntentFilter userFilter = new IntentFilter(); 4197 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4198 mContext.registerReceiver(new BroadcastReceiver() { 4199 @Override 4200 public void onReceive(Context context, Intent intent) { 4201 onUserRemoved(intent); 4202 } 4203 }, userFilter); 4204 4205 synchronized (this) { 4206 // Ensure that any processes we had put on hold are now started 4207 // up. 4208 final int NP = mProcessesOnHold.size(); 4209 if (NP > 0) { 4210 ArrayList<ProcessRecord> procs = 4211 new ArrayList<ProcessRecord>(mProcessesOnHold); 4212 for (int ip=0; ip<NP; ip++) { 4213 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4214 + procs.get(ip)); 4215 startProcessLocked(procs.get(ip), "on-hold", null); 4216 } 4217 } 4218 4219 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4220 // Start looking for apps that are abusing wake locks. 4221 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4222 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4223 // Tell anyone interested that we are done booting! 4224 SystemProperties.set("sys.boot_completed", "1"); 4225 SystemProperties.set("dev.bootcomplete", "1"); 4226 List<UserInfo> users = getUserManager().getUsers(); 4227 for (UserInfo user : users) { 4228 broadcastIntentLocked(null, null, 4229 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4230 null, null, 0, null, null, 4231 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4232 false, false, MY_PID, Process.SYSTEM_UID, user.id); 4233 } 4234 } 4235 } 4236 } 4237 4238 final void ensureBootCompleted() { 4239 boolean booting; 4240 boolean enableScreen; 4241 synchronized (this) { 4242 booting = mBooting; 4243 mBooting = false; 4244 enableScreen = !mBooted; 4245 mBooted = true; 4246 } 4247 4248 if (booting) { 4249 finishBooting(); 4250 } 4251 4252 if (enableScreen) { 4253 enableScreenAfterBoot(); 4254 } 4255 } 4256 4257 public final void activityPaused(IBinder token) { 4258 final long origId = Binder.clearCallingIdentity(); 4259 mMainStack.activityPaused(token, false); 4260 Binder.restoreCallingIdentity(origId); 4261 } 4262 4263 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4264 CharSequence description) { 4265 if (localLOGV) Slog.v( 4266 TAG, "Activity stopped: token=" + token); 4267 4268 // Refuse possible leaked file descriptors 4269 if (icicle != null && icicle.hasFileDescriptors()) { 4270 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4271 } 4272 4273 ActivityRecord r = null; 4274 4275 final long origId = Binder.clearCallingIdentity(); 4276 4277 synchronized (this) { 4278 r = mMainStack.isInStackLocked(token); 4279 if (r != null) { 4280 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4281 } 4282 } 4283 4284 if (r != null) { 4285 sendPendingThumbnail(r, null, null, null, false); 4286 } 4287 4288 trimApplications(); 4289 4290 Binder.restoreCallingIdentity(origId); 4291 } 4292 4293 public final void activityDestroyed(IBinder token) { 4294 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4295 mMainStack.activityDestroyed(token); 4296 } 4297 4298 public String getCallingPackage(IBinder token) { 4299 synchronized (this) { 4300 ActivityRecord r = getCallingRecordLocked(token); 4301 return r != null && r.app != null ? r.info.packageName : null; 4302 } 4303 } 4304 4305 public ComponentName getCallingActivity(IBinder token) { 4306 synchronized (this) { 4307 ActivityRecord r = getCallingRecordLocked(token); 4308 return r != null ? r.intent.getComponent() : null; 4309 } 4310 } 4311 4312 private ActivityRecord getCallingRecordLocked(IBinder token) { 4313 ActivityRecord r = mMainStack.isInStackLocked(token); 4314 if (r == null) { 4315 return null; 4316 } 4317 return r.resultTo; 4318 } 4319 4320 public ComponentName getActivityClassForToken(IBinder token) { 4321 synchronized(this) { 4322 ActivityRecord r = mMainStack.isInStackLocked(token); 4323 if (r == null) { 4324 return null; 4325 } 4326 return r.intent.getComponent(); 4327 } 4328 } 4329 4330 public String getPackageForToken(IBinder token) { 4331 synchronized(this) { 4332 ActivityRecord r = mMainStack.isInStackLocked(token); 4333 if (r == null) { 4334 return null; 4335 } 4336 return r.packageName; 4337 } 4338 } 4339 4340 public IIntentSender getIntentSender(int type, 4341 String packageName, IBinder token, String resultWho, 4342 int requestCode, Intent[] intents, String[] resolvedTypes, 4343 int flags, Bundle options) { 4344 enforceNotIsolatedCaller("getIntentSender"); 4345 // Refuse possible leaked file descriptors 4346 if (intents != null) { 4347 if (intents.length < 1) { 4348 throw new IllegalArgumentException("Intents array length must be >= 1"); 4349 } 4350 for (int i=0; i<intents.length; i++) { 4351 Intent intent = intents[i]; 4352 if (intent != null) { 4353 if (intent.hasFileDescriptors()) { 4354 throw new IllegalArgumentException("File descriptors passed in Intent"); 4355 } 4356 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4357 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4358 throw new IllegalArgumentException( 4359 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4360 } 4361 intents[i] = new Intent(intent); 4362 } 4363 } 4364 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4365 throw new IllegalArgumentException( 4366 "Intent array length does not match resolvedTypes length"); 4367 } 4368 } 4369 if (options != null) { 4370 if (options.hasFileDescriptors()) { 4371 throw new IllegalArgumentException("File descriptors passed in options"); 4372 } 4373 } 4374 4375 synchronized(this) { 4376 int callingUid = Binder.getCallingUid(); 4377 try { 4378 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4379 int uid = AppGlobals.getPackageManager() 4380 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4381 if (!UserHandle.isSameApp(callingUid, uid)) { 4382 String msg = "Permission Denial: getIntentSender() from pid=" 4383 + Binder.getCallingPid() 4384 + ", uid=" + Binder.getCallingUid() 4385 + ", (need uid=" + uid + ")" 4386 + " is not allowed to send as package " + packageName; 4387 Slog.w(TAG, msg); 4388 throw new SecurityException(msg); 4389 } 4390 } 4391 4392 if (DEBUG_MU) 4393 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4394 + Binder.getOrigCallingUid()); 4395 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4396 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4397 4398 } catch (RemoteException e) { 4399 throw new SecurityException(e); 4400 } 4401 } 4402 } 4403 4404 IIntentSender getIntentSenderLocked(int type, 4405 String packageName, int callingUid, IBinder token, String resultWho, 4406 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4407 Bundle options) { 4408 if (DEBUG_MU) 4409 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4410 ActivityRecord activity = null; 4411 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4412 activity = mMainStack.isInStackLocked(token); 4413 if (activity == null) { 4414 return null; 4415 } 4416 if (activity.finishing) { 4417 return null; 4418 } 4419 } 4420 4421 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4422 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4423 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4424 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4425 |PendingIntent.FLAG_UPDATE_CURRENT); 4426 4427 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4428 type, packageName, activity, resultWho, 4429 requestCode, intents, resolvedTypes, flags, options); 4430 WeakReference<PendingIntentRecord> ref; 4431 ref = mIntentSenderRecords.get(key); 4432 PendingIntentRecord rec = ref != null ? ref.get() : null; 4433 if (rec != null) { 4434 if (!cancelCurrent) { 4435 if (updateCurrent) { 4436 if (rec.key.requestIntent != null) { 4437 rec.key.requestIntent.replaceExtras(intents != null ? 4438 intents[intents.length - 1] : null); 4439 } 4440 if (intents != null) { 4441 intents[intents.length-1] = rec.key.requestIntent; 4442 rec.key.allIntents = intents; 4443 rec.key.allResolvedTypes = resolvedTypes; 4444 } else { 4445 rec.key.allIntents = null; 4446 rec.key.allResolvedTypes = null; 4447 } 4448 } 4449 return rec; 4450 } 4451 rec.canceled = true; 4452 mIntentSenderRecords.remove(key); 4453 } 4454 if (noCreate) { 4455 return rec; 4456 } 4457 rec = new PendingIntentRecord(this, key, callingUid); 4458 mIntentSenderRecords.put(key, rec.ref); 4459 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4460 if (activity.pendingResults == null) { 4461 activity.pendingResults 4462 = new HashSet<WeakReference<PendingIntentRecord>>(); 4463 } 4464 activity.pendingResults.add(rec.ref); 4465 } 4466 return rec; 4467 } 4468 4469 public void cancelIntentSender(IIntentSender sender) { 4470 if (!(sender instanceof PendingIntentRecord)) { 4471 return; 4472 } 4473 synchronized(this) { 4474 PendingIntentRecord rec = (PendingIntentRecord)sender; 4475 try { 4476 int uid = AppGlobals.getPackageManager() 4477 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4478 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4479 String msg = "Permission Denial: cancelIntentSender() from pid=" 4480 + Binder.getCallingPid() 4481 + ", uid=" + Binder.getCallingUid() 4482 + " is not allowed to cancel packges " 4483 + rec.key.packageName; 4484 Slog.w(TAG, msg); 4485 throw new SecurityException(msg); 4486 } 4487 } catch (RemoteException e) { 4488 throw new SecurityException(e); 4489 } 4490 cancelIntentSenderLocked(rec, true); 4491 } 4492 } 4493 4494 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4495 rec.canceled = true; 4496 mIntentSenderRecords.remove(rec.key); 4497 if (cleanActivity && rec.key.activity != null) { 4498 rec.key.activity.pendingResults.remove(rec.ref); 4499 } 4500 } 4501 4502 public String getPackageForIntentSender(IIntentSender pendingResult) { 4503 if (!(pendingResult instanceof PendingIntentRecord)) { 4504 return null; 4505 } 4506 try { 4507 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4508 return res.key.packageName; 4509 } catch (ClassCastException e) { 4510 } 4511 return null; 4512 } 4513 4514 public int getUidForIntentSender(IIntentSender sender) { 4515 if (sender instanceof PendingIntentRecord) { 4516 try { 4517 PendingIntentRecord res = (PendingIntentRecord)sender; 4518 return res.uid; 4519 } catch (ClassCastException e) { 4520 } 4521 } 4522 return -1; 4523 } 4524 4525 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4526 if (!(pendingResult instanceof PendingIntentRecord)) { 4527 return false; 4528 } 4529 try { 4530 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4531 if (res.key.allIntents == null) { 4532 return false; 4533 } 4534 for (int i=0; i<res.key.allIntents.length; i++) { 4535 Intent intent = res.key.allIntents[i]; 4536 if (intent.getPackage() != null && intent.getComponent() != null) { 4537 return false; 4538 } 4539 } 4540 return true; 4541 } catch (ClassCastException e) { 4542 } 4543 return false; 4544 } 4545 4546 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4547 if (!(pendingResult instanceof PendingIntentRecord)) { 4548 return false; 4549 } 4550 try { 4551 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4552 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4553 return true; 4554 } 4555 return false; 4556 } catch (ClassCastException e) { 4557 } 4558 return false; 4559 } 4560 4561 public void setProcessLimit(int max) { 4562 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4563 "setProcessLimit()"); 4564 synchronized (this) { 4565 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4566 mProcessLimitOverride = max; 4567 } 4568 trimApplications(); 4569 } 4570 4571 public int getProcessLimit() { 4572 synchronized (this) { 4573 return mProcessLimitOverride; 4574 } 4575 } 4576 4577 void foregroundTokenDied(ForegroundToken token) { 4578 synchronized (ActivityManagerService.this) { 4579 synchronized (mPidsSelfLocked) { 4580 ForegroundToken cur 4581 = mForegroundProcesses.get(token.pid); 4582 if (cur != token) { 4583 return; 4584 } 4585 mForegroundProcesses.remove(token.pid); 4586 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4587 if (pr == null) { 4588 return; 4589 } 4590 pr.forcingToForeground = null; 4591 pr.foregroundServices = false; 4592 } 4593 updateOomAdjLocked(); 4594 } 4595 } 4596 4597 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4598 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4599 "setProcessForeground()"); 4600 synchronized(this) { 4601 boolean changed = false; 4602 4603 synchronized (mPidsSelfLocked) { 4604 ProcessRecord pr = mPidsSelfLocked.get(pid); 4605 if (pr == null && isForeground) { 4606 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4607 return; 4608 } 4609 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4610 if (oldToken != null) { 4611 oldToken.token.unlinkToDeath(oldToken, 0); 4612 mForegroundProcesses.remove(pid); 4613 if (pr != null) { 4614 pr.forcingToForeground = null; 4615 } 4616 changed = true; 4617 } 4618 if (isForeground && token != null) { 4619 ForegroundToken newToken = new ForegroundToken() { 4620 public void binderDied() { 4621 foregroundTokenDied(this); 4622 } 4623 }; 4624 newToken.pid = pid; 4625 newToken.token = token; 4626 try { 4627 token.linkToDeath(newToken, 0); 4628 mForegroundProcesses.put(pid, newToken); 4629 pr.forcingToForeground = token; 4630 changed = true; 4631 } catch (RemoteException e) { 4632 // If the process died while doing this, we will later 4633 // do the cleanup with the process death link. 4634 } 4635 } 4636 } 4637 4638 if (changed) { 4639 updateOomAdjLocked(); 4640 } 4641 } 4642 } 4643 4644 // ========================================================= 4645 // PERMISSIONS 4646 // ========================================================= 4647 4648 static class PermissionController extends IPermissionController.Stub { 4649 ActivityManagerService mActivityManagerService; 4650 PermissionController(ActivityManagerService activityManagerService) { 4651 mActivityManagerService = activityManagerService; 4652 } 4653 4654 public boolean checkPermission(String permission, int pid, int uid) { 4655 return mActivityManagerService.checkPermission(permission, pid, 4656 uid) == PackageManager.PERMISSION_GRANTED; 4657 } 4658 } 4659 4660 /** 4661 * This can be called with or without the global lock held. 4662 */ 4663 int checkComponentPermission(String permission, int pid, int uid, 4664 int owningUid, boolean exported) { 4665 // We might be performing an operation on behalf of an indirect binder 4666 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4667 // client identity accordingly before proceeding. 4668 Identity tlsIdentity = sCallerIdentity.get(); 4669 if (tlsIdentity != null) { 4670 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4671 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4672 uid = tlsIdentity.uid; 4673 pid = tlsIdentity.pid; 4674 } 4675 4676 if (pid == MY_PID) { 4677 return PackageManager.PERMISSION_GRANTED; 4678 } 4679 4680 return ActivityManager.checkComponentPermission(permission, uid, 4681 owningUid, exported); 4682 } 4683 4684 /** 4685 * As the only public entry point for permissions checking, this method 4686 * can enforce the semantic that requesting a check on a null global 4687 * permission is automatically denied. (Internally a null permission 4688 * string is used when calling {@link #checkComponentPermission} in cases 4689 * when only uid-based security is needed.) 4690 * 4691 * This can be called with or without the global lock held. 4692 */ 4693 public int checkPermission(String permission, int pid, int uid) { 4694 if (permission == null) { 4695 return PackageManager.PERMISSION_DENIED; 4696 } 4697 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4698 } 4699 4700 /** 4701 * Binder IPC calls go through the public entry point. 4702 * This can be called with or without the global lock held. 4703 */ 4704 int checkCallingPermission(String permission) { 4705 return checkPermission(permission, 4706 Binder.getCallingPid(), 4707 UserHandle.getAppId(Binder.getCallingUid())); 4708 } 4709 4710 /** 4711 * This can be called with or without the global lock held. 4712 */ 4713 void enforceCallingPermission(String permission, String func) { 4714 if (checkCallingPermission(permission) 4715 == PackageManager.PERMISSION_GRANTED) { 4716 return; 4717 } 4718 4719 String msg = "Permission Denial: " + func + " from pid=" 4720 + Binder.getCallingPid() 4721 + ", uid=" + Binder.getCallingUid() 4722 + " requires " + permission; 4723 Slog.w(TAG, msg); 4724 throw new SecurityException(msg); 4725 } 4726 4727 /** 4728 * Determine if UID is holding permissions required to access {@link Uri} in 4729 * the given {@link ProviderInfo}. Final permission checking is always done 4730 * in {@link ContentProvider}. 4731 */ 4732 private final boolean checkHoldingPermissionsLocked( 4733 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4734 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4735 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4736 4737 if (pi.applicationInfo.uid == uid) { 4738 return true; 4739 } else if (!pi.exported) { 4740 return false; 4741 } 4742 4743 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4744 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4745 try { 4746 // check if target holds top-level <provider> permissions 4747 if (!readMet && pi.readPermission != null 4748 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4749 readMet = true; 4750 } 4751 if (!writeMet && pi.writePermission != null 4752 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4753 writeMet = true; 4754 } 4755 4756 // track if unprotected read/write is allowed; any denied 4757 // <path-permission> below removes this ability 4758 boolean allowDefaultRead = pi.readPermission == null; 4759 boolean allowDefaultWrite = pi.writePermission == null; 4760 4761 // check if target holds any <path-permission> that match uri 4762 final PathPermission[] pps = pi.pathPermissions; 4763 if (pps != null) { 4764 final String path = uri.getPath(); 4765 int i = pps.length; 4766 while (i > 0 && (!readMet || !writeMet)) { 4767 i--; 4768 PathPermission pp = pps[i]; 4769 if (pp.match(path)) { 4770 if (!readMet) { 4771 final String pprperm = pp.getReadPermission(); 4772 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4773 + pprperm + " for " + pp.getPath() 4774 + ": match=" + pp.match(path) 4775 + " check=" + pm.checkUidPermission(pprperm, uid)); 4776 if (pprperm != null) { 4777 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4778 readMet = true; 4779 } else { 4780 allowDefaultRead = false; 4781 } 4782 } 4783 } 4784 if (!writeMet) { 4785 final String ppwperm = pp.getWritePermission(); 4786 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4787 + ppwperm + " for " + pp.getPath() 4788 + ": match=" + pp.match(path) 4789 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4790 if (ppwperm != null) { 4791 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4792 writeMet = true; 4793 } else { 4794 allowDefaultWrite = false; 4795 } 4796 } 4797 } 4798 } 4799 } 4800 } 4801 4802 // grant unprotected <provider> read/write, if not blocked by 4803 // <path-permission> above 4804 if (allowDefaultRead) readMet = true; 4805 if (allowDefaultWrite) writeMet = true; 4806 4807 } catch (RemoteException e) { 4808 return false; 4809 } 4810 4811 return readMet && writeMet; 4812 } 4813 4814 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4815 int modeFlags) { 4816 // Root gets to do everything. 4817 if (uid == 0) { 4818 return true; 4819 } 4820 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4821 if (perms == null) return false; 4822 UriPermission perm = perms.get(uri); 4823 if (perm == null) return false; 4824 return (modeFlags&perm.modeFlags) == modeFlags; 4825 } 4826 4827 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4828 enforceNotIsolatedCaller("checkUriPermission"); 4829 4830 // Another redirected-binder-call permissions check as in 4831 // {@link checkComponentPermission}. 4832 Identity tlsIdentity = sCallerIdentity.get(); 4833 if (tlsIdentity != null) { 4834 uid = tlsIdentity.uid; 4835 pid = tlsIdentity.pid; 4836 } 4837 4838 uid = UserHandle.getAppId(uid); 4839 // Our own process gets to do everything. 4840 if (pid == MY_PID) { 4841 return PackageManager.PERMISSION_GRANTED; 4842 } 4843 synchronized(this) { 4844 return checkUriPermissionLocked(uri, uid, modeFlags) 4845 ? PackageManager.PERMISSION_GRANTED 4846 : PackageManager.PERMISSION_DENIED; 4847 } 4848 } 4849 4850 /** 4851 * Check if the targetPkg can be granted permission to access uri by 4852 * the callingUid using the given modeFlags. Throws a security exception 4853 * if callingUid is not allowed to do this. Returns the uid of the target 4854 * if the URI permission grant should be performed; returns -1 if it is not 4855 * needed (for example targetPkg already has permission to access the URI). 4856 * If you already know the uid of the target, you can supply it in 4857 * lastTargetUid else set that to -1. 4858 */ 4859 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4860 Uri uri, int modeFlags, int lastTargetUid) { 4861 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4862 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4863 if (modeFlags == 0) { 4864 return -1; 4865 } 4866 4867 if (targetPkg != null) { 4868 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4869 "Checking grant " + targetPkg + " permission to " + uri); 4870 } 4871 4872 final IPackageManager pm = AppGlobals.getPackageManager(); 4873 4874 // If this is not a content: uri, we can't do anything with it. 4875 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4876 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4877 "Can't grant URI permission for non-content URI: " + uri); 4878 return -1; 4879 } 4880 4881 String name = uri.getAuthority(); 4882 ProviderInfo pi = null; 4883 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4884 UserHandle.getUserId(callingUid)); 4885 if (cpr != null) { 4886 pi = cpr.info; 4887 } else { 4888 try { 4889 pi = pm.resolveContentProvider(name, 4890 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4891 } catch (RemoteException ex) { 4892 } 4893 } 4894 if (pi == null) { 4895 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4896 return -1; 4897 } 4898 4899 int targetUid = lastTargetUid; 4900 if (targetUid < 0 && targetPkg != null) { 4901 try { 4902 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4903 if (targetUid < 0) { 4904 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4905 "Can't grant URI permission no uid for: " + targetPkg); 4906 return -1; 4907 } 4908 } catch (RemoteException ex) { 4909 return -1; 4910 } 4911 } 4912 4913 if (targetUid >= 0) { 4914 // First... does the target actually need this permission? 4915 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4916 // No need to grant the target this permission. 4917 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4918 "Target " + targetPkg + " already has full permission to " + uri); 4919 return -1; 4920 } 4921 } else { 4922 // First... there is no target package, so can anyone access it? 4923 boolean allowed = pi.exported; 4924 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4925 if (pi.readPermission != null) { 4926 allowed = false; 4927 } 4928 } 4929 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4930 if (pi.writePermission != null) { 4931 allowed = false; 4932 } 4933 } 4934 if (allowed) { 4935 return -1; 4936 } 4937 } 4938 4939 // Second... is the provider allowing granting of URI permissions? 4940 if (!pi.grantUriPermissions) { 4941 throw new SecurityException("Provider " + pi.packageName 4942 + "/" + pi.name 4943 + " does not allow granting of Uri permissions (uri " 4944 + uri + ")"); 4945 } 4946 if (pi.uriPermissionPatterns != null) { 4947 final int N = pi.uriPermissionPatterns.length; 4948 boolean allowed = false; 4949 for (int i=0; i<N; i++) { 4950 if (pi.uriPermissionPatterns[i] != null 4951 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4952 allowed = true; 4953 break; 4954 } 4955 } 4956 if (!allowed) { 4957 throw new SecurityException("Provider " + pi.packageName 4958 + "/" + pi.name 4959 + " does not allow granting of permission to path of Uri " 4960 + uri); 4961 } 4962 } 4963 4964 // Third... does the caller itself have permission to access 4965 // this uri? 4966 if (callingUid != Process.myUid()) { 4967 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4968 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4969 throw new SecurityException("Uid " + callingUid 4970 + " does not have permission to uri " + uri); 4971 } 4972 } 4973 } 4974 4975 return targetUid; 4976 } 4977 4978 public int checkGrantUriPermission(int callingUid, String targetPkg, 4979 Uri uri, int modeFlags) { 4980 enforceNotIsolatedCaller("checkGrantUriPermission"); 4981 synchronized(this) { 4982 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 4983 } 4984 } 4985 4986 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 4987 Uri uri, int modeFlags, UriPermissionOwner owner) { 4988 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4989 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4990 if (modeFlags == 0) { 4991 return; 4992 } 4993 4994 // So here we are: the caller has the assumed permission 4995 // to the uri, and the target doesn't. Let's now give this to 4996 // the target. 4997 4998 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4999 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5000 5001 HashMap<Uri, UriPermission> targetUris 5002 = mGrantedUriPermissions.get(targetUid); 5003 if (targetUris == null) { 5004 targetUris = new HashMap<Uri, UriPermission>(); 5005 mGrantedUriPermissions.put(targetUid, targetUris); 5006 } 5007 5008 UriPermission perm = targetUris.get(uri); 5009 if (perm == null) { 5010 perm = new UriPermission(targetUid, uri); 5011 targetUris.put(uri, perm); 5012 } 5013 5014 perm.modeFlags |= modeFlags; 5015 if (owner == null) { 5016 perm.globalModeFlags |= modeFlags; 5017 } else { 5018 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5019 perm.readOwners.add(owner); 5020 owner.addReadPermission(perm); 5021 } 5022 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5023 perm.writeOwners.add(owner); 5024 owner.addWritePermission(perm); 5025 } 5026 } 5027 } 5028 5029 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5030 int modeFlags, UriPermissionOwner owner) { 5031 if (targetPkg == null) { 5032 throw new NullPointerException("targetPkg"); 5033 } 5034 5035 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5036 if (targetUid < 0) { 5037 return; 5038 } 5039 5040 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5041 } 5042 5043 static class NeededUriGrants extends ArrayList<Uri> { 5044 final String targetPkg; 5045 final int targetUid; 5046 final int flags; 5047 5048 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5049 targetPkg = _targetPkg; 5050 targetUid = _targetUid; 5051 flags = _flags; 5052 } 5053 } 5054 5055 /** 5056 * Like checkGrantUriPermissionLocked, but takes an Intent. 5057 */ 5058 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5059 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5060 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5061 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5062 + " clip=" + (intent != null ? intent.getClipData() : null) 5063 + " from " + intent + "; flags=0x" 5064 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5065 5066 if (targetPkg == null) { 5067 throw new NullPointerException("targetPkg"); 5068 } 5069 5070 if (intent == null) { 5071 return null; 5072 } 5073 Uri data = intent.getData(); 5074 ClipData clip = intent.getClipData(); 5075 if (data == null && clip == null) { 5076 return null; 5077 } 5078 if (data != null) { 5079 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5080 mode, needed != null ? needed.targetUid : -1); 5081 if (target > 0) { 5082 if (needed == null) { 5083 needed = new NeededUriGrants(targetPkg, target, mode); 5084 } 5085 needed.add(data); 5086 } 5087 } 5088 if (clip != null) { 5089 for (int i=0; i<clip.getItemCount(); i++) { 5090 Uri uri = clip.getItemAt(i).getUri(); 5091 if (uri != null) { 5092 int target = -1; 5093 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5094 mode, needed != null ? needed.targetUid : -1); 5095 if (target > 0) { 5096 if (needed == null) { 5097 needed = new NeededUriGrants(targetPkg, target, mode); 5098 } 5099 needed.add(uri); 5100 } 5101 } else { 5102 Intent clipIntent = clip.getItemAt(i).getIntent(); 5103 if (clipIntent != null) { 5104 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5105 callingUid, targetPkg, clipIntent, mode, needed); 5106 if (newNeeded != null) { 5107 needed = newNeeded; 5108 } 5109 } 5110 } 5111 } 5112 } 5113 5114 return needed; 5115 } 5116 5117 /** 5118 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5119 */ 5120 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5121 UriPermissionOwner owner) { 5122 if (needed != null) { 5123 for (int i=0; i<needed.size(); i++) { 5124 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5125 needed.get(i), needed.flags, owner); 5126 } 5127 } 5128 } 5129 5130 void grantUriPermissionFromIntentLocked(int callingUid, 5131 String targetPkg, Intent intent, UriPermissionOwner owner) { 5132 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5133 intent, intent != null ? intent.getFlags() : 0, null); 5134 if (needed == null) { 5135 return; 5136 } 5137 5138 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5139 } 5140 5141 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5142 Uri uri, int modeFlags) { 5143 enforceNotIsolatedCaller("grantUriPermission"); 5144 synchronized(this) { 5145 final ProcessRecord r = getRecordForAppLocked(caller); 5146 if (r == null) { 5147 throw new SecurityException("Unable to find app for caller " 5148 + caller 5149 + " when granting permission to uri " + uri); 5150 } 5151 if (targetPkg == null) { 5152 throw new IllegalArgumentException("null target"); 5153 } 5154 if (uri == null) { 5155 throw new IllegalArgumentException("null uri"); 5156 } 5157 5158 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5159 null); 5160 } 5161 } 5162 5163 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5164 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5165 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5166 HashMap<Uri, UriPermission> perms 5167 = mGrantedUriPermissions.get(perm.uid); 5168 if (perms != null) { 5169 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5170 "Removing " + perm.uid + " permission to " + perm.uri); 5171 perms.remove(perm.uri); 5172 if (perms.size() == 0) { 5173 mGrantedUriPermissions.remove(perm.uid); 5174 } 5175 } 5176 } 5177 } 5178 5179 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5180 int modeFlags) { 5181 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5182 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5183 if (modeFlags == 0) { 5184 return; 5185 } 5186 5187 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5188 "Revoking all granted permissions to " + uri); 5189 5190 final IPackageManager pm = AppGlobals.getPackageManager(); 5191 5192 final String authority = uri.getAuthority(); 5193 ProviderInfo pi = null; 5194 int userId = UserHandle.getUserId(callingUid); 5195 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5196 if (cpr != null) { 5197 pi = cpr.info; 5198 } else { 5199 try { 5200 pi = pm.resolveContentProvider(authority, 5201 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5202 } catch (RemoteException ex) { 5203 } 5204 } 5205 if (pi == null) { 5206 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5207 return; 5208 } 5209 5210 // Does the caller have this permission on the URI? 5211 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5212 // Right now, if you are not the original owner of the permission, 5213 // you are not allowed to revoke it. 5214 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5215 throw new SecurityException("Uid " + callingUid 5216 + " does not have permission to uri " + uri); 5217 //} 5218 } 5219 5220 // Go through all of the permissions and remove any that match. 5221 final List<String> SEGMENTS = uri.getPathSegments(); 5222 if (SEGMENTS != null) { 5223 final int NS = SEGMENTS.size(); 5224 int N = mGrantedUriPermissions.size(); 5225 for (int i=0; i<N; i++) { 5226 HashMap<Uri, UriPermission> perms 5227 = mGrantedUriPermissions.valueAt(i); 5228 Iterator<UriPermission> it = perms.values().iterator(); 5229 toploop: 5230 while (it.hasNext()) { 5231 UriPermission perm = it.next(); 5232 Uri targetUri = perm.uri; 5233 if (!authority.equals(targetUri.getAuthority())) { 5234 continue; 5235 } 5236 List<String> targetSegments = targetUri.getPathSegments(); 5237 if (targetSegments == null) { 5238 continue; 5239 } 5240 if (targetSegments.size() < NS) { 5241 continue; 5242 } 5243 for (int j=0; j<NS; j++) { 5244 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5245 continue toploop; 5246 } 5247 } 5248 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5249 "Revoking " + perm.uid + " permission to " + perm.uri); 5250 perm.clearModes(modeFlags); 5251 if (perm.modeFlags == 0) { 5252 it.remove(); 5253 } 5254 } 5255 if (perms.size() == 0) { 5256 mGrantedUriPermissions.remove( 5257 mGrantedUriPermissions.keyAt(i)); 5258 N--; 5259 i--; 5260 } 5261 } 5262 } 5263 } 5264 5265 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5266 int modeFlags) { 5267 enforceNotIsolatedCaller("revokeUriPermission"); 5268 synchronized(this) { 5269 final ProcessRecord r = getRecordForAppLocked(caller); 5270 if (r == null) { 5271 throw new SecurityException("Unable to find app for caller " 5272 + caller 5273 + " when revoking permission to uri " + uri); 5274 } 5275 if (uri == null) { 5276 Slog.w(TAG, "revokeUriPermission: null uri"); 5277 return; 5278 } 5279 5280 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5281 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5282 if (modeFlags == 0) { 5283 return; 5284 } 5285 5286 final IPackageManager pm = AppGlobals.getPackageManager(); 5287 5288 final String authority = uri.getAuthority(); 5289 ProviderInfo pi = null; 5290 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5291 if (cpr != null) { 5292 pi = cpr.info; 5293 } else { 5294 try { 5295 pi = pm.resolveContentProvider(authority, 5296 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5297 } catch (RemoteException ex) { 5298 } 5299 } 5300 if (pi == null) { 5301 Slog.w(TAG, "No content provider found for permission revoke: " 5302 + uri.toSafeString()); 5303 return; 5304 } 5305 5306 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5307 } 5308 } 5309 5310 @Override 5311 public IBinder newUriPermissionOwner(String name) { 5312 enforceNotIsolatedCaller("newUriPermissionOwner"); 5313 synchronized(this) { 5314 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5315 return owner.getExternalTokenLocked(); 5316 } 5317 } 5318 5319 @Override 5320 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5321 Uri uri, int modeFlags) { 5322 synchronized(this) { 5323 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5324 if (owner == null) { 5325 throw new IllegalArgumentException("Unknown owner: " + token); 5326 } 5327 if (fromUid != Binder.getCallingUid()) { 5328 if (Binder.getCallingUid() != Process.myUid()) { 5329 // Only system code can grant URI permissions on behalf 5330 // of other users. 5331 throw new SecurityException("nice try"); 5332 } 5333 } 5334 if (targetPkg == null) { 5335 throw new IllegalArgumentException("null target"); 5336 } 5337 if (uri == null) { 5338 throw new IllegalArgumentException("null uri"); 5339 } 5340 5341 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5342 } 5343 } 5344 5345 @Override 5346 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5347 synchronized(this) { 5348 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5349 if (owner == null) { 5350 throw new IllegalArgumentException("Unknown owner: " + token); 5351 } 5352 5353 if (uri == null) { 5354 owner.removeUriPermissionsLocked(mode); 5355 } else { 5356 owner.removeUriPermissionLocked(uri, mode); 5357 } 5358 } 5359 } 5360 5361 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5362 synchronized (this) { 5363 ProcessRecord app = 5364 who != null ? getRecordForAppLocked(who) : null; 5365 if (app == null) return; 5366 5367 Message msg = Message.obtain(); 5368 msg.what = WAIT_FOR_DEBUGGER_MSG; 5369 msg.obj = app; 5370 msg.arg1 = waiting ? 1 : 0; 5371 mHandler.sendMessage(msg); 5372 } 5373 } 5374 5375 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5376 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5377 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5378 outInfo.availMem = Process.getFreeMemory(); 5379 outInfo.totalMem = Process.getTotalMemory(); 5380 outInfo.threshold = homeAppMem; 5381 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5382 outInfo.hiddenAppThreshold = hiddenAppMem; 5383 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5384 ProcessList.SERVICE_ADJ); 5385 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5386 ProcessList.VISIBLE_APP_ADJ); 5387 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5388 ProcessList.FOREGROUND_APP_ADJ); 5389 } 5390 5391 // ========================================================= 5392 // TASK MANAGEMENT 5393 // ========================================================= 5394 5395 public List getTasks(int maxNum, int flags, 5396 IThumbnailReceiver receiver) { 5397 ArrayList list = new ArrayList(); 5398 5399 PendingThumbnailsRecord pending = null; 5400 IApplicationThread topThumbnail = null; 5401 ActivityRecord topRecord = null; 5402 5403 synchronized(this) { 5404 if (localLOGV) Slog.v( 5405 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5406 + ", receiver=" + receiver); 5407 5408 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5409 != PackageManager.PERMISSION_GRANTED) { 5410 if (receiver != null) { 5411 // If the caller wants to wait for pending thumbnails, 5412 // it ain't gonna get them. 5413 try { 5414 receiver.finished(); 5415 } catch (RemoteException ex) { 5416 } 5417 } 5418 String msg = "Permission Denial: getTasks() from pid=" 5419 + Binder.getCallingPid() 5420 + ", uid=" + Binder.getCallingUid() 5421 + " requires " + android.Manifest.permission.GET_TASKS; 5422 Slog.w(TAG, msg); 5423 throw new SecurityException(msg); 5424 } 5425 5426 int pos = mMainStack.mHistory.size()-1; 5427 ActivityRecord next = 5428 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5429 ActivityRecord top = null; 5430 TaskRecord curTask = null; 5431 int numActivities = 0; 5432 int numRunning = 0; 5433 while (pos >= 0 && maxNum > 0) { 5434 final ActivityRecord r = next; 5435 pos--; 5436 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5437 5438 // Initialize state for next task if needed. 5439 if (top == null || 5440 (top.state == ActivityState.INITIALIZING 5441 && top.task == r.task)) { 5442 top = r; 5443 curTask = r.task; 5444 numActivities = numRunning = 0; 5445 } 5446 5447 // Add 'r' into the current task. 5448 numActivities++; 5449 if (r.app != null && r.app.thread != null) { 5450 numRunning++; 5451 } 5452 5453 if (localLOGV) Slog.v( 5454 TAG, r.intent.getComponent().flattenToShortString() 5455 + ": task=" + r.task); 5456 5457 // If the next one is a different task, generate a new 5458 // TaskInfo entry for what we have. 5459 if (next == null || next.task != curTask) { 5460 ActivityManager.RunningTaskInfo ci 5461 = new ActivityManager.RunningTaskInfo(); 5462 ci.id = curTask.taskId; 5463 ci.baseActivity = r.intent.getComponent(); 5464 ci.topActivity = top.intent.getComponent(); 5465 if (top.thumbHolder != null) { 5466 ci.description = top.thumbHolder.lastDescription; 5467 } 5468 ci.numActivities = numActivities; 5469 ci.numRunning = numRunning; 5470 //System.out.println( 5471 // "#" + maxNum + ": " + " descr=" + ci.description); 5472 if (ci.thumbnail == null && receiver != null) { 5473 if (localLOGV) Slog.v( 5474 TAG, "State=" + top.state + "Idle=" + top.idle 5475 + " app=" + top.app 5476 + " thr=" + (top.app != null ? top.app.thread : null)); 5477 if (top.state == ActivityState.RESUMED 5478 || top.state == ActivityState.PAUSING) { 5479 if (top.idle && top.app != null 5480 && top.app.thread != null) { 5481 topRecord = top; 5482 topThumbnail = top.app.thread; 5483 } else { 5484 top.thumbnailNeeded = true; 5485 } 5486 } 5487 if (pending == null) { 5488 pending = new PendingThumbnailsRecord(receiver); 5489 } 5490 pending.pendingRecords.add(top); 5491 } 5492 list.add(ci); 5493 maxNum--; 5494 top = null; 5495 } 5496 } 5497 5498 if (pending != null) { 5499 mPendingThumbnails.add(pending); 5500 } 5501 } 5502 5503 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5504 5505 if (topThumbnail != null) { 5506 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5507 try { 5508 topThumbnail.requestThumbnail(topRecord.appToken); 5509 } catch (Exception e) { 5510 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5511 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5512 } 5513 } 5514 5515 if (pending == null && receiver != null) { 5516 // In this case all thumbnails were available and the client 5517 // is being asked to be told when the remaining ones come in... 5518 // which is unusually, since the top-most currently running 5519 // activity should never have a canned thumbnail! Oh well. 5520 try { 5521 receiver.finished(); 5522 } catch (RemoteException ex) { 5523 } 5524 } 5525 5526 return list; 5527 } 5528 5529 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5530 int flags, int userId) { 5531 final int callingUid = Binder.getCallingUid(); 5532 if (userId != UserHandle.getCallingUserId()) { 5533 // Check if the caller is holding permissions for cross-user requests. 5534 if (checkComponentPermission( 5535 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5536 Binder.getCallingPid(), callingUid, -1, true) 5537 != PackageManager.PERMISSION_GRANTED) { 5538 String msg = "Permission Denial: " 5539 + "Request to get recent tasks for user " + userId 5540 + " but is calling from user " + UserHandle.getUserId(callingUid) 5541 + "; this requires " 5542 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5543 Slog.w(TAG, msg); 5544 throw new SecurityException(msg); 5545 } else { 5546 if (userId == UserHandle.USER_CURRENT) { 5547 userId = mCurrentUserId; 5548 } 5549 } 5550 } 5551 5552 synchronized (this) { 5553 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5554 "getRecentTasks()"); 5555 final boolean detailed = checkCallingPermission( 5556 android.Manifest.permission.GET_DETAILED_TASKS) 5557 == PackageManager.PERMISSION_GRANTED; 5558 5559 IPackageManager pm = AppGlobals.getPackageManager(); 5560 5561 final int N = mRecentTasks.size(); 5562 ArrayList<ActivityManager.RecentTaskInfo> res 5563 = new ArrayList<ActivityManager.RecentTaskInfo>( 5564 maxNum < N ? maxNum : N); 5565 for (int i=0; i<N && maxNum > 0; i++) { 5566 TaskRecord tr = mRecentTasks.get(i); 5567 // Only add calling user's recent tasks 5568 if (tr.userId != userId) continue; 5569 // Return the entry if desired by the caller. We always return 5570 // the first entry, because callers always expect this to be the 5571 // foreground app. We may filter others if the caller has 5572 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5573 // we should exclude the entry. 5574 5575 if (i == 0 5576 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5577 || (tr.intent == null) 5578 || ((tr.intent.getFlags() 5579 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5580 ActivityManager.RecentTaskInfo rti 5581 = new ActivityManager.RecentTaskInfo(); 5582 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5583 rti.persistentId = tr.taskId; 5584 rti.baseIntent = new Intent( 5585 tr.intent != null ? tr.intent : tr.affinityIntent); 5586 if (!detailed) { 5587 rti.baseIntent.replaceExtras((Bundle)null); 5588 } 5589 rti.origActivity = tr.origActivity; 5590 rti.description = tr.lastDescription; 5591 5592 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5593 // Check whether this activity is currently available. 5594 try { 5595 if (rti.origActivity != null) { 5596 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5597 == null) { 5598 continue; 5599 } 5600 } else if (rti.baseIntent != null) { 5601 if (pm.queryIntentActivities(rti.baseIntent, 5602 null, 0, userId) == null) { 5603 continue; 5604 } 5605 } 5606 } catch (RemoteException e) { 5607 // Will never happen. 5608 } 5609 } 5610 5611 res.add(rti); 5612 maxNum--; 5613 } 5614 } 5615 return res; 5616 } 5617 } 5618 5619 private TaskRecord taskForIdLocked(int id) { 5620 final int N = mRecentTasks.size(); 5621 for (int i=0; i<N; i++) { 5622 TaskRecord tr = mRecentTasks.get(i); 5623 if (tr.taskId == id) { 5624 return tr; 5625 } 5626 } 5627 return null; 5628 } 5629 5630 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5631 synchronized (this) { 5632 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5633 "getTaskThumbnails()"); 5634 TaskRecord tr = taskForIdLocked(id); 5635 if (tr != null) { 5636 return mMainStack.getTaskThumbnailsLocked(tr); 5637 } 5638 } 5639 return null; 5640 } 5641 5642 public boolean removeSubTask(int taskId, int subTaskIndex) { 5643 synchronized (this) { 5644 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5645 "removeSubTask()"); 5646 long ident = Binder.clearCallingIdentity(); 5647 try { 5648 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5649 true) != null; 5650 } finally { 5651 Binder.restoreCallingIdentity(ident); 5652 } 5653 } 5654 } 5655 5656 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5657 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5658 Intent baseIntent = new Intent( 5659 tr.intent != null ? tr.intent : tr.affinityIntent); 5660 ComponentName component = baseIntent.getComponent(); 5661 if (component == null) { 5662 Slog.w(TAG, "Now component for base intent of task: " + tr); 5663 return; 5664 } 5665 5666 // Find any running services associated with this app. 5667 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5668 5669 if (killProcesses) { 5670 // Find any running processes associated with this app. 5671 final String pkg = component.getPackageName(); 5672 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5673 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5674 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5675 for (int i=0; i<uids.size(); i++) { 5676 ProcessRecord proc = uids.valueAt(i); 5677 if (proc.userId != tr.userId) { 5678 continue; 5679 } 5680 if (!proc.pkgList.contains(pkg)) { 5681 continue; 5682 } 5683 procs.add(proc); 5684 } 5685 } 5686 5687 // Kill the running processes. 5688 for (int i=0; i<procs.size(); i++) { 5689 ProcessRecord pr = procs.get(i); 5690 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5691 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5692 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5693 pr.processName, pr.setAdj, "remove task"); 5694 pr.killedBackground = true; 5695 Process.killProcessQuiet(pr.pid); 5696 } else { 5697 pr.waitingToKill = "remove task"; 5698 } 5699 } 5700 } 5701 } 5702 5703 public boolean removeTask(int taskId, int flags) { 5704 synchronized (this) { 5705 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5706 "removeTask()"); 5707 long ident = Binder.clearCallingIdentity(); 5708 try { 5709 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5710 false); 5711 if (r != null) { 5712 mRecentTasks.remove(r.task); 5713 cleanUpRemovedTaskLocked(r.task, flags); 5714 return true; 5715 } else { 5716 TaskRecord tr = null; 5717 int i=0; 5718 while (i < mRecentTasks.size()) { 5719 TaskRecord t = mRecentTasks.get(i); 5720 if (t.taskId == taskId) { 5721 tr = t; 5722 break; 5723 } 5724 i++; 5725 } 5726 if (tr != null) { 5727 if (tr.numActivities <= 0) { 5728 // Caller is just removing a recent task that is 5729 // not actively running. That is easy! 5730 mRecentTasks.remove(i); 5731 cleanUpRemovedTaskLocked(tr, flags); 5732 return true; 5733 } else { 5734 Slog.w(TAG, "removeTask: task " + taskId 5735 + " does not have activities to remove, " 5736 + " but numActivities=" + tr.numActivities 5737 + ": " + tr); 5738 } 5739 } 5740 } 5741 } finally { 5742 Binder.restoreCallingIdentity(ident); 5743 } 5744 } 5745 return false; 5746 } 5747 5748 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5749 int j; 5750 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5751 TaskRecord jt = startTask; 5752 5753 // First look backwards 5754 for (j=startIndex-1; j>=0; j--) { 5755 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5756 if (r.task != jt) { 5757 jt = r.task; 5758 if (affinity.equals(jt.affinity)) { 5759 return j; 5760 } 5761 } 5762 } 5763 5764 // Now look forwards 5765 final int N = mMainStack.mHistory.size(); 5766 jt = startTask; 5767 for (j=startIndex+1; j<N; j++) { 5768 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5769 if (r.task != jt) { 5770 if (affinity.equals(jt.affinity)) { 5771 return j; 5772 } 5773 jt = r.task; 5774 } 5775 } 5776 5777 // Might it be at the top? 5778 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5779 return N-1; 5780 } 5781 5782 return -1; 5783 } 5784 5785 /** 5786 * TODO: Add mController hook 5787 */ 5788 public void moveTaskToFront(int task, int flags, Bundle options) { 5789 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5790 "moveTaskToFront()"); 5791 5792 synchronized(this) { 5793 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5794 Binder.getCallingUid(), "Task to front")) { 5795 ActivityOptions.abort(options); 5796 return; 5797 } 5798 final long origId = Binder.clearCallingIdentity(); 5799 try { 5800 TaskRecord tr = taskForIdLocked(task); 5801 if (tr != null) { 5802 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5803 mMainStack.mUserLeaving = true; 5804 } 5805 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5806 // Caller wants the home activity moved with it. To accomplish this, 5807 // we'll just move the home task to the top first. 5808 mMainStack.moveHomeToFrontLocked(); 5809 } 5810 mMainStack.moveTaskToFrontLocked(tr, null, options); 5811 return; 5812 } 5813 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5814 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5815 if (hr.task.taskId == task) { 5816 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5817 mMainStack.mUserLeaving = true; 5818 } 5819 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5820 // Caller wants the home activity moved with it. To accomplish this, 5821 // we'll just move the home task to the top first. 5822 mMainStack.moveHomeToFrontLocked(); 5823 } 5824 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5825 return; 5826 } 5827 } 5828 } finally { 5829 Binder.restoreCallingIdentity(origId); 5830 } 5831 ActivityOptions.abort(options); 5832 } 5833 } 5834 5835 public void moveTaskToBack(int task) { 5836 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5837 "moveTaskToBack()"); 5838 5839 synchronized(this) { 5840 if (mMainStack.mResumedActivity != null 5841 && mMainStack.mResumedActivity.task.taskId == task) { 5842 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5843 Binder.getCallingUid(), "Task to back")) { 5844 return; 5845 } 5846 } 5847 final long origId = Binder.clearCallingIdentity(); 5848 mMainStack.moveTaskToBackLocked(task, null); 5849 Binder.restoreCallingIdentity(origId); 5850 } 5851 } 5852 5853 /** 5854 * Moves an activity, and all of the other activities within the same task, to the bottom 5855 * of the history stack. The activity's order within the task is unchanged. 5856 * 5857 * @param token A reference to the activity we wish to move 5858 * @param nonRoot If false then this only works if the activity is the root 5859 * of a task; if true it will work for any activity in a task. 5860 * @return Returns true if the move completed, false if not. 5861 */ 5862 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5863 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5864 synchronized(this) { 5865 final long origId = Binder.clearCallingIdentity(); 5866 int taskId = getTaskForActivityLocked(token, !nonRoot); 5867 if (taskId >= 0) { 5868 return mMainStack.moveTaskToBackLocked(taskId, null); 5869 } 5870 Binder.restoreCallingIdentity(origId); 5871 } 5872 return false; 5873 } 5874 5875 public void moveTaskBackwards(int task) { 5876 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5877 "moveTaskBackwards()"); 5878 5879 synchronized(this) { 5880 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5881 Binder.getCallingUid(), "Task backwards")) { 5882 return; 5883 } 5884 final long origId = Binder.clearCallingIdentity(); 5885 moveTaskBackwardsLocked(task); 5886 Binder.restoreCallingIdentity(origId); 5887 } 5888 } 5889 5890 private final void moveTaskBackwardsLocked(int task) { 5891 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5892 } 5893 5894 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5895 synchronized(this) { 5896 return getTaskForActivityLocked(token, onlyRoot); 5897 } 5898 } 5899 5900 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5901 final int N = mMainStack.mHistory.size(); 5902 TaskRecord lastTask = null; 5903 for (int i=0; i<N; i++) { 5904 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5905 if (r.appToken == token) { 5906 if (!onlyRoot || lastTask != r.task) { 5907 return r.task.taskId; 5908 } 5909 return -1; 5910 } 5911 lastTask = r.task; 5912 } 5913 5914 return -1; 5915 } 5916 5917 // ========================================================= 5918 // THUMBNAILS 5919 // ========================================================= 5920 5921 public void reportThumbnail(IBinder token, 5922 Bitmap thumbnail, CharSequence description) { 5923 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5924 final long origId = Binder.clearCallingIdentity(); 5925 sendPendingThumbnail(null, token, thumbnail, description, true); 5926 Binder.restoreCallingIdentity(origId); 5927 } 5928 5929 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5930 Bitmap thumbnail, CharSequence description, boolean always) { 5931 TaskRecord task = null; 5932 ArrayList receivers = null; 5933 5934 //System.out.println("Send pending thumbnail: " + r); 5935 5936 synchronized(this) { 5937 if (r == null) { 5938 r = mMainStack.isInStackLocked(token); 5939 if (r == null) { 5940 return; 5941 } 5942 } 5943 if (thumbnail == null && r.thumbHolder != null) { 5944 thumbnail = r.thumbHolder.lastThumbnail; 5945 description = r.thumbHolder.lastDescription; 5946 } 5947 if (thumbnail == null && !always) { 5948 // If there is no thumbnail, and this entry is not actually 5949 // going away, then abort for now and pick up the next 5950 // thumbnail we get. 5951 return; 5952 } 5953 task = r.task; 5954 5955 int N = mPendingThumbnails.size(); 5956 int i=0; 5957 while (i<N) { 5958 PendingThumbnailsRecord pr = 5959 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5960 //System.out.println("Looking in " + pr.pendingRecords); 5961 if (pr.pendingRecords.remove(r)) { 5962 if (receivers == null) { 5963 receivers = new ArrayList(); 5964 } 5965 receivers.add(pr); 5966 if (pr.pendingRecords.size() == 0) { 5967 pr.finished = true; 5968 mPendingThumbnails.remove(i); 5969 N--; 5970 continue; 5971 } 5972 } 5973 i++; 5974 } 5975 } 5976 5977 if (receivers != null) { 5978 final int N = receivers.size(); 5979 for (int i=0; i<N; i++) { 5980 try { 5981 PendingThumbnailsRecord pr = 5982 (PendingThumbnailsRecord)receivers.get(i); 5983 pr.receiver.newThumbnail( 5984 task != null ? task.taskId : -1, thumbnail, description); 5985 if (pr.finished) { 5986 pr.receiver.finished(); 5987 } 5988 } catch (Exception e) { 5989 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 5990 } 5991 } 5992 } 5993 } 5994 5995 // ========================================================= 5996 // CONTENT PROVIDERS 5997 // ========================================================= 5998 5999 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6000 List<ProviderInfo> providers = null; 6001 try { 6002 providers = AppGlobals.getPackageManager(). 6003 queryContentProviders(app.processName, app.uid, 6004 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6005 } catch (RemoteException ex) { 6006 } 6007 if (DEBUG_MU) 6008 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6009 int userId = app.userId; 6010 if (providers != null) { 6011 int N = providers.size(); 6012 for (int i=0; i<N; i++) { 6013 ProviderInfo cpi = 6014 (ProviderInfo)providers.get(i); 6015 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6016 cpi.name, cpi.flags); 6017 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6018 // This is a singleton provider, but a user besides the 6019 // default user is asking to initialize a process it runs 6020 // in... well, no, it doesn't actually run in this process, 6021 // it runs in the process of the default user. Get rid of it. 6022 providers.remove(i); 6023 N--; 6024 continue; 6025 } 6026 6027 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6028 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6029 if (cpr == null) { 6030 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6031 mProviderMap.putProviderByClass(comp, cpr); 6032 } 6033 if (DEBUG_MU) 6034 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6035 app.pubProviders.put(cpi.name, cpr); 6036 app.addPackage(cpi.applicationInfo.packageName); 6037 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6038 } 6039 } 6040 return providers; 6041 } 6042 6043 /** 6044 * Check if {@link ProcessRecord} has a possible chance at accessing the 6045 * given {@link ProviderInfo}. Final permission checking is always done 6046 * in {@link ContentProvider}. 6047 */ 6048 private final String checkContentProviderPermissionLocked( 6049 ProviderInfo cpi, ProcessRecord r) { 6050 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6051 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6052 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6053 cpi.applicationInfo.uid, cpi.exported) 6054 == PackageManager.PERMISSION_GRANTED) { 6055 return null; 6056 } 6057 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6058 cpi.applicationInfo.uid, cpi.exported) 6059 == PackageManager.PERMISSION_GRANTED) { 6060 return null; 6061 } 6062 6063 PathPermission[] pps = cpi.pathPermissions; 6064 if (pps != null) { 6065 int i = pps.length; 6066 while (i > 0) { 6067 i--; 6068 PathPermission pp = pps[i]; 6069 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6070 cpi.applicationInfo.uid, cpi.exported) 6071 == PackageManager.PERMISSION_GRANTED) { 6072 return null; 6073 } 6074 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6075 cpi.applicationInfo.uid, cpi.exported) 6076 == PackageManager.PERMISSION_GRANTED) { 6077 return null; 6078 } 6079 } 6080 } 6081 6082 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6083 if (perms != null) { 6084 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6085 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6086 return null; 6087 } 6088 } 6089 } 6090 6091 String msg; 6092 if (!cpi.exported) { 6093 msg = "Permission Denial: opening provider " + cpi.name 6094 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6095 + ", uid=" + callingUid + ") that is not exported from uid " 6096 + cpi.applicationInfo.uid; 6097 } else { 6098 msg = "Permission Denial: opening provider " + cpi.name 6099 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6100 + ", uid=" + callingUid + ") requires " 6101 + cpi.readPermission + " or " + cpi.writePermission; 6102 } 6103 Slog.w(TAG, msg); 6104 return msg; 6105 } 6106 6107 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6108 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6109 if (r != null) { 6110 for (int i=0; i<r.conProviders.size(); i++) { 6111 ContentProviderConnection conn = r.conProviders.get(i); 6112 if (conn.provider == cpr) { 6113 if (DEBUG_PROVIDER) Slog.v(TAG, 6114 "Adding provider requested by " 6115 + r.processName + " from process " 6116 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6117 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6118 if (stable) { 6119 conn.stableCount++; 6120 conn.numStableIncs++; 6121 } else { 6122 conn.unstableCount++; 6123 conn.numUnstableIncs++; 6124 } 6125 return conn; 6126 } 6127 } 6128 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6129 if (stable) { 6130 conn.stableCount = 1; 6131 conn.numStableIncs = 1; 6132 } else { 6133 conn.unstableCount = 1; 6134 conn.numUnstableIncs = 1; 6135 } 6136 cpr.connections.add(conn); 6137 r.conProviders.add(conn); 6138 return conn; 6139 } 6140 cpr.addExternalProcessHandleLocked(externalProcessToken); 6141 return null; 6142 } 6143 6144 boolean decProviderCountLocked(ContentProviderConnection conn, 6145 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6146 if (conn != null) { 6147 cpr = conn.provider; 6148 if (DEBUG_PROVIDER) Slog.v(TAG, 6149 "Removing provider requested by " 6150 + conn.client.processName + " from process " 6151 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6152 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6153 if (stable) { 6154 conn.stableCount--; 6155 } else { 6156 conn.unstableCount--; 6157 } 6158 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6159 cpr.connections.remove(conn); 6160 conn.client.conProviders.remove(conn); 6161 return true; 6162 } 6163 return false; 6164 } 6165 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6166 return false; 6167 } 6168 6169 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6170 String name, IBinder token, boolean stable) { 6171 ContentProviderRecord cpr; 6172 ContentProviderConnection conn = null; 6173 ProviderInfo cpi = null; 6174 6175 synchronized(this) { 6176 ProcessRecord r = null; 6177 if (caller != null) { 6178 r = getRecordForAppLocked(caller); 6179 if (r == null) { 6180 throw new SecurityException( 6181 "Unable to find app for caller " + caller 6182 + " (pid=" + Binder.getCallingPid() 6183 + ") when getting content provider " + name); 6184 } 6185 } 6186 6187 // First check if this content provider has been published... 6188 int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6189 cpr = mProviderMap.getProviderByName(name, userId); 6190 boolean providerRunning = cpr != null; 6191 if (providerRunning) { 6192 cpi = cpr.info; 6193 String msg; 6194 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6195 throw new SecurityException(msg); 6196 } 6197 6198 if (r != null && cpr.canRunHere(r)) { 6199 // This provider has been published or is in the process 6200 // of being published... but it is also allowed to run 6201 // in the caller's process, so don't make a connection 6202 // and just let the caller instantiate its own instance. 6203 ContentProviderHolder holder = cpr.newHolder(null); 6204 // don't give caller the provider object, it needs 6205 // to make its own. 6206 holder.provider = null; 6207 return holder; 6208 } 6209 6210 final long origId = Binder.clearCallingIdentity(); 6211 6212 // In this case the provider instance already exists, so we can 6213 // return it right away. 6214 conn = incProviderCountLocked(r, cpr, token, stable); 6215 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6216 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6217 // If this is a perceptible app accessing the provider, 6218 // make sure to count it as being accessed and thus 6219 // back up on the LRU list. This is good because 6220 // content providers are often expensive to start. 6221 updateLruProcessLocked(cpr.proc, false, true); 6222 } 6223 } 6224 6225 if (cpr.proc != null) { 6226 if (false) { 6227 if (cpr.name.flattenToShortString().equals( 6228 "com.android.providers.calendar/.CalendarProvider2")) { 6229 Slog.v(TAG, "****************** KILLING " 6230 + cpr.name.flattenToShortString()); 6231 Process.killProcess(cpr.proc.pid); 6232 } 6233 } 6234 boolean success = updateOomAdjLocked(cpr.proc); 6235 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6236 // NOTE: there is still a race here where a signal could be 6237 // pending on the process even though we managed to update its 6238 // adj level. Not sure what to do about this, but at least 6239 // the race is now smaller. 6240 if (!success) { 6241 // Uh oh... it looks like the provider's process 6242 // has been killed on us. We need to wait for a new 6243 // process to be started, and make sure its death 6244 // doesn't kill our process. 6245 Slog.i(TAG, 6246 "Existing provider " + cpr.name.flattenToShortString() 6247 + " is crashing; detaching " + r); 6248 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6249 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6250 if (!lastRef) { 6251 // This wasn't the last ref our process had on 6252 // the provider... we have now been killed, bail. 6253 return null; 6254 } 6255 providerRunning = false; 6256 conn = null; 6257 } 6258 } 6259 6260 Binder.restoreCallingIdentity(origId); 6261 } 6262 6263 boolean singleton; 6264 if (!providerRunning) { 6265 try { 6266 cpi = AppGlobals.getPackageManager(). 6267 resolveContentProvider(name, 6268 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6269 } catch (RemoteException ex) { 6270 } 6271 if (cpi == null) { 6272 return null; 6273 } 6274 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6275 cpi.name, cpi.flags); 6276 if (singleton) { 6277 userId = 0; 6278 } 6279 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6280 6281 String msg; 6282 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6283 throw new SecurityException(msg); 6284 } 6285 6286 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6287 && !cpi.processName.equals("system")) { 6288 // If this content provider does not run in the system 6289 // process, and the system is not yet ready to run other 6290 // processes, then fail fast instead of hanging. 6291 throw new IllegalArgumentException( 6292 "Attempt to launch content provider before system ready"); 6293 } 6294 6295 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6296 cpr = mProviderMap.getProviderByClass(comp, userId); 6297 final boolean firstClass = cpr == null; 6298 if (firstClass) { 6299 try { 6300 ApplicationInfo ai = 6301 AppGlobals.getPackageManager(). 6302 getApplicationInfo( 6303 cpi.applicationInfo.packageName, 6304 STOCK_PM_FLAGS, userId); 6305 if (ai == null) { 6306 Slog.w(TAG, "No package info for content provider " 6307 + cpi.name); 6308 return null; 6309 } 6310 ai = getAppInfoForUser(ai, userId); 6311 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6312 } catch (RemoteException ex) { 6313 // pm is in same process, this will never happen. 6314 } 6315 } 6316 6317 if (r != null && cpr.canRunHere(r)) { 6318 // If this is a multiprocess provider, then just return its 6319 // info and allow the caller to instantiate it. Only do 6320 // this if the provider is the same user as the caller's 6321 // process, or can run as root (so can be in any process). 6322 return cpr.newHolder(null); 6323 } 6324 6325 if (DEBUG_PROVIDER) { 6326 RuntimeException e = new RuntimeException("here"); 6327 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6328 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6329 } 6330 6331 // This is single process, and our app is now connecting to it. 6332 // See if we are already in the process of launching this 6333 // provider. 6334 final int N = mLaunchingProviders.size(); 6335 int i; 6336 for (i=0; i<N; i++) { 6337 if (mLaunchingProviders.get(i) == cpr) { 6338 break; 6339 } 6340 } 6341 6342 // If the provider is not already being launched, then get it 6343 // started. 6344 if (i >= N) { 6345 final long origId = Binder.clearCallingIdentity(); 6346 6347 try { 6348 // Content provider is now in use, its package can't be stopped. 6349 try { 6350 AppGlobals.getPackageManager().setPackageStoppedState( 6351 cpr.appInfo.packageName, false, userId); 6352 } catch (RemoteException e) { 6353 } catch (IllegalArgumentException e) { 6354 Slog.w(TAG, "Failed trying to unstop package " 6355 + cpr.appInfo.packageName + ": " + e); 6356 } 6357 6358 ProcessRecord proc = startProcessLocked(cpi.processName, 6359 cpr.appInfo, false, 0, "content provider", 6360 new ComponentName(cpi.applicationInfo.packageName, 6361 cpi.name), false, false); 6362 if (proc == null) { 6363 Slog.w(TAG, "Unable to launch app " 6364 + cpi.applicationInfo.packageName + "/" 6365 + cpi.applicationInfo.uid + " for provider " 6366 + name + ": process is bad"); 6367 return null; 6368 } 6369 cpr.launchingApp = proc; 6370 mLaunchingProviders.add(cpr); 6371 } finally { 6372 Binder.restoreCallingIdentity(origId); 6373 } 6374 } 6375 6376 // Make sure the provider is published (the same provider class 6377 // may be published under multiple names). 6378 if (firstClass) { 6379 mProviderMap.putProviderByClass(comp, cpr); 6380 } 6381 6382 mProviderMap.putProviderByName(name, cpr); 6383 conn = incProviderCountLocked(r, cpr, token, stable); 6384 if (conn != null) { 6385 conn.waiting = true; 6386 } 6387 } 6388 } 6389 6390 // Wait for the provider to be published... 6391 synchronized (cpr) { 6392 while (cpr.provider == null) { 6393 if (cpr.launchingApp == null) { 6394 Slog.w(TAG, "Unable to launch app " 6395 + cpi.applicationInfo.packageName + "/" 6396 + cpi.applicationInfo.uid + " for provider " 6397 + name + ": launching app became null"); 6398 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6399 cpi.applicationInfo.packageName, 6400 cpi.applicationInfo.uid, name); 6401 return null; 6402 } 6403 try { 6404 if (DEBUG_MU) { 6405 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6406 + cpr.launchingApp); 6407 } 6408 if (conn != null) { 6409 conn.waiting = true; 6410 } 6411 cpr.wait(); 6412 } catch (InterruptedException ex) { 6413 } finally { 6414 if (conn != null) { 6415 conn.waiting = false; 6416 } 6417 } 6418 } 6419 } 6420 return cpr != null ? cpr.newHolder(conn) : null; 6421 } 6422 6423 public final ContentProviderHolder getContentProvider( 6424 IApplicationThread caller, String name, boolean stable) { 6425 enforceNotIsolatedCaller("getContentProvider"); 6426 if (caller == null) { 6427 String msg = "null IApplicationThread when getting content provider " 6428 + name; 6429 Slog.w(TAG, msg); 6430 throw new SecurityException(msg); 6431 } 6432 6433 return getContentProviderImpl(caller, name, null, stable); 6434 } 6435 6436 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6437 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6438 "Do not have permission in call getContentProviderExternal()"); 6439 return getContentProviderExternalUnchecked(name, token); 6440 } 6441 6442 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6443 return getContentProviderImpl(null, name, token, true); 6444 } 6445 6446 /** 6447 * Drop a content provider from a ProcessRecord's bookkeeping 6448 * @param cpr 6449 */ 6450 public void removeContentProvider(IBinder connection, boolean stable) { 6451 enforceNotIsolatedCaller("removeContentProvider"); 6452 synchronized (this) { 6453 ContentProviderConnection conn; 6454 try { 6455 conn = (ContentProviderConnection)connection; 6456 } catch (ClassCastException e) { 6457 String msg ="removeContentProvider: " + connection 6458 + " not a ContentProviderConnection"; 6459 Slog.w(TAG, msg); 6460 throw new IllegalArgumentException(msg); 6461 } 6462 if (conn == null) { 6463 throw new NullPointerException("connection is null"); 6464 } 6465 if (decProviderCountLocked(conn, null, null, stable)) { 6466 updateOomAdjLocked(); 6467 } 6468 } 6469 } 6470 6471 public void removeContentProviderExternal(String name, IBinder token) { 6472 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6473 "Do not have permission in call removeContentProviderExternal()"); 6474 removeContentProviderExternalUnchecked(name, token); 6475 } 6476 6477 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6478 synchronized (this) { 6479 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6480 Binder.getOrigCallingUser()); 6481 if(cpr == null) { 6482 //remove from mProvidersByClass 6483 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6484 return; 6485 } 6486 6487 //update content provider record entry info 6488 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6489 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6490 Binder.getOrigCallingUser()); 6491 if (localCpr.hasExternalProcessHandles()) { 6492 if (localCpr.removeExternalProcessHandleLocked(token)) { 6493 updateOomAdjLocked(); 6494 } else { 6495 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6496 + " with no external reference for token: " 6497 + token + "."); 6498 } 6499 } else { 6500 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6501 + " with no external references."); 6502 } 6503 } 6504 } 6505 6506 public final void publishContentProviders(IApplicationThread caller, 6507 List<ContentProviderHolder> providers) { 6508 if (providers == null) { 6509 return; 6510 } 6511 6512 enforceNotIsolatedCaller("publishContentProviders"); 6513 synchronized (this) { 6514 final ProcessRecord r = getRecordForAppLocked(caller); 6515 if (DEBUG_MU) 6516 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6517 if (r == null) { 6518 throw new SecurityException( 6519 "Unable to find app for caller " + caller 6520 + " (pid=" + Binder.getCallingPid() 6521 + ") when publishing content providers"); 6522 } 6523 6524 final long origId = Binder.clearCallingIdentity(); 6525 6526 final int N = providers.size(); 6527 for (int i=0; i<N; i++) { 6528 ContentProviderHolder src = providers.get(i); 6529 if (src == null || src.info == null || src.provider == null) { 6530 continue; 6531 } 6532 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6533 if (DEBUG_MU) 6534 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6535 if (dst != null) { 6536 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6537 mProviderMap.putProviderByClass(comp, dst); 6538 String names[] = dst.info.authority.split(";"); 6539 for (int j = 0; j < names.length; j++) { 6540 mProviderMap.putProviderByName(names[j], dst); 6541 } 6542 6543 int NL = mLaunchingProviders.size(); 6544 int j; 6545 for (j=0; j<NL; j++) { 6546 if (mLaunchingProviders.get(j) == dst) { 6547 mLaunchingProviders.remove(j); 6548 j--; 6549 NL--; 6550 } 6551 } 6552 synchronized (dst) { 6553 dst.provider = src.provider; 6554 dst.proc = r; 6555 dst.notifyAll(); 6556 } 6557 updateOomAdjLocked(r); 6558 } 6559 } 6560 6561 Binder.restoreCallingIdentity(origId); 6562 } 6563 } 6564 6565 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6566 ContentProviderConnection conn; 6567 try { 6568 conn = (ContentProviderConnection)connection; 6569 } catch (ClassCastException e) { 6570 String msg ="refContentProvider: " + connection 6571 + " not a ContentProviderConnection"; 6572 Slog.w(TAG, msg); 6573 throw new IllegalArgumentException(msg); 6574 } 6575 if (conn == null) { 6576 throw new NullPointerException("connection is null"); 6577 } 6578 6579 synchronized (this) { 6580 if (stable > 0) { 6581 conn.numStableIncs += stable; 6582 } 6583 stable = conn.stableCount + stable; 6584 if (stable < 0) { 6585 throw new IllegalStateException("stableCount < 0: " + stable); 6586 } 6587 6588 if (unstable > 0) { 6589 conn.numUnstableIncs += unstable; 6590 } 6591 unstable = conn.unstableCount + unstable; 6592 if (unstable < 0) { 6593 throw new IllegalStateException("unstableCount < 0: " + unstable); 6594 } 6595 6596 if ((stable+unstable) <= 0) { 6597 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6598 + stable + " unstable=" + unstable); 6599 } 6600 conn.stableCount = stable; 6601 conn.unstableCount = unstable; 6602 return !conn.dead; 6603 } 6604 } 6605 6606 public void unstableProviderDied(IBinder connection) { 6607 ContentProviderConnection conn; 6608 try { 6609 conn = (ContentProviderConnection)connection; 6610 } catch (ClassCastException e) { 6611 String msg ="refContentProvider: " + connection 6612 + " not a ContentProviderConnection"; 6613 Slog.w(TAG, msg); 6614 throw new IllegalArgumentException(msg); 6615 } 6616 if (conn == null) { 6617 throw new NullPointerException("connection is null"); 6618 } 6619 6620 // Safely retrieve the content provider associated with the connection. 6621 IContentProvider provider; 6622 synchronized (this) { 6623 provider = conn.provider.provider; 6624 } 6625 6626 if (provider == null) { 6627 // Um, yeah, we're way ahead of you. 6628 return; 6629 } 6630 6631 // Make sure the caller is being honest with us. 6632 if (provider.asBinder().pingBinder()) { 6633 // Er, no, still looks good to us. 6634 synchronized (this) { 6635 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6636 + " says " + conn + " died, but we don't agree"); 6637 return; 6638 } 6639 } 6640 6641 // Well look at that! It's dead! 6642 synchronized (this) { 6643 if (conn.provider.provider != provider) { 6644 // But something changed... good enough. 6645 return; 6646 } 6647 6648 ProcessRecord proc = conn.provider.proc; 6649 if (proc == null || proc.thread == null) { 6650 // Seems like the process is already cleaned up. 6651 return; 6652 } 6653 6654 // As far as we're concerned, this is just like receiving a 6655 // death notification... just a bit prematurely. 6656 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6657 + ") early provider death"); 6658 final long ident = Binder.clearCallingIdentity(); 6659 try { 6660 appDiedLocked(proc, proc.pid, proc.thread); 6661 } finally { 6662 Binder.restoreCallingIdentity(ident); 6663 } 6664 } 6665 } 6666 6667 public static final void installSystemProviders() { 6668 List<ProviderInfo> providers; 6669 synchronized (mSelf) { 6670 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6671 providers = mSelf.generateApplicationProvidersLocked(app); 6672 if (providers != null) { 6673 for (int i=providers.size()-1; i>=0; i--) { 6674 ProviderInfo pi = (ProviderInfo)providers.get(i); 6675 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6676 Slog.w(TAG, "Not installing system proc provider " + pi.name 6677 + ": not system .apk"); 6678 providers.remove(i); 6679 } 6680 } 6681 } 6682 } 6683 if (providers != null) { 6684 mSystemThread.installSystemProviders(providers); 6685 } 6686 6687 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6688 6689 mSelf.mUsageStatsService.monitorPackages(); 6690 } 6691 6692 /** 6693 * Allows app to retrieve the MIME type of a URI without having permission 6694 * to access its content provider. 6695 * 6696 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6697 * 6698 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6699 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6700 */ 6701 public String getProviderMimeType(Uri uri) { 6702 enforceNotIsolatedCaller("getProviderMimeType"); 6703 final String name = uri.getAuthority(); 6704 final long ident = Binder.clearCallingIdentity(); 6705 ContentProviderHolder holder = null; 6706 6707 try { 6708 holder = getContentProviderExternalUnchecked(name, null); 6709 if (holder != null) { 6710 return holder.provider.getType(uri); 6711 } 6712 } catch (RemoteException e) { 6713 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6714 return null; 6715 } finally { 6716 if (holder != null) { 6717 removeContentProviderExternalUnchecked(name, null); 6718 } 6719 Binder.restoreCallingIdentity(ident); 6720 } 6721 6722 return null; 6723 } 6724 6725 // ========================================================= 6726 // GLOBAL MANAGEMENT 6727 // ========================================================= 6728 6729 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6730 ApplicationInfo info, String customProcess, boolean isolated) { 6731 String proc = customProcess != null ? customProcess : info.processName; 6732 BatteryStatsImpl.Uid.Proc ps = null; 6733 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6734 int uid = info.uid; 6735 if (isolated) { 6736 int userId = UserHandle.getUserId(uid); 6737 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6738 uid = 0; 6739 while (true) { 6740 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6741 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6742 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6743 } 6744 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6745 mNextIsolatedProcessUid++; 6746 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6747 // No process for this uid, use it. 6748 break; 6749 } 6750 stepsLeft--; 6751 if (stepsLeft <= 0) { 6752 return null; 6753 } 6754 } 6755 } 6756 synchronized (stats) { 6757 ps = stats.getProcessStatsLocked(info.uid, proc); 6758 } 6759 return new ProcessRecord(ps, thread, info, proc, uid); 6760 } 6761 6762 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6763 ProcessRecord app; 6764 if (!isolated) { 6765 app = getProcessRecordLocked(info.processName, info.uid); 6766 } else { 6767 app = null; 6768 } 6769 6770 if (app == null) { 6771 app = newProcessRecordLocked(null, info, null, isolated); 6772 mProcessNames.put(info.processName, app.uid, app); 6773 if (isolated) { 6774 mIsolatedProcesses.put(app.uid, app); 6775 } 6776 updateLruProcessLocked(app, true, true); 6777 } 6778 6779 // This package really, really can not be stopped. 6780 try { 6781 AppGlobals.getPackageManager().setPackageStoppedState( 6782 info.packageName, false, UserHandle.getUserId(app.uid)); 6783 } catch (RemoteException e) { 6784 } catch (IllegalArgumentException e) { 6785 Slog.w(TAG, "Failed trying to unstop package " 6786 + info.packageName + ": " + e); 6787 } 6788 6789 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6790 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6791 app.persistent = true; 6792 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6793 } 6794 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6795 mPersistentStartingProcesses.add(app); 6796 startProcessLocked(app, "added application", app.processName); 6797 } 6798 6799 return app; 6800 } 6801 6802 public void unhandledBack() { 6803 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6804 "unhandledBack()"); 6805 6806 synchronized(this) { 6807 int count = mMainStack.mHistory.size(); 6808 if (DEBUG_SWITCH) Slog.d( 6809 TAG, "Performing unhandledBack(): stack size = " + count); 6810 if (count > 1) { 6811 final long origId = Binder.clearCallingIdentity(); 6812 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6813 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6814 Binder.restoreCallingIdentity(origId); 6815 } 6816 } 6817 } 6818 6819 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6820 enforceNotIsolatedCaller("openContentUri"); 6821 String name = uri.getAuthority(); 6822 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6823 ParcelFileDescriptor pfd = null; 6824 if (cph != null) { 6825 // We record the binder invoker's uid in thread-local storage before 6826 // going to the content provider to open the file. Later, in the code 6827 // that handles all permissions checks, we look for this uid and use 6828 // that rather than the Activity Manager's own uid. The effect is that 6829 // we do the check against the caller's permissions even though it looks 6830 // to the content provider like the Activity Manager itself is making 6831 // the request. 6832 sCallerIdentity.set(new Identity( 6833 Binder.getCallingPid(), Binder.getCallingUid())); 6834 try { 6835 pfd = cph.provider.openFile(uri, "r"); 6836 } catch (FileNotFoundException e) { 6837 // do nothing; pfd will be returned null 6838 } finally { 6839 // Ensure that whatever happens, we clean up the identity state 6840 sCallerIdentity.remove(); 6841 } 6842 6843 // We've got the fd now, so we're done with the provider. 6844 removeContentProviderExternalUnchecked(name, null); 6845 } else { 6846 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6847 } 6848 return pfd; 6849 } 6850 6851 // Actually is sleeping or shutting down or whatever else in the future 6852 // is an inactive state. 6853 public boolean isSleeping() { 6854 return mSleeping || mShuttingDown; 6855 } 6856 6857 public void goingToSleep() { 6858 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6859 != PackageManager.PERMISSION_GRANTED) { 6860 throw new SecurityException("Requires permission " 6861 + android.Manifest.permission.DEVICE_POWER); 6862 } 6863 6864 synchronized(this) { 6865 mWentToSleep = true; 6866 updateEventDispatchingLocked(); 6867 6868 if (!mSleeping) { 6869 mSleeping = true; 6870 mMainStack.stopIfSleepingLocked(); 6871 6872 // Initialize the wake times of all processes. 6873 checkExcessivePowerUsageLocked(false); 6874 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6875 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6876 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6877 } 6878 } 6879 } 6880 6881 public boolean shutdown(int timeout) { 6882 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6883 != PackageManager.PERMISSION_GRANTED) { 6884 throw new SecurityException("Requires permission " 6885 + android.Manifest.permission.SHUTDOWN); 6886 } 6887 6888 boolean timedout = false; 6889 6890 synchronized(this) { 6891 mShuttingDown = true; 6892 updateEventDispatchingLocked(); 6893 6894 if (mMainStack.mResumedActivity != null) { 6895 mMainStack.stopIfSleepingLocked(); 6896 final long endTime = System.currentTimeMillis() + timeout; 6897 while (mMainStack.mResumedActivity != null 6898 || mMainStack.mPausingActivity != null) { 6899 long delay = endTime - System.currentTimeMillis(); 6900 if (delay <= 0) { 6901 Slog.w(TAG, "Activity manager shutdown timed out"); 6902 timedout = true; 6903 break; 6904 } 6905 try { 6906 this.wait(); 6907 } catch (InterruptedException e) { 6908 } 6909 } 6910 } 6911 } 6912 6913 mUsageStatsService.shutdown(); 6914 mBatteryStatsService.shutdown(); 6915 6916 return timedout; 6917 } 6918 6919 public final void activitySlept(IBinder token) { 6920 if (localLOGV) Slog.v( 6921 TAG, "Activity slept: token=" + token); 6922 6923 ActivityRecord r = null; 6924 6925 final long origId = Binder.clearCallingIdentity(); 6926 6927 synchronized (this) { 6928 r = mMainStack.isInStackLocked(token); 6929 if (r != null) { 6930 mMainStack.activitySleptLocked(r); 6931 } 6932 } 6933 6934 Binder.restoreCallingIdentity(origId); 6935 } 6936 6937 private void comeOutOfSleepIfNeededLocked() { 6938 if (!mWentToSleep && !mLockScreenShown) { 6939 if (mSleeping) { 6940 mSleeping = false; 6941 mMainStack.awakeFromSleepingLocked(); 6942 mMainStack.resumeTopActivityLocked(null); 6943 } 6944 } 6945 } 6946 6947 public void wakingUp() { 6948 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6949 != PackageManager.PERMISSION_GRANTED) { 6950 throw new SecurityException("Requires permission " 6951 + android.Manifest.permission.DEVICE_POWER); 6952 } 6953 6954 synchronized(this) { 6955 mWentToSleep = false; 6956 updateEventDispatchingLocked(); 6957 comeOutOfSleepIfNeededLocked(); 6958 } 6959 } 6960 6961 private void updateEventDispatchingLocked() { 6962 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6963 } 6964 6965 public void setLockScreenShown(boolean shown) { 6966 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6967 != PackageManager.PERMISSION_GRANTED) { 6968 throw new SecurityException("Requires permission " 6969 + android.Manifest.permission.DEVICE_POWER); 6970 } 6971 6972 synchronized(this) { 6973 mLockScreenShown = shown; 6974 comeOutOfSleepIfNeededLocked(); 6975 } 6976 } 6977 6978 public void stopAppSwitches() { 6979 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6980 != PackageManager.PERMISSION_GRANTED) { 6981 throw new SecurityException("Requires permission " 6982 + android.Manifest.permission.STOP_APP_SWITCHES); 6983 } 6984 6985 synchronized(this) { 6986 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 6987 + APP_SWITCH_DELAY_TIME; 6988 mDidAppSwitch = false; 6989 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6990 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 6991 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 6992 } 6993 } 6994 6995 public void resumeAppSwitches() { 6996 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6997 != PackageManager.PERMISSION_GRANTED) { 6998 throw new SecurityException("Requires permission " 6999 + android.Manifest.permission.STOP_APP_SWITCHES); 7000 } 7001 7002 synchronized(this) { 7003 // Note that we don't execute any pending app switches... we will 7004 // let those wait until either the timeout, or the next start 7005 // activity request. 7006 mAppSwitchesAllowedTime = 0; 7007 } 7008 } 7009 7010 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7011 String name) { 7012 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7013 return true; 7014 } 7015 7016 final int perm = checkComponentPermission( 7017 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7018 callingUid, -1, true); 7019 if (perm == PackageManager.PERMISSION_GRANTED) { 7020 return true; 7021 } 7022 7023 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7024 return false; 7025 } 7026 7027 public void setDebugApp(String packageName, boolean waitForDebugger, 7028 boolean persistent) { 7029 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7030 "setDebugApp()"); 7031 7032 // Note that this is not really thread safe if there are multiple 7033 // callers into it at the same time, but that's not a situation we 7034 // care about. 7035 if (persistent) { 7036 final ContentResolver resolver = mContext.getContentResolver(); 7037 Settings.System.putString( 7038 resolver, Settings.System.DEBUG_APP, 7039 packageName); 7040 Settings.System.putInt( 7041 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7042 waitForDebugger ? 1 : 0); 7043 } 7044 7045 synchronized (this) { 7046 if (!persistent) { 7047 mOrigDebugApp = mDebugApp; 7048 mOrigWaitForDebugger = mWaitForDebugger; 7049 } 7050 mDebugApp = packageName; 7051 mWaitForDebugger = waitForDebugger; 7052 mDebugTransient = !persistent; 7053 if (packageName != null) { 7054 final long origId = Binder.clearCallingIdentity(); 7055 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7056 Binder.restoreCallingIdentity(origId); 7057 } 7058 } 7059 } 7060 7061 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7062 synchronized (this) { 7063 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7064 if (!isDebuggable) { 7065 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7066 throw new SecurityException("Process not debuggable: " + app.packageName); 7067 } 7068 } 7069 7070 mOpenGlTraceApp = processName; 7071 } 7072 } 7073 7074 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7075 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7076 synchronized (this) { 7077 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7078 if (!isDebuggable) { 7079 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7080 throw new SecurityException("Process not debuggable: " + app.packageName); 7081 } 7082 } 7083 mProfileApp = processName; 7084 mProfileFile = profileFile; 7085 if (mProfileFd != null) { 7086 try { 7087 mProfileFd.close(); 7088 } catch (IOException e) { 7089 } 7090 mProfileFd = null; 7091 } 7092 mProfileFd = profileFd; 7093 mProfileType = 0; 7094 mAutoStopProfiler = autoStopProfiler; 7095 } 7096 } 7097 7098 public void setAlwaysFinish(boolean enabled) { 7099 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7100 "setAlwaysFinish()"); 7101 7102 Settings.System.putInt( 7103 mContext.getContentResolver(), 7104 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7105 7106 synchronized (this) { 7107 mAlwaysFinishActivities = enabled; 7108 } 7109 } 7110 7111 public void setActivityController(IActivityController controller) { 7112 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7113 "setActivityController()"); 7114 synchronized (this) { 7115 mController = controller; 7116 } 7117 } 7118 7119 public boolean isUserAMonkey() { 7120 // For now the fact that there is a controller implies 7121 // we have a monkey. 7122 synchronized (this) { 7123 return mController != null; 7124 } 7125 } 7126 7127 public void registerProcessObserver(IProcessObserver observer) { 7128 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7129 "registerProcessObserver()"); 7130 synchronized (this) { 7131 mProcessObservers.register(observer); 7132 } 7133 } 7134 7135 public void unregisterProcessObserver(IProcessObserver observer) { 7136 synchronized (this) { 7137 mProcessObservers.unregister(observer); 7138 } 7139 } 7140 7141 public void setImmersive(IBinder token, boolean immersive) { 7142 synchronized(this) { 7143 ActivityRecord r = mMainStack.isInStackLocked(token); 7144 if (r == null) { 7145 throw new IllegalArgumentException(); 7146 } 7147 r.immersive = immersive; 7148 } 7149 } 7150 7151 public boolean isImmersive(IBinder token) { 7152 synchronized (this) { 7153 ActivityRecord r = mMainStack.isInStackLocked(token); 7154 if (r == null) { 7155 throw new IllegalArgumentException(); 7156 } 7157 return r.immersive; 7158 } 7159 } 7160 7161 public boolean isTopActivityImmersive() { 7162 enforceNotIsolatedCaller("startActivity"); 7163 synchronized (this) { 7164 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7165 return (r != null) ? r.immersive : false; 7166 } 7167 } 7168 7169 public final void enterSafeMode() { 7170 synchronized(this) { 7171 // It only makes sense to do this before the system is ready 7172 // and started launching other packages. 7173 if (!mSystemReady) { 7174 try { 7175 AppGlobals.getPackageManager().enterSafeMode(); 7176 } catch (RemoteException e) { 7177 } 7178 } 7179 } 7180 } 7181 7182 public final void showSafeModeOverlay() { 7183 View v = LayoutInflater.from(mContext).inflate( 7184 com.android.internal.R.layout.safe_mode, null); 7185 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7186 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7187 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7188 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7189 lp.gravity = Gravity.BOTTOM | Gravity.START; 7190 lp.format = v.getBackground().getOpacity(); 7191 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7192 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7193 ((WindowManager)mContext.getSystemService( 7194 Context.WINDOW_SERVICE)).addView(v, lp); 7195 } 7196 7197 public void noteWakeupAlarm(IIntentSender sender) { 7198 if (!(sender instanceof PendingIntentRecord)) { 7199 return; 7200 } 7201 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7202 synchronized (stats) { 7203 if (mBatteryStatsService.isOnBattery()) { 7204 mBatteryStatsService.enforceCallingPermission(); 7205 PendingIntentRecord rec = (PendingIntentRecord)sender; 7206 int MY_UID = Binder.getCallingUid(); 7207 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7208 BatteryStatsImpl.Uid.Pkg pkg = 7209 stats.getPackageStatsLocked(uid, rec.key.packageName); 7210 pkg.incWakeupsLocked(); 7211 } 7212 } 7213 } 7214 7215 public boolean killPids(int[] pids, String pReason, boolean secure) { 7216 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7217 throw new SecurityException("killPids only available to the system"); 7218 } 7219 String reason = (pReason == null) ? "Unknown" : pReason; 7220 // XXX Note: don't acquire main activity lock here, because the window 7221 // manager calls in with its locks held. 7222 7223 boolean killed = false; 7224 synchronized (mPidsSelfLocked) { 7225 int[] types = new int[pids.length]; 7226 int worstType = 0; 7227 for (int i=0; i<pids.length; i++) { 7228 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7229 if (proc != null) { 7230 int type = proc.setAdj; 7231 types[i] = type; 7232 if (type > worstType) { 7233 worstType = type; 7234 } 7235 } 7236 } 7237 7238 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7239 // then constrain it so we will kill all hidden procs. 7240 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7241 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7242 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7243 } 7244 7245 // If this is not a secure call, don't let it kill processes that 7246 // are important. 7247 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7248 worstType = ProcessList.SERVICE_ADJ; 7249 } 7250 7251 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7252 for (int i=0; i<pids.length; i++) { 7253 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7254 if (proc == null) { 7255 continue; 7256 } 7257 int adj = proc.setAdj; 7258 if (adj >= worstType && !proc.killedBackground) { 7259 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7260 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7261 proc.processName, adj, reason); 7262 killed = true; 7263 proc.killedBackground = true; 7264 Process.killProcessQuiet(pids[i]); 7265 } 7266 } 7267 } 7268 return killed; 7269 } 7270 7271 @Override 7272 public boolean killProcessesBelowForeground(String reason) { 7273 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7274 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7275 } 7276 7277 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7278 } 7279 7280 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7281 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7282 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7283 } 7284 7285 boolean killed = false; 7286 synchronized (mPidsSelfLocked) { 7287 final int size = mPidsSelfLocked.size(); 7288 for (int i = 0; i < size; i++) { 7289 final int pid = mPidsSelfLocked.keyAt(i); 7290 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7291 if (proc == null) continue; 7292 7293 final int adj = proc.setAdj; 7294 if (adj > belowAdj && !proc.killedBackground) { 7295 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7296 EventLog.writeEvent( 7297 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7298 killed = true; 7299 proc.killedBackground = true; 7300 Process.killProcessQuiet(pid); 7301 } 7302 } 7303 } 7304 return killed; 7305 } 7306 7307 public final void startRunning(String pkg, String cls, String action, 7308 String data) { 7309 synchronized(this) { 7310 if (mStartRunning) { 7311 return; 7312 } 7313 mStartRunning = true; 7314 mTopComponent = pkg != null && cls != null 7315 ? new ComponentName(pkg, cls) : null; 7316 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7317 mTopData = data; 7318 if (!mSystemReady) { 7319 return; 7320 } 7321 } 7322 7323 systemReady(null); 7324 } 7325 7326 private void retrieveSettings() { 7327 final ContentResolver resolver = mContext.getContentResolver(); 7328 String debugApp = Settings.System.getString( 7329 resolver, Settings.System.DEBUG_APP); 7330 boolean waitForDebugger = Settings.System.getInt( 7331 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7332 boolean alwaysFinishActivities = Settings.System.getInt( 7333 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7334 7335 Configuration configuration = new Configuration(); 7336 Settings.System.getConfiguration(resolver, configuration); 7337 7338 synchronized (this) { 7339 mDebugApp = mOrigDebugApp = debugApp; 7340 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7341 mAlwaysFinishActivities = alwaysFinishActivities; 7342 // This happens before any activities are started, so we can 7343 // change mConfiguration in-place. 7344 updateConfigurationLocked(configuration, null, false, true); 7345 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7346 } 7347 } 7348 7349 public boolean testIsSystemReady() { 7350 // no need to synchronize(this) just to read & return the value 7351 return mSystemReady; 7352 } 7353 7354 private static File getCalledPreBootReceiversFile() { 7355 File dataDir = Environment.getDataDirectory(); 7356 File systemDir = new File(dataDir, "system"); 7357 File fname = new File(systemDir, "called_pre_boots.dat"); 7358 return fname; 7359 } 7360 7361 static final int LAST_DONE_VERSION = 10000; 7362 7363 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7364 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7365 File file = getCalledPreBootReceiversFile(); 7366 FileInputStream fis = null; 7367 try { 7368 fis = new FileInputStream(file); 7369 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7370 int fvers = dis.readInt(); 7371 if (fvers == LAST_DONE_VERSION) { 7372 String vers = dis.readUTF(); 7373 String codename = dis.readUTF(); 7374 String build = dis.readUTF(); 7375 if (android.os.Build.VERSION.RELEASE.equals(vers) 7376 && android.os.Build.VERSION.CODENAME.equals(codename) 7377 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7378 int num = dis.readInt(); 7379 while (num > 0) { 7380 num--; 7381 String pkg = dis.readUTF(); 7382 String cls = dis.readUTF(); 7383 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7384 } 7385 } 7386 } 7387 } catch (FileNotFoundException e) { 7388 } catch (IOException e) { 7389 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7390 } finally { 7391 if (fis != null) { 7392 try { 7393 fis.close(); 7394 } catch (IOException e) { 7395 } 7396 } 7397 } 7398 return lastDoneReceivers; 7399 } 7400 7401 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7402 File file = getCalledPreBootReceiversFile(); 7403 FileOutputStream fos = null; 7404 DataOutputStream dos = null; 7405 try { 7406 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7407 fos = new FileOutputStream(file); 7408 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7409 dos.writeInt(LAST_DONE_VERSION); 7410 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7411 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7412 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7413 dos.writeInt(list.size()); 7414 for (int i=0; i<list.size(); i++) { 7415 dos.writeUTF(list.get(i).getPackageName()); 7416 dos.writeUTF(list.get(i).getClassName()); 7417 } 7418 } catch (IOException e) { 7419 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7420 file.delete(); 7421 } finally { 7422 FileUtils.sync(fos); 7423 if (dos != null) { 7424 try { 7425 dos.close(); 7426 } catch (IOException e) { 7427 // TODO Auto-generated catch block 7428 e.printStackTrace(); 7429 } 7430 } 7431 } 7432 } 7433 7434 public void systemReady(final Runnable goingCallback) { 7435 synchronized(this) { 7436 if (mSystemReady) { 7437 if (goingCallback != null) goingCallback.run(); 7438 return; 7439 } 7440 7441 // Check to see if there are any update receivers to run. 7442 if (!mDidUpdate) { 7443 if (mWaitingUpdate) { 7444 return; 7445 } 7446 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7447 List<ResolveInfo> ris = null; 7448 try { 7449 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7450 intent, null, 0, 0); 7451 } catch (RemoteException e) { 7452 } 7453 if (ris != null) { 7454 for (int i=ris.size()-1; i>=0; i--) { 7455 if ((ris.get(i).activityInfo.applicationInfo.flags 7456 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7457 ris.remove(i); 7458 } 7459 } 7460 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7461 7462 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7463 7464 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7465 for (int i=0; i<ris.size(); i++) { 7466 ActivityInfo ai = ris.get(i).activityInfo; 7467 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7468 if (lastDoneReceivers.contains(comp)) { 7469 ris.remove(i); 7470 i--; 7471 } 7472 } 7473 7474 for (int i=0; i<ris.size(); i++) { 7475 ActivityInfo ai = ris.get(i).activityInfo; 7476 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7477 doneReceivers.add(comp); 7478 intent.setComponent(comp); 7479 IIntentReceiver finisher = null; 7480 if (i == ris.size()-1) { 7481 finisher = new IIntentReceiver.Stub() { 7482 public void performReceive(Intent intent, int resultCode, 7483 String data, Bundle extras, boolean ordered, 7484 boolean sticky) { 7485 // The raw IIntentReceiver interface is called 7486 // with the AM lock held, so redispatch to 7487 // execute our code without the lock. 7488 mHandler.post(new Runnable() { 7489 public void run() { 7490 synchronized (ActivityManagerService.this) { 7491 mDidUpdate = true; 7492 } 7493 writeLastDonePreBootReceivers(doneReceivers); 7494 showBootMessage(mContext.getText( 7495 R.string.android_upgrading_complete), 7496 false); 7497 systemReady(goingCallback); 7498 } 7499 }); 7500 } 7501 }; 7502 } 7503 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7504 /* TODO: Send this to all users */ 7505 broadcastIntentLocked(null, null, intent, null, finisher, 7506 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7507 0 /* UserId zero */); 7508 if (finisher != null) { 7509 mWaitingUpdate = true; 7510 } 7511 } 7512 } 7513 if (mWaitingUpdate) { 7514 return; 7515 } 7516 mDidUpdate = true; 7517 } 7518 7519 mSystemReady = true; 7520 if (!mStartRunning) { 7521 return; 7522 } 7523 } 7524 7525 ArrayList<ProcessRecord> procsToKill = null; 7526 synchronized(mPidsSelfLocked) { 7527 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7528 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7529 if (!isAllowedWhileBooting(proc.info)){ 7530 if (procsToKill == null) { 7531 procsToKill = new ArrayList<ProcessRecord>(); 7532 } 7533 procsToKill.add(proc); 7534 } 7535 } 7536 } 7537 7538 synchronized(this) { 7539 if (procsToKill != null) { 7540 for (int i=procsToKill.size()-1; i>=0; i--) { 7541 ProcessRecord proc = procsToKill.get(i); 7542 Slog.i(TAG, "Removing system update proc: " + proc); 7543 removeProcessLocked(proc, true, false, "system update done"); 7544 } 7545 } 7546 7547 // Now that we have cleaned up any update processes, we 7548 // are ready to start launching real processes and know that 7549 // we won't trample on them any more. 7550 mProcessesReady = true; 7551 } 7552 7553 Slog.i(TAG, "System now ready"); 7554 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7555 SystemClock.uptimeMillis()); 7556 7557 synchronized(this) { 7558 // Make sure we have no pre-ready processes sitting around. 7559 7560 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7561 ResolveInfo ri = mContext.getPackageManager() 7562 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7563 STOCK_PM_FLAGS); 7564 CharSequence errorMsg = null; 7565 if (ri != null) { 7566 ActivityInfo ai = ri.activityInfo; 7567 ApplicationInfo app = ai.applicationInfo; 7568 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7569 mTopAction = Intent.ACTION_FACTORY_TEST; 7570 mTopData = null; 7571 mTopComponent = new ComponentName(app.packageName, 7572 ai.name); 7573 } else { 7574 errorMsg = mContext.getResources().getText( 7575 com.android.internal.R.string.factorytest_not_system); 7576 } 7577 } else { 7578 errorMsg = mContext.getResources().getText( 7579 com.android.internal.R.string.factorytest_no_action); 7580 } 7581 if (errorMsg != null) { 7582 mTopAction = null; 7583 mTopData = null; 7584 mTopComponent = null; 7585 Message msg = Message.obtain(); 7586 msg.what = SHOW_FACTORY_ERROR_MSG; 7587 msg.getData().putCharSequence("msg", errorMsg); 7588 mHandler.sendMessage(msg); 7589 } 7590 } 7591 } 7592 7593 retrieveSettings(); 7594 7595 if (goingCallback != null) goingCallback.run(); 7596 7597 synchronized (this) { 7598 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7599 try { 7600 List apps = AppGlobals.getPackageManager(). 7601 getPersistentApplications(STOCK_PM_FLAGS); 7602 if (apps != null) { 7603 int N = apps.size(); 7604 int i; 7605 for (i=0; i<N; i++) { 7606 ApplicationInfo info 7607 = (ApplicationInfo)apps.get(i); 7608 if (info != null && 7609 !info.packageName.equals("android")) { 7610 addAppLocked(info, false); 7611 } 7612 } 7613 } 7614 } catch (RemoteException ex) { 7615 // pm is in same process, this will never happen. 7616 } 7617 } 7618 7619 // Start up initial activity. 7620 mBooting = true; 7621 7622 try { 7623 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7624 Message msg = Message.obtain(); 7625 msg.what = SHOW_UID_ERROR_MSG; 7626 mHandler.sendMessage(msg); 7627 } 7628 } catch (RemoteException e) { 7629 } 7630 7631 mMainStack.resumeTopActivityLocked(null); 7632 } 7633 } 7634 7635 private boolean makeAppCrashingLocked(ProcessRecord app, 7636 String shortMsg, String longMsg, String stackTrace) { 7637 app.crashing = true; 7638 app.crashingReport = generateProcessError(app, 7639 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7640 startAppProblemLocked(app); 7641 app.stopFreezingAllLocked(); 7642 return handleAppCrashLocked(app); 7643 } 7644 7645 private void makeAppNotRespondingLocked(ProcessRecord app, 7646 String activity, String shortMsg, String longMsg) { 7647 app.notResponding = true; 7648 app.notRespondingReport = generateProcessError(app, 7649 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7650 activity, shortMsg, longMsg, null); 7651 startAppProblemLocked(app); 7652 app.stopFreezingAllLocked(); 7653 } 7654 7655 /** 7656 * Generate a process error record, suitable for attachment to a ProcessRecord. 7657 * 7658 * @param app The ProcessRecord in which the error occurred. 7659 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7660 * ActivityManager.AppErrorStateInfo 7661 * @param activity The activity associated with the crash, if known. 7662 * @param shortMsg Short message describing the crash. 7663 * @param longMsg Long message describing the crash. 7664 * @param stackTrace Full crash stack trace, may be null. 7665 * 7666 * @return Returns a fully-formed AppErrorStateInfo record. 7667 */ 7668 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7669 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7670 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7671 7672 report.condition = condition; 7673 report.processName = app.processName; 7674 report.pid = app.pid; 7675 report.uid = app.info.uid; 7676 report.tag = activity; 7677 report.shortMsg = shortMsg; 7678 report.longMsg = longMsg; 7679 report.stackTrace = stackTrace; 7680 7681 return report; 7682 } 7683 7684 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7685 synchronized (this) { 7686 app.crashing = false; 7687 app.crashingReport = null; 7688 app.notResponding = false; 7689 app.notRespondingReport = null; 7690 if (app.anrDialog == fromDialog) { 7691 app.anrDialog = null; 7692 } 7693 if (app.waitDialog == fromDialog) { 7694 app.waitDialog = null; 7695 } 7696 if (app.pid > 0 && app.pid != MY_PID) { 7697 handleAppCrashLocked(app); 7698 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7699 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7700 app.processName, app.setAdj, "user's request after error"); 7701 Process.killProcessQuiet(app.pid); 7702 } 7703 } 7704 } 7705 7706 private boolean handleAppCrashLocked(ProcessRecord app) { 7707 if (mHeadless) { 7708 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7709 return false; 7710 } 7711 long now = SystemClock.uptimeMillis(); 7712 7713 Long crashTime; 7714 if (!app.isolated) { 7715 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7716 } else { 7717 crashTime = null; 7718 } 7719 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7720 // This process loses! 7721 Slog.w(TAG, "Process " + app.info.processName 7722 + " has crashed too many times: killing!"); 7723 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7724 app.info.processName, app.uid); 7725 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7726 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7727 if (r.app == app) { 7728 Slog.w(TAG, " Force finishing activity " 7729 + r.intent.getComponent().flattenToShortString()); 7730 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7731 } 7732 } 7733 if (!app.persistent) { 7734 // We don't want to start this process again until the user 7735 // explicitly does so... but for persistent process, we really 7736 // need to keep it running. If a persistent process is actually 7737 // repeatedly crashing, then badness for everyone. 7738 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7739 app.info.processName); 7740 if (!app.isolated) { 7741 // XXX We don't have a way to mark isolated processes 7742 // as bad, since they don't have a peristent identity. 7743 mBadProcesses.put(app.info.processName, app.uid, now); 7744 mProcessCrashTimes.remove(app.info.processName, app.uid); 7745 } 7746 app.bad = true; 7747 app.removed = true; 7748 // Don't let services in this process be restarted and potentially 7749 // annoy the user repeatedly. Unless it is persistent, since those 7750 // processes run critical code. 7751 removeProcessLocked(app, false, false, "crash"); 7752 mMainStack.resumeTopActivityLocked(null); 7753 return false; 7754 } 7755 mMainStack.resumeTopActivityLocked(null); 7756 } else { 7757 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7758 if (r != null && r.app == app) { 7759 // If the top running activity is from this crashing 7760 // process, then terminate it to avoid getting in a loop. 7761 Slog.w(TAG, " Force finishing activity " 7762 + r.intent.getComponent().flattenToShortString()); 7763 int index = mMainStack.indexOfActivityLocked(r); 7764 r.stack.finishActivityLocked(r, index, 7765 Activity.RESULT_CANCELED, null, "crashed"); 7766 // Also terminate any activities below it that aren't yet 7767 // stopped, to avoid a situation where one will get 7768 // re-start our crashing activity once it gets resumed again. 7769 index--; 7770 if (index >= 0) { 7771 r = (ActivityRecord)mMainStack.mHistory.get(index); 7772 if (r.state == ActivityState.RESUMED 7773 || r.state == ActivityState.PAUSING 7774 || r.state == ActivityState.PAUSED) { 7775 if (!r.isHomeActivity || mHomeProcess != r.app) { 7776 Slog.w(TAG, " Force finishing activity " 7777 + r.intent.getComponent().flattenToShortString()); 7778 r.stack.finishActivityLocked(r, index, 7779 Activity.RESULT_CANCELED, null, "crashed"); 7780 } 7781 } 7782 } 7783 } 7784 } 7785 7786 // Bump up the crash count of any services currently running in the proc. 7787 if (app.services.size() != 0) { 7788 // Any services running in the application need to be placed 7789 // back in the pending list. 7790 Iterator<ServiceRecord> it = app.services.iterator(); 7791 while (it.hasNext()) { 7792 ServiceRecord sr = it.next(); 7793 sr.crashCount++; 7794 } 7795 } 7796 7797 // If the crashing process is what we consider to be the "home process" and it has been 7798 // replaced by a third-party app, clear the package preferred activities from packages 7799 // with a home activity running in the process to prevent a repeatedly crashing app 7800 // from blocking the user to manually clear the list. 7801 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7802 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7803 Iterator it = mHomeProcess.activities.iterator(); 7804 while (it.hasNext()) { 7805 ActivityRecord r = (ActivityRecord)it.next(); 7806 if (r.isHomeActivity) { 7807 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7808 try { 7809 ActivityThread.getPackageManager() 7810 .clearPackagePreferredActivities(r.packageName); 7811 } catch (RemoteException c) { 7812 // pm is in same process, this will never happen. 7813 } 7814 } 7815 } 7816 } 7817 7818 if (!app.isolated) { 7819 // XXX Can't keep track of crash times for isolated processes, 7820 // because they don't have a perisistent identity. 7821 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7822 } 7823 7824 return true; 7825 } 7826 7827 void startAppProblemLocked(ProcessRecord app) { 7828 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7829 mContext, app.info.packageName, app.info.flags); 7830 skipCurrentReceiverLocked(app); 7831 } 7832 7833 void skipCurrentReceiverLocked(ProcessRecord app) { 7834 for (BroadcastQueue queue : mBroadcastQueues) { 7835 queue.skipCurrentReceiverLocked(app); 7836 } 7837 } 7838 7839 /** 7840 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7841 * The application process will exit immediately after this call returns. 7842 * @param app object of the crashing app, null for the system server 7843 * @param crashInfo describing the exception 7844 */ 7845 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7846 ProcessRecord r = findAppProcess(app, "Crash"); 7847 final String processName = app == null ? "system_server" 7848 : (r == null ? "unknown" : r.processName); 7849 7850 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7851 processName, 7852 r == null ? -1 : r.info.flags, 7853 crashInfo.exceptionClassName, 7854 crashInfo.exceptionMessage, 7855 crashInfo.throwFileName, 7856 crashInfo.throwLineNumber); 7857 7858 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7859 7860 crashApplication(r, crashInfo); 7861 } 7862 7863 public void handleApplicationStrictModeViolation( 7864 IBinder app, 7865 int violationMask, 7866 StrictMode.ViolationInfo info) { 7867 ProcessRecord r = findAppProcess(app, "StrictMode"); 7868 if (r == null) { 7869 return; 7870 } 7871 7872 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7873 Integer stackFingerprint = info.hashCode(); 7874 boolean logIt = true; 7875 synchronized (mAlreadyLoggedViolatedStacks) { 7876 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7877 logIt = false; 7878 // TODO: sub-sample into EventLog for these, with 7879 // the info.durationMillis? Then we'd get 7880 // the relative pain numbers, without logging all 7881 // the stack traces repeatedly. We'd want to do 7882 // likewise in the client code, which also does 7883 // dup suppression, before the Binder call. 7884 } else { 7885 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7886 mAlreadyLoggedViolatedStacks.clear(); 7887 } 7888 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7889 } 7890 } 7891 if (logIt) { 7892 logStrictModeViolationToDropBox(r, info); 7893 } 7894 } 7895 7896 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7897 AppErrorResult result = new AppErrorResult(); 7898 synchronized (this) { 7899 final long origId = Binder.clearCallingIdentity(); 7900 7901 Message msg = Message.obtain(); 7902 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7903 HashMap<String, Object> data = new HashMap<String, Object>(); 7904 data.put("result", result); 7905 data.put("app", r); 7906 data.put("violationMask", violationMask); 7907 data.put("info", info); 7908 msg.obj = data; 7909 mHandler.sendMessage(msg); 7910 7911 Binder.restoreCallingIdentity(origId); 7912 } 7913 int res = result.get(); 7914 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7915 } 7916 } 7917 7918 // Depending on the policy in effect, there could be a bunch of 7919 // these in quick succession so we try to batch these together to 7920 // minimize disk writes, number of dropbox entries, and maximize 7921 // compression, by having more fewer, larger records. 7922 private void logStrictModeViolationToDropBox( 7923 ProcessRecord process, 7924 StrictMode.ViolationInfo info) { 7925 if (info == null) { 7926 return; 7927 } 7928 final boolean isSystemApp = process == null || 7929 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7930 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7931 final String processName = process == null ? "unknown" : process.processName; 7932 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7933 final DropBoxManager dbox = (DropBoxManager) 7934 mContext.getSystemService(Context.DROPBOX_SERVICE); 7935 7936 // Exit early if the dropbox isn't configured to accept this report type. 7937 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7938 7939 boolean bufferWasEmpty; 7940 boolean needsFlush; 7941 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7942 synchronized (sb) { 7943 bufferWasEmpty = sb.length() == 0; 7944 appendDropBoxProcessHeaders(process, processName, sb); 7945 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7946 sb.append("System-App: ").append(isSystemApp).append("\n"); 7947 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7948 if (info.violationNumThisLoop != 0) { 7949 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7950 } 7951 if (info.numAnimationsRunning != 0) { 7952 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7953 } 7954 if (info.broadcastIntentAction != null) { 7955 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7956 } 7957 if (info.durationMillis != -1) { 7958 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7959 } 7960 if (info.numInstances != -1) { 7961 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7962 } 7963 if (info.tags != null) { 7964 for (String tag : info.tags) { 7965 sb.append("Span-Tag: ").append(tag).append("\n"); 7966 } 7967 } 7968 sb.append("\n"); 7969 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7970 sb.append(info.crashInfo.stackTrace); 7971 } 7972 sb.append("\n"); 7973 7974 // Only buffer up to ~64k. Various logging bits truncate 7975 // things at 128k. 7976 needsFlush = (sb.length() > 64 * 1024); 7977 } 7978 7979 // Flush immediately if the buffer's grown too large, or this 7980 // is a non-system app. Non-system apps are isolated with a 7981 // different tag & policy and not batched. 7982 // 7983 // Batching is useful during internal testing with 7984 // StrictMode settings turned up high. Without batching, 7985 // thousands of separate files could be created on boot. 7986 if (!isSystemApp || needsFlush) { 7987 new Thread("Error dump: " + dropboxTag) { 7988 @Override 7989 public void run() { 7990 String report; 7991 synchronized (sb) { 7992 report = sb.toString(); 7993 sb.delete(0, sb.length()); 7994 sb.trimToSize(); 7995 } 7996 if (report.length() != 0) { 7997 dbox.addText(dropboxTag, report); 7998 } 7999 } 8000 }.start(); 8001 return; 8002 } 8003 8004 // System app batching: 8005 if (!bufferWasEmpty) { 8006 // An existing dropbox-writing thread is outstanding, so 8007 // we don't need to start it up. The existing thread will 8008 // catch the buffer appends we just did. 8009 return; 8010 } 8011 8012 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8013 // (After this point, we shouldn't access AMS internal data structures.) 8014 new Thread("Error dump: " + dropboxTag) { 8015 @Override 8016 public void run() { 8017 // 5 second sleep to let stacks arrive and be batched together 8018 try { 8019 Thread.sleep(5000); // 5 seconds 8020 } catch (InterruptedException e) {} 8021 8022 String errorReport; 8023 synchronized (mStrictModeBuffer) { 8024 errorReport = mStrictModeBuffer.toString(); 8025 if (errorReport.length() == 0) { 8026 return; 8027 } 8028 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8029 mStrictModeBuffer.trimToSize(); 8030 } 8031 dbox.addText(dropboxTag, errorReport); 8032 } 8033 }.start(); 8034 } 8035 8036 /** 8037 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8038 * @param app object of the crashing app, null for the system server 8039 * @param tag reported by the caller 8040 * @param crashInfo describing the context of the error 8041 * @return true if the process should exit immediately (WTF is fatal) 8042 */ 8043 public boolean handleApplicationWtf(IBinder app, String tag, 8044 ApplicationErrorReport.CrashInfo crashInfo) { 8045 ProcessRecord r = findAppProcess(app, "WTF"); 8046 final String processName = app == null ? "system_server" 8047 : (r == null ? "unknown" : r.processName); 8048 8049 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8050 processName, 8051 r == null ? -1 : r.info.flags, 8052 tag, crashInfo.exceptionMessage); 8053 8054 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8055 8056 if (r != null && r.pid != Process.myPid() && 8057 Settings.Secure.getInt(mContext.getContentResolver(), 8058 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8059 crashApplication(r, crashInfo); 8060 return true; 8061 } else { 8062 return false; 8063 } 8064 } 8065 8066 /** 8067 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8068 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8069 */ 8070 private ProcessRecord findAppProcess(IBinder app, String reason) { 8071 if (app == null) { 8072 return null; 8073 } 8074 8075 synchronized (this) { 8076 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8077 final int NA = apps.size(); 8078 for (int ia=0; ia<NA; ia++) { 8079 ProcessRecord p = apps.valueAt(ia); 8080 if (p.thread != null && p.thread.asBinder() == app) { 8081 return p; 8082 } 8083 } 8084 } 8085 8086 Slog.w(TAG, "Can't find mystery application for " + reason 8087 + " from pid=" + Binder.getCallingPid() 8088 + " uid=" + Binder.getCallingUid() + ": " + app); 8089 return null; 8090 } 8091 } 8092 8093 /** 8094 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8095 * to append various headers to the dropbox log text. 8096 */ 8097 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8098 StringBuilder sb) { 8099 // Watchdog thread ends up invoking this function (with 8100 // a null ProcessRecord) to add the stack file to dropbox. 8101 // Do not acquire a lock on this (am) in such cases, as it 8102 // could cause a potential deadlock, if and when watchdog 8103 // is invoked due to unavailability of lock on am and it 8104 // would prevent watchdog from killing system_server. 8105 if (process == null) { 8106 sb.append("Process: ").append(processName).append("\n"); 8107 return; 8108 } 8109 // Note: ProcessRecord 'process' is guarded by the service 8110 // instance. (notably process.pkgList, which could otherwise change 8111 // concurrently during execution of this method) 8112 synchronized (this) { 8113 sb.append("Process: ").append(processName).append("\n"); 8114 int flags = process.info.flags; 8115 IPackageManager pm = AppGlobals.getPackageManager(); 8116 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8117 for (String pkg : process.pkgList) { 8118 sb.append("Package: ").append(pkg); 8119 try { 8120 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8121 if (pi != null) { 8122 sb.append(" v").append(pi.versionCode); 8123 if (pi.versionName != null) { 8124 sb.append(" (").append(pi.versionName).append(")"); 8125 } 8126 } 8127 } catch (RemoteException e) { 8128 Slog.e(TAG, "Error getting package info: " + pkg, e); 8129 } 8130 sb.append("\n"); 8131 } 8132 } 8133 } 8134 8135 private static String processClass(ProcessRecord process) { 8136 if (process == null || process.pid == MY_PID) { 8137 return "system_server"; 8138 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8139 return "system_app"; 8140 } else { 8141 return "data_app"; 8142 } 8143 } 8144 8145 /** 8146 * Write a description of an error (crash, WTF, ANR) to the drop box. 8147 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8148 * @param process which caused the error, null means the system server 8149 * @param activity which triggered the error, null if unknown 8150 * @param parent activity related to the error, null if unknown 8151 * @param subject line related to the error, null if absent 8152 * @param report in long form describing the error, null if absent 8153 * @param logFile to include in the report, null if none 8154 * @param crashInfo giving an application stack trace, null if absent 8155 */ 8156 public void addErrorToDropBox(String eventType, 8157 ProcessRecord process, String processName, ActivityRecord activity, 8158 ActivityRecord parent, String subject, 8159 final String report, final File logFile, 8160 final ApplicationErrorReport.CrashInfo crashInfo) { 8161 // NOTE -- this must never acquire the ActivityManagerService lock, 8162 // otherwise the watchdog may be prevented from resetting the system. 8163 8164 final String dropboxTag = processClass(process) + "_" + eventType; 8165 final DropBoxManager dbox = (DropBoxManager) 8166 mContext.getSystemService(Context.DROPBOX_SERVICE); 8167 8168 // Exit early if the dropbox isn't configured to accept this report type. 8169 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8170 8171 final StringBuilder sb = new StringBuilder(1024); 8172 appendDropBoxProcessHeaders(process, processName, sb); 8173 if (activity != null) { 8174 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8175 } 8176 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8177 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8178 } 8179 if (parent != null && parent != activity) { 8180 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8181 } 8182 if (subject != null) { 8183 sb.append("Subject: ").append(subject).append("\n"); 8184 } 8185 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8186 if (Debug.isDebuggerConnected()) { 8187 sb.append("Debugger: Connected\n"); 8188 } 8189 sb.append("\n"); 8190 8191 // Do the rest in a worker thread to avoid blocking the caller on I/O 8192 // (After this point, we shouldn't access AMS internal data structures.) 8193 Thread worker = new Thread("Error dump: " + dropboxTag) { 8194 @Override 8195 public void run() { 8196 if (report != null) { 8197 sb.append(report); 8198 } 8199 if (logFile != null) { 8200 try { 8201 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8202 } catch (IOException e) { 8203 Slog.e(TAG, "Error reading " + logFile, e); 8204 } 8205 } 8206 if (crashInfo != null && crashInfo.stackTrace != null) { 8207 sb.append(crashInfo.stackTrace); 8208 } 8209 8210 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8211 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8212 if (lines > 0) { 8213 sb.append("\n"); 8214 8215 // Merge several logcat streams, and take the last N lines 8216 InputStreamReader input = null; 8217 try { 8218 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8219 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8220 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8221 8222 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8223 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8224 input = new InputStreamReader(logcat.getInputStream()); 8225 8226 int num; 8227 char[] buf = new char[8192]; 8228 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8229 } catch (IOException e) { 8230 Slog.e(TAG, "Error running logcat", e); 8231 } finally { 8232 if (input != null) try { input.close(); } catch (IOException e) {} 8233 } 8234 } 8235 8236 dbox.addText(dropboxTag, sb.toString()); 8237 } 8238 }; 8239 8240 if (process == null) { 8241 // If process is null, we are being called from some internal code 8242 // and may be about to die -- run this synchronously. 8243 worker.run(); 8244 } else { 8245 worker.start(); 8246 } 8247 } 8248 8249 /** 8250 * Bring up the "unexpected error" dialog box for a crashing app. 8251 * Deal with edge cases (intercepts from instrumented applications, 8252 * ActivityController, error intent receivers, that sort of thing). 8253 * @param r the application crashing 8254 * @param crashInfo describing the failure 8255 */ 8256 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8257 long timeMillis = System.currentTimeMillis(); 8258 String shortMsg = crashInfo.exceptionClassName; 8259 String longMsg = crashInfo.exceptionMessage; 8260 String stackTrace = crashInfo.stackTrace; 8261 if (shortMsg != null && longMsg != null) { 8262 longMsg = shortMsg + ": " + longMsg; 8263 } else if (shortMsg != null) { 8264 longMsg = shortMsg; 8265 } 8266 8267 AppErrorResult result = new AppErrorResult(); 8268 synchronized (this) { 8269 if (mController != null) { 8270 try { 8271 String name = r != null ? r.processName : null; 8272 int pid = r != null ? r.pid : Binder.getCallingPid(); 8273 if (!mController.appCrashed(name, pid, 8274 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8275 Slog.w(TAG, "Force-killing crashed app " + name 8276 + " at watcher's request"); 8277 Process.killProcess(pid); 8278 return; 8279 } 8280 } catch (RemoteException e) { 8281 mController = null; 8282 } 8283 } 8284 8285 final long origId = Binder.clearCallingIdentity(); 8286 8287 // If this process is running instrumentation, finish it. 8288 if (r != null && r.instrumentationClass != null) { 8289 Slog.w(TAG, "Error in app " + r.processName 8290 + " running instrumentation " + r.instrumentationClass + ":"); 8291 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8292 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8293 Bundle info = new Bundle(); 8294 info.putString("shortMsg", shortMsg); 8295 info.putString("longMsg", longMsg); 8296 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8297 Binder.restoreCallingIdentity(origId); 8298 return; 8299 } 8300 8301 // If we can't identify the process or it's already exceeded its crash quota, 8302 // quit right away without showing a crash dialog. 8303 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8304 Binder.restoreCallingIdentity(origId); 8305 return; 8306 } 8307 8308 Message msg = Message.obtain(); 8309 msg.what = SHOW_ERROR_MSG; 8310 HashMap data = new HashMap(); 8311 data.put("result", result); 8312 data.put("app", r); 8313 msg.obj = data; 8314 mHandler.sendMessage(msg); 8315 8316 Binder.restoreCallingIdentity(origId); 8317 } 8318 8319 int res = result.get(); 8320 8321 Intent appErrorIntent = null; 8322 synchronized (this) { 8323 if (r != null && !r.isolated) { 8324 // XXX Can't keep track of crash time for isolated processes, 8325 // since they don't have a persistent identity. 8326 mProcessCrashTimes.put(r.info.processName, r.uid, 8327 SystemClock.uptimeMillis()); 8328 } 8329 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8330 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8331 } 8332 } 8333 8334 if (appErrorIntent != null) { 8335 try { 8336 mContext.startActivity(appErrorIntent); 8337 } catch (ActivityNotFoundException e) { 8338 Slog.w(TAG, "bug report receiver dissappeared", e); 8339 } 8340 } 8341 } 8342 8343 Intent createAppErrorIntentLocked(ProcessRecord r, 8344 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8345 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8346 if (report == null) { 8347 return null; 8348 } 8349 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8350 result.setComponent(r.errorReportReceiver); 8351 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8352 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8353 return result; 8354 } 8355 8356 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8357 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8358 if (r.errorReportReceiver == null) { 8359 return null; 8360 } 8361 8362 if (!r.crashing && !r.notResponding) { 8363 return null; 8364 } 8365 8366 ApplicationErrorReport report = new ApplicationErrorReport(); 8367 report.packageName = r.info.packageName; 8368 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8369 report.processName = r.processName; 8370 report.time = timeMillis; 8371 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8372 8373 if (r.crashing) { 8374 report.type = ApplicationErrorReport.TYPE_CRASH; 8375 report.crashInfo = crashInfo; 8376 } else if (r.notResponding) { 8377 report.type = ApplicationErrorReport.TYPE_ANR; 8378 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8379 8380 report.anrInfo.activity = r.notRespondingReport.tag; 8381 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8382 report.anrInfo.info = r.notRespondingReport.longMsg; 8383 } 8384 8385 return report; 8386 } 8387 8388 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8389 enforceNotIsolatedCaller("getProcessesInErrorState"); 8390 // assume our apps are happy - lazy create the list 8391 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8392 8393 final boolean allUsers = ActivityManager.checkUidPermission( 8394 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8395 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8396 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8397 8398 synchronized (this) { 8399 8400 // iterate across all processes 8401 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8402 ProcessRecord app = mLruProcesses.get(i); 8403 if (!allUsers && app.userId != userId) { 8404 continue; 8405 } 8406 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8407 // This one's in trouble, so we'll generate a report for it 8408 // crashes are higher priority (in case there's a crash *and* an anr) 8409 ActivityManager.ProcessErrorStateInfo report = null; 8410 if (app.crashing) { 8411 report = app.crashingReport; 8412 } else if (app.notResponding) { 8413 report = app.notRespondingReport; 8414 } 8415 8416 if (report != null) { 8417 if (errList == null) { 8418 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8419 } 8420 errList.add(report); 8421 } else { 8422 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8423 " crashing = " + app.crashing + 8424 " notResponding = " + app.notResponding); 8425 } 8426 } 8427 } 8428 } 8429 8430 return errList; 8431 } 8432 8433 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8434 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8435 if (currApp != null) { 8436 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8437 } 8438 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8439 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8440 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8441 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8442 if (currApp != null) { 8443 currApp.lru = 0; 8444 } 8445 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8446 } else if (adj >= ProcessList.SERVICE_ADJ) { 8447 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8448 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8449 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8450 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8451 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8452 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8453 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8454 } else { 8455 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8456 } 8457 } 8458 8459 private void fillInProcMemInfo(ProcessRecord app, 8460 ActivityManager.RunningAppProcessInfo outInfo) { 8461 outInfo.pid = app.pid; 8462 outInfo.uid = app.info.uid; 8463 if (mHeavyWeightProcess == app) { 8464 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8465 } 8466 if (app.persistent) { 8467 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8468 } 8469 if (app.hasActivities) { 8470 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8471 } 8472 outInfo.lastTrimLevel = app.trimMemoryLevel; 8473 int adj = app.curAdj; 8474 outInfo.importance = oomAdjToImportance(adj, outInfo); 8475 outInfo.importanceReasonCode = app.adjTypeCode; 8476 } 8477 8478 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8479 enforceNotIsolatedCaller("getRunningAppProcesses"); 8480 // Lazy instantiation of list 8481 List<ActivityManager.RunningAppProcessInfo> runList = null; 8482 final boolean allUsers = ActivityManager.checkUidPermission( 8483 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8484 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8485 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8486 synchronized (this) { 8487 // Iterate across all processes 8488 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8489 ProcessRecord app = mLruProcesses.get(i); 8490 if (!allUsers && app.userId != userId) { 8491 continue; 8492 } 8493 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8494 // Generate process state info for running application 8495 ActivityManager.RunningAppProcessInfo currApp = 8496 new ActivityManager.RunningAppProcessInfo(app.processName, 8497 app.pid, app.getPackageList()); 8498 fillInProcMemInfo(app, currApp); 8499 if (app.adjSource instanceof ProcessRecord) { 8500 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8501 currApp.importanceReasonImportance = oomAdjToImportance( 8502 app.adjSourceOom, null); 8503 } else if (app.adjSource instanceof ActivityRecord) { 8504 ActivityRecord r = (ActivityRecord)app.adjSource; 8505 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8506 } 8507 if (app.adjTarget instanceof ComponentName) { 8508 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8509 } 8510 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8511 // + " lru=" + currApp.lru); 8512 if (runList == null) { 8513 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8514 } 8515 runList.add(currApp); 8516 } 8517 } 8518 } 8519 return runList; 8520 } 8521 8522 public List<ApplicationInfo> getRunningExternalApplications() { 8523 enforceNotIsolatedCaller("getRunningExternalApplications"); 8524 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8525 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8526 if (runningApps != null && runningApps.size() > 0) { 8527 Set<String> extList = new HashSet<String>(); 8528 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8529 if (app.pkgList != null) { 8530 for (String pkg : app.pkgList) { 8531 extList.add(pkg); 8532 } 8533 } 8534 } 8535 IPackageManager pm = AppGlobals.getPackageManager(); 8536 for (String pkg : extList) { 8537 try { 8538 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8539 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8540 retList.add(info); 8541 } 8542 } catch (RemoteException e) { 8543 } 8544 } 8545 } 8546 return retList; 8547 } 8548 8549 @Override 8550 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8551 enforceNotIsolatedCaller("getMyMemoryState"); 8552 synchronized (this) { 8553 ProcessRecord proc; 8554 synchronized (mPidsSelfLocked) { 8555 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8556 } 8557 fillInProcMemInfo(proc, outInfo); 8558 } 8559 } 8560 8561 @Override 8562 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8563 if (checkCallingPermission(android.Manifest.permission.DUMP) 8564 != PackageManager.PERMISSION_GRANTED) { 8565 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8566 + Binder.getCallingPid() 8567 + ", uid=" + Binder.getCallingUid() 8568 + " without permission " 8569 + android.Manifest.permission.DUMP); 8570 return; 8571 } 8572 8573 boolean dumpAll = false; 8574 boolean dumpClient = false; 8575 String dumpPackage = null; 8576 8577 int opti = 0; 8578 while (opti < args.length) { 8579 String opt = args[opti]; 8580 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8581 break; 8582 } 8583 opti++; 8584 if ("-a".equals(opt)) { 8585 dumpAll = true; 8586 } else if ("-c".equals(opt)) { 8587 dumpClient = true; 8588 } else if ("-h".equals(opt)) { 8589 pw.println("Activity manager dump options:"); 8590 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8591 pw.println(" cmd may be one of:"); 8592 pw.println(" a[ctivities]: activity stack state"); 8593 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8594 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8595 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8596 pw.println(" o[om]: out of memory management"); 8597 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8598 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8599 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8600 pw.println(" service [COMP_SPEC]: service client-side state"); 8601 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8602 pw.println(" all: dump all activities"); 8603 pw.println(" top: dump the top activity"); 8604 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8605 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8606 pw.println(" a partial substring in a component name, a"); 8607 pw.println(" hex object identifier."); 8608 pw.println(" -a: include all available server state."); 8609 pw.println(" -c: include client state."); 8610 return; 8611 } else { 8612 pw.println("Unknown argument: " + opt + "; use -h for help"); 8613 } 8614 } 8615 8616 long origId = Binder.clearCallingIdentity(); 8617 boolean more = false; 8618 // Is the caller requesting to dump a particular piece of data? 8619 if (opti < args.length) { 8620 String cmd = args[opti]; 8621 opti++; 8622 if ("activities".equals(cmd) || "a".equals(cmd)) { 8623 synchronized (this) { 8624 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8625 } 8626 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8627 String[] newArgs; 8628 String name; 8629 if (opti >= args.length) { 8630 name = null; 8631 newArgs = EMPTY_STRING_ARRAY; 8632 } else { 8633 name = args[opti]; 8634 opti++; 8635 newArgs = new String[args.length - opti]; 8636 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8637 args.length - opti); 8638 } 8639 synchronized (this) { 8640 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8641 } 8642 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8643 String[] newArgs; 8644 String name; 8645 if (opti >= args.length) { 8646 name = null; 8647 newArgs = EMPTY_STRING_ARRAY; 8648 } else { 8649 name = args[opti]; 8650 opti++; 8651 newArgs = new String[args.length - opti]; 8652 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8653 args.length - opti); 8654 } 8655 synchronized (this) { 8656 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8657 } 8658 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8659 String[] newArgs; 8660 String name; 8661 if (opti >= args.length) { 8662 name = null; 8663 newArgs = EMPTY_STRING_ARRAY; 8664 } else { 8665 name = args[opti]; 8666 opti++; 8667 newArgs = new String[args.length - opti]; 8668 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8669 args.length - opti); 8670 } 8671 synchronized (this) { 8672 dumpProcessesLocked(fd, pw, args, opti, true, name); 8673 } 8674 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8675 synchronized (this) { 8676 dumpOomLocked(fd, pw, args, opti, true); 8677 } 8678 } else if ("provider".equals(cmd)) { 8679 String[] newArgs; 8680 String name; 8681 if (opti >= args.length) { 8682 name = null; 8683 newArgs = EMPTY_STRING_ARRAY; 8684 } else { 8685 name = args[opti]; 8686 opti++; 8687 newArgs = new String[args.length - opti]; 8688 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8689 } 8690 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8691 pw.println("No providers match: " + name); 8692 pw.println("Use -h for help."); 8693 } 8694 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8695 synchronized (this) { 8696 dumpProvidersLocked(fd, pw, args, opti, true, null); 8697 } 8698 } else if ("service".equals(cmd)) { 8699 String[] newArgs; 8700 String name; 8701 if (opti >= args.length) { 8702 name = null; 8703 newArgs = EMPTY_STRING_ARRAY; 8704 } else { 8705 name = args[opti]; 8706 opti++; 8707 newArgs = new String[args.length - opti]; 8708 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8709 args.length - opti); 8710 } 8711 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8712 pw.println("No services match: " + name); 8713 pw.println("Use -h for help."); 8714 } 8715 } else if ("package".equals(cmd)) { 8716 String[] newArgs; 8717 if (opti >= args.length) { 8718 pw.println("package: no package name specified"); 8719 pw.println("Use -h for help."); 8720 } else { 8721 dumpPackage = args[opti]; 8722 opti++; 8723 newArgs = new String[args.length - opti]; 8724 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8725 args.length - opti); 8726 args = newArgs; 8727 opti = 0; 8728 more = true; 8729 } 8730 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8731 synchronized (this) { 8732 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8733 } 8734 } else { 8735 // Dumping a single activity? 8736 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8737 pw.println("Bad activity command, or no activities match: " + cmd); 8738 pw.println("Use -h for help."); 8739 } 8740 } 8741 if (!more) { 8742 Binder.restoreCallingIdentity(origId); 8743 return; 8744 } 8745 } 8746 8747 // No piece of data specified, dump everything. 8748 synchronized (this) { 8749 boolean needSep; 8750 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8751 if (needSep) { 8752 pw.println(" "); 8753 } 8754 if (dumpAll) { 8755 pw.println("-------------------------------------------------------------------------------"); 8756 } 8757 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8758 if (needSep) { 8759 pw.println(" "); 8760 } 8761 if (dumpAll) { 8762 pw.println("-------------------------------------------------------------------------------"); 8763 } 8764 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8765 if (needSep) { 8766 pw.println(" "); 8767 } 8768 if (dumpAll) { 8769 pw.println("-------------------------------------------------------------------------------"); 8770 } 8771 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8772 if (needSep) { 8773 pw.println(" "); 8774 } 8775 if (dumpAll) { 8776 pw.println("-------------------------------------------------------------------------------"); 8777 } 8778 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8779 if (needSep) { 8780 pw.println(" "); 8781 } 8782 if (dumpAll) { 8783 pw.println("-------------------------------------------------------------------------------"); 8784 } 8785 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8786 } 8787 Binder.restoreCallingIdentity(origId); 8788 } 8789 8790 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8791 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8792 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8793 pw.println(" Main stack:"); 8794 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8795 dumpPackage); 8796 pw.println(" "); 8797 pw.println(" Running activities (most recent first):"); 8798 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8799 dumpPackage); 8800 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8801 pw.println(" "); 8802 pw.println(" Activities waiting for another to become visible:"); 8803 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8804 !dumpAll, false, dumpPackage); 8805 } 8806 if (mMainStack.mStoppingActivities.size() > 0) { 8807 pw.println(" "); 8808 pw.println(" Activities waiting to stop:"); 8809 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8810 !dumpAll, false, dumpPackage); 8811 } 8812 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8813 pw.println(" "); 8814 pw.println(" Activities waiting to sleep:"); 8815 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8816 !dumpAll, false, dumpPackage); 8817 } 8818 if (mMainStack.mFinishingActivities.size() > 0) { 8819 pw.println(" "); 8820 pw.println(" Activities waiting to finish:"); 8821 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8822 !dumpAll, false, dumpPackage); 8823 } 8824 8825 pw.println(" "); 8826 if (mMainStack.mPausingActivity != null) { 8827 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8828 } 8829 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8830 pw.println(" mFocusedActivity: " + mFocusedActivity); 8831 if (dumpAll) { 8832 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8833 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8834 pw.println(" mDismissKeyguardOnNextActivity: " 8835 + mMainStack.mDismissKeyguardOnNextActivity); 8836 } 8837 8838 if (mRecentTasks.size() > 0) { 8839 pw.println(); 8840 pw.println(" Recent tasks:"); 8841 8842 final int N = mRecentTasks.size(); 8843 for (int i=0; i<N; i++) { 8844 TaskRecord tr = mRecentTasks.get(i); 8845 if (dumpPackage != null) { 8846 if (tr.realActivity == null || 8847 !dumpPackage.equals(tr.realActivity)) { 8848 continue; 8849 } 8850 } 8851 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8852 pw.println(tr); 8853 if (dumpAll) { 8854 mRecentTasks.get(i).dump(pw, " "); 8855 } 8856 } 8857 } 8858 8859 if (dumpAll) { 8860 pw.println(" "); 8861 pw.println(" mCurTask: " + mCurTask); 8862 } 8863 8864 return true; 8865 } 8866 8867 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8868 int opti, boolean dumpAll, String dumpPackage) { 8869 boolean needSep = false; 8870 int numPers = 0; 8871 8872 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8873 8874 if (dumpAll) { 8875 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8876 final int NA = procs.size(); 8877 for (int ia=0; ia<NA; ia++) { 8878 ProcessRecord r = procs.valueAt(ia); 8879 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8880 continue; 8881 } 8882 if (!needSep) { 8883 pw.println(" All known processes:"); 8884 needSep = true; 8885 } 8886 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8887 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8888 pw.print(" "); pw.println(r); 8889 r.dump(pw, " "); 8890 if (r.persistent) { 8891 numPers++; 8892 } 8893 } 8894 } 8895 } 8896 8897 if (mIsolatedProcesses.size() > 0) { 8898 if (needSep) pw.println(" "); 8899 needSep = true; 8900 pw.println(" Isolated process list (sorted by uid):"); 8901 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8902 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8903 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8904 continue; 8905 } 8906 pw.println(String.format("%sIsolated #%2d: %s", 8907 " ", i, r.toString())); 8908 } 8909 } 8910 8911 if (mLruProcesses.size() > 0) { 8912 if (needSep) pw.println(" "); 8913 needSep = true; 8914 pw.println(" Process LRU list (sorted by oom_adj):"); 8915 dumpProcessOomList(pw, this, mLruProcesses, " ", 8916 "Proc", "PERS", false, dumpPackage); 8917 needSep = true; 8918 } 8919 8920 if (dumpAll) { 8921 synchronized (mPidsSelfLocked) { 8922 boolean printed = false; 8923 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8924 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8925 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8926 continue; 8927 } 8928 if (!printed) { 8929 if (needSep) pw.println(" "); 8930 needSep = true; 8931 pw.println(" PID mappings:"); 8932 printed = true; 8933 } 8934 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8935 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8936 } 8937 } 8938 } 8939 8940 if (mForegroundProcesses.size() > 0) { 8941 synchronized (mPidsSelfLocked) { 8942 boolean printed = false; 8943 for (int i=0; i<mForegroundProcesses.size(); i++) { 8944 ProcessRecord r = mPidsSelfLocked.get( 8945 mForegroundProcesses.valueAt(i).pid); 8946 if (dumpPackage != null && (r == null 8947 || !dumpPackage.equals(r.info.packageName))) { 8948 continue; 8949 } 8950 if (!printed) { 8951 if (needSep) pw.println(" "); 8952 needSep = true; 8953 pw.println(" Foreground Processes:"); 8954 printed = true; 8955 } 8956 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8957 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8958 } 8959 } 8960 } 8961 8962 if (mPersistentStartingProcesses.size() > 0) { 8963 if (needSep) pw.println(" "); 8964 needSep = true; 8965 pw.println(" Persisent processes that are starting:"); 8966 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8967 "Starting Norm", "Restarting PERS", dumpPackage); 8968 } 8969 8970 if (mRemovedProcesses.size() > 0) { 8971 if (needSep) pw.println(" "); 8972 needSep = true; 8973 pw.println(" Processes that are being removed:"); 8974 dumpProcessList(pw, this, mRemovedProcesses, " ", 8975 "Removed Norm", "Removed PERS", dumpPackage); 8976 } 8977 8978 if (mProcessesOnHold.size() > 0) { 8979 if (needSep) pw.println(" "); 8980 needSep = true; 8981 pw.println(" Processes that are on old until the system is ready:"); 8982 dumpProcessList(pw, this, mProcessesOnHold, " ", 8983 "OnHold Norm", "OnHold PERS", dumpPackage); 8984 } 8985 8986 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8987 8988 if (mProcessCrashTimes.getMap().size() > 0) { 8989 boolean printed = false; 8990 long now = SystemClock.uptimeMillis(); 8991 for (Map.Entry<String, SparseArray<Long>> procs 8992 : mProcessCrashTimes.getMap().entrySet()) { 8993 String pname = procs.getKey(); 8994 SparseArray<Long> uids = procs.getValue(); 8995 final int N = uids.size(); 8996 for (int i=0; i<N; i++) { 8997 int puid = uids.keyAt(i); 8998 ProcessRecord r = mProcessNames.get(pname, puid); 8999 if (dumpPackage != null && (r == null 9000 || !dumpPackage.equals(r.info.packageName))) { 9001 continue; 9002 } 9003 if (!printed) { 9004 if (needSep) pw.println(" "); 9005 needSep = true; 9006 pw.println(" Time since processes crashed:"); 9007 printed = true; 9008 } 9009 pw.print(" Process "); pw.print(pname); 9010 pw.print(" uid "); pw.print(puid); 9011 pw.print(": last crashed "); 9012 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9013 pw.println(" ago"); 9014 } 9015 } 9016 } 9017 9018 if (mBadProcesses.getMap().size() > 0) { 9019 boolean printed = false; 9020 for (Map.Entry<String, SparseArray<Long>> procs 9021 : mBadProcesses.getMap().entrySet()) { 9022 String pname = procs.getKey(); 9023 SparseArray<Long> uids = procs.getValue(); 9024 final int N = uids.size(); 9025 for (int i=0; i<N; i++) { 9026 int puid = uids.keyAt(i); 9027 ProcessRecord r = mProcessNames.get(pname, puid); 9028 if (dumpPackage != null && (r == null 9029 || !dumpPackage.equals(r.info.packageName))) { 9030 continue; 9031 } 9032 if (!printed) { 9033 if (needSep) pw.println(" "); 9034 needSep = true; 9035 pw.println(" Bad processes:"); 9036 } 9037 pw.print(" Bad process "); pw.print(pname); 9038 pw.print(" uid "); pw.print(puid); 9039 pw.print(": crashed at time "); 9040 pw.println(uids.valueAt(i)); 9041 } 9042 } 9043 } 9044 9045 pw.println(); 9046 pw.println(" mHomeProcess: " + mHomeProcess); 9047 pw.println(" mPreviousProcess: " + mPreviousProcess); 9048 if (dumpAll) { 9049 StringBuilder sb = new StringBuilder(128); 9050 sb.append(" mPreviousProcessVisibleTime: "); 9051 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9052 pw.println(sb); 9053 } 9054 if (mHeavyWeightProcess != null) { 9055 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9056 } 9057 pw.println(" mConfiguration: " + mConfiguration); 9058 if (dumpAll) { 9059 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9060 if (mCompatModePackages.getPackages().size() > 0) { 9061 boolean printed = false; 9062 for (Map.Entry<String, Integer> entry 9063 : mCompatModePackages.getPackages().entrySet()) { 9064 String pkg = entry.getKey(); 9065 int mode = entry.getValue(); 9066 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9067 continue; 9068 } 9069 if (!printed) { 9070 pw.println(" mScreenCompatPackages:"); 9071 printed = true; 9072 } 9073 pw.print(" "); pw.print(pkg); pw.print(": "); 9074 pw.print(mode); pw.println(); 9075 } 9076 } 9077 } 9078 if (mSleeping || mWentToSleep || mLockScreenShown) { 9079 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9080 + " mLockScreenShown " + mLockScreenShown); 9081 } 9082 if (mShuttingDown) { 9083 pw.println(" mShuttingDown=" + mShuttingDown); 9084 } 9085 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9086 || mOrigWaitForDebugger) { 9087 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9088 + " mDebugTransient=" + mDebugTransient 9089 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9090 } 9091 if (mOpenGlTraceApp != null) { 9092 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9093 } 9094 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9095 || mProfileFd != null) { 9096 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9097 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9098 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9099 + mAutoStopProfiler); 9100 } 9101 if (mAlwaysFinishActivities || mController != null) { 9102 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9103 + " mController=" + mController); 9104 } 9105 if (dumpAll) { 9106 pw.println(" Total persistent processes: " + numPers); 9107 pw.println(" mStartRunning=" + mStartRunning 9108 + " mProcessesReady=" + mProcessesReady 9109 + " mSystemReady=" + mSystemReady); 9110 pw.println(" mBooting=" + mBooting 9111 + " mBooted=" + mBooted 9112 + " mFactoryTest=" + mFactoryTest); 9113 pw.print(" mLastPowerCheckRealtime="); 9114 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9115 pw.println(""); 9116 pw.print(" mLastPowerCheckUptime="); 9117 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9118 pw.println(""); 9119 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9120 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9121 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9122 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9123 + " mNumHiddenProcs=" + mNumHiddenProcs 9124 + " mNumServiceProcs=" + mNumServiceProcs 9125 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9126 } 9127 9128 return true; 9129 } 9130 9131 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9132 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9133 if (mProcessesToGc.size() > 0) { 9134 boolean printed = false; 9135 long now = SystemClock.uptimeMillis(); 9136 for (int i=0; i<mProcessesToGc.size(); i++) { 9137 ProcessRecord proc = mProcessesToGc.get(i); 9138 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9139 continue; 9140 } 9141 if (!printed) { 9142 if (needSep) pw.println(" "); 9143 needSep = true; 9144 pw.println(" Processes that are waiting to GC:"); 9145 printed = true; 9146 } 9147 pw.print(" Process "); pw.println(proc); 9148 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9149 pw.print(", last gced="); 9150 pw.print(now-proc.lastRequestedGc); 9151 pw.print(" ms ago, last lowMem="); 9152 pw.print(now-proc.lastLowMemory); 9153 pw.println(" ms ago"); 9154 9155 } 9156 } 9157 return needSep; 9158 } 9159 9160 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9161 int opti, boolean dumpAll) { 9162 boolean needSep = false; 9163 9164 if (mLruProcesses.size() > 0) { 9165 if (needSep) pw.println(" "); 9166 needSep = true; 9167 pw.println(" OOM levels:"); 9168 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9169 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9170 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9171 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9172 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9173 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9174 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9175 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9176 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9177 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9178 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9179 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9180 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9181 9182 if (needSep) pw.println(" "); 9183 needSep = true; 9184 pw.println(" Process OOM control:"); 9185 dumpProcessOomList(pw, this, mLruProcesses, " ", 9186 "Proc", "PERS", true, null); 9187 needSep = true; 9188 } 9189 9190 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9191 9192 pw.println(); 9193 pw.println(" mHomeProcess: " + mHomeProcess); 9194 pw.println(" mPreviousProcess: " + mPreviousProcess); 9195 if (mHeavyWeightProcess != null) { 9196 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9197 } 9198 9199 return true; 9200 } 9201 9202 /** 9203 * There are three ways to call this: 9204 * - no provider specified: dump all the providers 9205 * - a flattened component name that matched an existing provider was specified as the 9206 * first arg: dump that one provider 9207 * - the first arg isn't the flattened component name of an existing provider: 9208 * dump all providers whose component contains the first arg as a substring 9209 */ 9210 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9211 int opti, boolean dumpAll) { 9212 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9213 } 9214 9215 static class ItemMatcher { 9216 ArrayList<ComponentName> components; 9217 ArrayList<String> strings; 9218 ArrayList<Integer> objects; 9219 boolean all; 9220 9221 ItemMatcher() { 9222 all = true; 9223 } 9224 9225 void build(String name) { 9226 ComponentName componentName = ComponentName.unflattenFromString(name); 9227 if (componentName != null) { 9228 if (components == null) { 9229 components = new ArrayList<ComponentName>(); 9230 } 9231 components.add(componentName); 9232 all = false; 9233 } else { 9234 int objectId = 0; 9235 // Not a '/' separated full component name; maybe an object ID? 9236 try { 9237 objectId = Integer.parseInt(name, 16); 9238 if (objects == null) { 9239 objects = new ArrayList<Integer>(); 9240 } 9241 objects.add(objectId); 9242 all = false; 9243 } catch (RuntimeException e) { 9244 // Not an integer; just do string match. 9245 if (strings == null) { 9246 strings = new ArrayList<String>(); 9247 } 9248 strings.add(name); 9249 all = false; 9250 } 9251 } 9252 } 9253 9254 int build(String[] args, int opti) { 9255 for (; opti<args.length; opti++) { 9256 String name = args[opti]; 9257 if ("--".equals(name)) { 9258 return opti+1; 9259 } 9260 build(name); 9261 } 9262 return opti; 9263 } 9264 9265 boolean match(Object object, ComponentName comp) { 9266 if (all) { 9267 return true; 9268 } 9269 if (components != null) { 9270 for (int i=0; i<components.size(); i++) { 9271 if (components.get(i).equals(comp)) { 9272 return true; 9273 } 9274 } 9275 } 9276 if (objects != null) { 9277 for (int i=0; i<objects.size(); i++) { 9278 if (System.identityHashCode(object) == objects.get(i)) { 9279 return true; 9280 } 9281 } 9282 } 9283 if (strings != null) { 9284 String flat = comp.flattenToString(); 9285 for (int i=0; i<strings.size(); i++) { 9286 if (flat.contains(strings.get(i))) { 9287 return true; 9288 } 9289 } 9290 } 9291 return false; 9292 } 9293 } 9294 9295 /** 9296 * There are three things that cmd can be: 9297 * - a flattened component name that matches an existing activity 9298 * - the cmd arg isn't the flattened component name of an existing activity: 9299 * dump all activity whose component contains the cmd as a substring 9300 * - A hex number of the ActivityRecord object instance. 9301 */ 9302 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9303 int opti, boolean dumpAll) { 9304 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9305 9306 if ("all".equals(name)) { 9307 synchronized (this) { 9308 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9309 activities.add(r1); 9310 } 9311 } 9312 } else if ("top".equals(name)) { 9313 synchronized (this) { 9314 final int N = mMainStack.mHistory.size(); 9315 if (N > 0) { 9316 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9317 } 9318 } 9319 } else { 9320 ItemMatcher matcher = new ItemMatcher(); 9321 matcher.build(name); 9322 9323 synchronized (this) { 9324 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9325 if (matcher.match(r1, r1.intent.getComponent())) { 9326 activities.add(r1); 9327 } 9328 } 9329 } 9330 } 9331 9332 if (activities.size() <= 0) { 9333 return false; 9334 } 9335 9336 String[] newArgs = new String[args.length - opti]; 9337 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9338 9339 TaskRecord lastTask = null; 9340 boolean needSep = false; 9341 for (int i=activities.size()-1; i>=0; i--) { 9342 ActivityRecord r = (ActivityRecord)activities.get(i); 9343 if (needSep) { 9344 pw.println(); 9345 } 9346 needSep = true; 9347 synchronized (this) { 9348 if (lastTask != r.task) { 9349 lastTask = r.task; 9350 pw.print("TASK "); pw.print(lastTask.affinity); 9351 pw.print(" id="); pw.println(lastTask.taskId); 9352 if (dumpAll) { 9353 lastTask.dump(pw, " "); 9354 } 9355 } 9356 } 9357 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9358 } 9359 return true; 9360 } 9361 9362 /** 9363 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9364 * there is a thread associated with the activity. 9365 */ 9366 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9367 final ActivityRecord r, String[] args, boolean dumpAll) { 9368 String innerPrefix = prefix + " "; 9369 synchronized (this) { 9370 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9371 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9372 pw.print(" pid="); 9373 if (r.app != null) pw.println(r.app.pid); 9374 else pw.println("(not running)"); 9375 if (dumpAll) { 9376 r.dump(pw, innerPrefix); 9377 } 9378 } 9379 if (r.app != null && r.app.thread != null) { 9380 // flush anything that is already in the PrintWriter since the thread is going 9381 // to write to the file descriptor directly 9382 pw.flush(); 9383 try { 9384 TransferPipe tp = new TransferPipe(); 9385 try { 9386 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9387 r.appToken, innerPrefix, args); 9388 tp.go(fd); 9389 } finally { 9390 tp.kill(); 9391 } 9392 } catch (IOException e) { 9393 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9394 } catch (RemoteException e) { 9395 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9396 } 9397 } 9398 } 9399 9400 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9401 int opti, boolean dumpAll, String dumpPackage) { 9402 boolean needSep = false; 9403 9404 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9405 if (dumpAll) { 9406 if (mRegisteredReceivers.size() > 0) { 9407 boolean printed = false; 9408 Iterator it = mRegisteredReceivers.values().iterator(); 9409 while (it.hasNext()) { 9410 ReceiverList r = (ReceiverList)it.next(); 9411 if (dumpPackage != null && (r.app == null || 9412 !dumpPackage.equals(r.app.info.packageName))) { 9413 continue; 9414 } 9415 if (!printed) { 9416 pw.println(" Registered Receivers:"); 9417 needSep = true; 9418 printed = true; 9419 } 9420 pw.print(" * "); pw.println(r); 9421 r.dump(pw, " "); 9422 } 9423 } 9424 9425 if (mReceiverResolver.dump(pw, needSep ? 9426 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9427 " ", dumpPackage, false)) { 9428 needSep = true; 9429 } 9430 } 9431 9432 for (BroadcastQueue q : mBroadcastQueues) { 9433 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9434 } 9435 9436 needSep = true; 9437 9438 if (mStickyBroadcasts != null && dumpPackage == null) { 9439 if (needSep) { 9440 pw.println(); 9441 } 9442 needSep = true; 9443 pw.println(" Sticky broadcasts:"); 9444 StringBuilder sb = new StringBuilder(128); 9445 for (Map.Entry<String, ArrayList<Intent>> ent 9446 : mStickyBroadcasts.entrySet()) { 9447 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9448 if (dumpAll) { 9449 pw.println(":"); 9450 ArrayList<Intent> intents = ent.getValue(); 9451 final int N = intents.size(); 9452 for (int i=0; i<N; i++) { 9453 sb.setLength(0); 9454 sb.append(" Intent: "); 9455 intents.get(i).toShortString(sb, false, true, false, false); 9456 pw.println(sb.toString()); 9457 Bundle bundle = intents.get(i).getExtras(); 9458 if (bundle != null) { 9459 pw.print(" "); 9460 pw.println(bundle.toString()); 9461 } 9462 } 9463 } else { 9464 pw.println(""); 9465 } 9466 } 9467 needSep = true; 9468 } 9469 9470 if (dumpAll) { 9471 pw.println(); 9472 for (BroadcastQueue queue : mBroadcastQueues) { 9473 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9474 + queue.mBroadcastsScheduled); 9475 } 9476 pw.println(" mHandler:"); 9477 mHandler.dump(new PrintWriterPrinter(pw), " "); 9478 needSep = true; 9479 } 9480 9481 return needSep; 9482 } 9483 9484 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9485 int opti, boolean dumpAll, String dumpPackage) { 9486 boolean needSep = true; 9487 9488 ItemMatcher matcher = new ItemMatcher(); 9489 matcher.build(args, opti); 9490 9491 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9492 9493 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9494 9495 if (mLaunchingProviders.size() > 0) { 9496 boolean printed = false; 9497 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9498 ContentProviderRecord r = mLaunchingProviders.get(i); 9499 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9500 continue; 9501 } 9502 if (!printed) { 9503 if (needSep) pw.println(" "); 9504 needSep = true; 9505 pw.println(" Launching content providers:"); 9506 printed = true; 9507 } 9508 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9509 pw.println(r); 9510 } 9511 } 9512 9513 if (mGrantedUriPermissions.size() > 0) { 9514 if (needSep) pw.println(); 9515 needSep = true; 9516 pw.println("Granted Uri Permissions:"); 9517 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9518 int uid = mGrantedUriPermissions.keyAt(i); 9519 HashMap<Uri, UriPermission> perms 9520 = mGrantedUriPermissions.valueAt(i); 9521 pw.print(" * UID "); pw.print(uid); 9522 pw.println(" holds:"); 9523 for (UriPermission perm : perms.values()) { 9524 pw.print(" "); pw.println(perm); 9525 if (dumpAll) { 9526 perm.dump(pw, " "); 9527 } 9528 } 9529 } 9530 needSep = true; 9531 } 9532 9533 return needSep; 9534 } 9535 9536 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9537 int opti, boolean dumpAll, String dumpPackage) { 9538 boolean needSep = false; 9539 9540 if (mIntentSenderRecords.size() > 0) { 9541 boolean printed = false; 9542 Iterator<WeakReference<PendingIntentRecord>> it 9543 = mIntentSenderRecords.values().iterator(); 9544 while (it.hasNext()) { 9545 WeakReference<PendingIntentRecord> ref = it.next(); 9546 PendingIntentRecord rec = ref != null ? ref.get(): null; 9547 if (dumpPackage != null && (rec == null 9548 || !dumpPackage.equals(rec.key.packageName))) { 9549 continue; 9550 } 9551 if (!printed) { 9552 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9553 printed = true; 9554 } 9555 needSep = true; 9556 if (rec != null) { 9557 pw.print(" * "); pw.println(rec); 9558 if (dumpAll) { 9559 rec.dump(pw, " "); 9560 } 9561 } else { 9562 pw.print(" * "); pw.println(ref); 9563 } 9564 } 9565 } 9566 9567 return needSep; 9568 } 9569 9570 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9571 String prefix, String label, boolean complete, boolean brief, boolean client, 9572 String dumpPackage) { 9573 TaskRecord lastTask = null; 9574 boolean needNL = false; 9575 final String innerPrefix = prefix + " "; 9576 final String[] args = new String[0]; 9577 for (int i=list.size()-1; i>=0; i--) { 9578 final ActivityRecord r = (ActivityRecord)list.get(i); 9579 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9580 continue; 9581 } 9582 final boolean full = !brief && (complete || !r.isInHistory()); 9583 if (needNL) { 9584 pw.println(" "); 9585 needNL = false; 9586 } 9587 if (lastTask != r.task) { 9588 lastTask = r.task; 9589 pw.print(prefix); 9590 pw.print(full ? "* " : " "); 9591 pw.println(lastTask); 9592 if (full) { 9593 lastTask.dump(pw, prefix + " "); 9594 } else if (complete) { 9595 // Complete + brief == give a summary. Isn't that obvious?!? 9596 if (lastTask.intent != null) { 9597 pw.print(prefix); pw.print(" "); 9598 pw.println(lastTask.intent.toInsecureStringWithClip()); 9599 } 9600 } 9601 } 9602 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9603 pw.print(" #"); pw.print(i); pw.print(": "); 9604 pw.println(r); 9605 if (full) { 9606 r.dump(pw, innerPrefix); 9607 } else if (complete) { 9608 // Complete + brief == give a summary. Isn't that obvious?!? 9609 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9610 if (r.app != null) { 9611 pw.print(innerPrefix); pw.println(r.app); 9612 } 9613 } 9614 if (client && r.app != null && r.app.thread != null) { 9615 // flush anything that is already in the PrintWriter since the thread is going 9616 // to write to the file descriptor directly 9617 pw.flush(); 9618 try { 9619 TransferPipe tp = new TransferPipe(); 9620 try { 9621 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9622 r.appToken, innerPrefix, args); 9623 // Short timeout, since blocking here can 9624 // deadlock with the application. 9625 tp.go(fd, 2000); 9626 } finally { 9627 tp.kill(); 9628 } 9629 } catch (IOException e) { 9630 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9631 } catch (RemoteException e) { 9632 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9633 } 9634 needNL = true; 9635 } 9636 } 9637 } 9638 9639 private static String buildOomTag(String prefix, String space, int val, int base) { 9640 if (val == base) { 9641 if (space == null) return prefix; 9642 return prefix + " "; 9643 } 9644 return prefix + "+" + Integer.toString(val-base); 9645 } 9646 9647 private static final int dumpProcessList(PrintWriter pw, 9648 ActivityManagerService service, List list, 9649 String prefix, String normalLabel, String persistentLabel, 9650 String dumpPackage) { 9651 int numPers = 0; 9652 final int N = list.size()-1; 9653 for (int i=N; i>=0; i--) { 9654 ProcessRecord r = (ProcessRecord)list.get(i); 9655 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9656 continue; 9657 } 9658 pw.println(String.format("%s%s #%2d: %s", 9659 prefix, (r.persistent ? persistentLabel : normalLabel), 9660 i, r.toString())); 9661 if (r.persistent) { 9662 numPers++; 9663 } 9664 } 9665 return numPers; 9666 } 9667 9668 private static final boolean dumpProcessOomList(PrintWriter pw, 9669 ActivityManagerService service, List<ProcessRecord> origList, 9670 String prefix, String normalLabel, String persistentLabel, 9671 boolean inclDetails, String dumpPackage) { 9672 9673 ArrayList<Pair<ProcessRecord, Integer>> list 9674 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9675 for (int i=0; i<origList.size(); i++) { 9676 ProcessRecord r = origList.get(i); 9677 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9678 continue; 9679 } 9680 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9681 } 9682 9683 if (list.size() <= 0) { 9684 return false; 9685 } 9686 9687 Comparator<Pair<ProcessRecord, Integer>> comparator 9688 = new Comparator<Pair<ProcessRecord, Integer>>() { 9689 @Override 9690 public int compare(Pair<ProcessRecord, Integer> object1, 9691 Pair<ProcessRecord, Integer> object2) { 9692 if (object1.first.setAdj != object2.first.setAdj) { 9693 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9694 } 9695 if (object1.second.intValue() != object2.second.intValue()) { 9696 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9697 } 9698 return 0; 9699 } 9700 }; 9701 9702 Collections.sort(list, comparator); 9703 9704 final long curRealtime = SystemClock.elapsedRealtime(); 9705 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9706 final long curUptime = SystemClock.uptimeMillis(); 9707 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9708 9709 for (int i=list.size()-1; i>=0; i--) { 9710 ProcessRecord r = list.get(i).first; 9711 String oomAdj; 9712 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9713 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9714 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9715 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9716 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9717 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9718 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9719 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9720 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9721 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9722 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9723 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9724 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9725 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9726 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9727 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9728 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9729 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9730 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9731 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9732 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9733 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9734 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9735 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9736 } else { 9737 oomAdj = Integer.toString(r.setAdj); 9738 } 9739 String schedGroup; 9740 switch (r.setSchedGroup) { 9741 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9742 schedGroup = "B"; 9743 break; 9744 case Process.THREAD_GROUP_DEFAULT: 9745 schedGroup = "F"; 9746 break; 9747 default: 9748 schedGroup = Integer.toString(r.setSchedGroup); 9749 break; 9750 } 9751 String foreground; 9752 if (r.foregroundActivities) { 9753 foreground = "A"; 9754 } else if (r.foregroundServices) { 9755 foreground = "S"; 9756 } else { 9757 foreground = " "; 9758 } 9759 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9760 prefix, (r.persistent ? persistentLabel : normalLabel), 9761 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9762 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9763 if (r.adjSource != null || r.adjTarget != null) { 9764 pw.print(prefix); 9765 pw.print(" "); 9766 if (r.adjTarget instanceof ComponentName) { 9767 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9768 } else if (r.adjTarget != null) { 9769 pw.print(r.adjTarget.toString()); 9770 } else { 9771 pw.print("{null}"); 9772 } 9773 pw.print("<="); 9774 if (r.adjSource instanceof ProcessRecord) { 9775 pw.print("Proc{"); 9776 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9777 pw.println("}"); 9778 } else if (r.adjSource != null) { 9779 pw.println(r.adjSource.toString()); 9780 } else { 9781 pw.println("{null}"); 9782 } 9783 } 9784 if (inclDetails) { 9785 pw.print(prefix); 9786 pw.print(" "); 9787 pw.print("oom: max="); pw.print(r.maxAdj); 9788 pw.print(" hidden="); pw.print(r.hiddenAdj); 9789 pw.print(" empty="); pw.print(r.emptyAdj); 9790 pw.print(" curRaw="); pw.print(r.curRawAdj); 9791 pw.print(" setRaw="); pw.print(r.setRawAdj); 9792 pw.print(" cur="); pw.print(r.curAdj); 9793 pw.print(" set="); pw.println(r.setAdj); 9794 pw.print(prefix); 9795 pw.print(" "); 9796 pw.print("keeping="); pw.print(r.keeping); 9797 pw.print(" hidden="); pw.print(r.hidden); 9798 pw.print(" empty="); pw.print(r.empty); 9799 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9800 9801 if (!r.keeping) { 9802 if (r.lastWakeTime != 0) { 9803 long wtime; 9804 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9805 synchronized (stats) { 9806 wtime = stats.getProcessWakeTime(r.info.uid, 9807 r.pid, curRealtime); 9808 } 9809 long timeUsed = wtime - r.lastWakeTime; 9810 pw.print(prefix); 9811 pw.print(" "); 9812 pw.print("keep awake over "); 9813 TimeUtils.formatDuration(realtimeSince, pw); 9814 pw.print(" used "); 9815 TimeUtils.formatDuration(timeUsed, pw); 9816 pw.print(" ("); 9817 pw.print((timeUsed*100)/realtimeSince); 9818 pw.println("%)"); 9819 } 9820 if (r.lastCpuTime != 0) { 9821 long timeUsed = r.curCpuTime - r.lastCpuTime; 9822 pw.print(prefix); 9823 pw.print(" "); 9824 pw.print("run cpu over "); 9825 TimeUtils.formatDuration(uptimeSince, pw); 9826 pw.print(" used "); 9827 TimeUtils.formatDuration(timeUsed, pw); 9828 pw.print(" ("); 9829 pw.print((timeUsed*100)/uptimeSince); 9830 pw.println("%)"); 9831 } 9832 } 9833 } 9834 } 9835 return true; 9836 } 9837 9838 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9839 ArrayList<ProcessRecord> procs; 9840 synchronized (this) { 9841 if (args != null && args.length > start 9842 && args[start].charAt(0) != '-') { 9843 procs = new ArrayList<ProcessRecord>(); 9844 int pid = -1; 9845 try { 9846 pid = Integer.parseInt(args[start]); 9847 } catch (NumberFormatException e) { 9848 9849 } 9850 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9851 ProcessRecord proc = mLruProcesses.get(i); 9852 if (proc.pid == pid) { 9853 procs.add(proc); 9854 } else if (proc.processName.equals(args[start])) { 9855 procs.add(proc); 9856 } 9857 } 9858 if (procs.size() <= 0) { 9859 pw.println("No process found for: " + args[start]); 9860 return null; 9861 } 9862 } else { 9863 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9864 } 9865 } 9866 return procs; 9867 } 9868 9869 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9870 PrintWriter pw, String[] args) { 9871 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9872 if (procs == null) { 9873 return; 9874 } 9875 9876 long uptime = SystemClock.uptimeMillis(); 9877 long realtime = SystemClock.elapsedRealtime(); 9878 pw.println("Applications Graphics Acceleration Info:"); 9879 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9880 9881 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9882 ProcessRecord r = procs.get(i); 9883 if (r.thread != null) { 9884 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9885 pw.flush(); 9886 try { 9887 TransferPipe tp = new TransferPipe(); 9888 try { 9889 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9890 tp.go(fd); 9891 } finally { 9892 tp.kill(); 9893 } 9894 } catch (IOException e) { 9895 pw.println("Failure while dumping the app: " + r); 9896 pw.flush(); 9897 } catch (RemoteException e) { 9898 pw.println("Got a RemoteException while dumping the app " + r); 9899 pw.flush(); 9900 } 9901 } 9902 } 9903 } 9904 9905 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9906 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9907 if (procs == null) { 9908 return; 9909 } 9910 9911 pw.println("Applications Database Info:"); 9912 9913 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9914 ProcessRecord r = procs.get(i); 9915 if (r.thread != null) { 9916 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 9917 pw.flush(); 9918 try { 9919 TransferPipe tp = new TransferPipe(); 9920 try { 9921 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 9922 tp.go(fd); 9923 } finally { 9924 tp.kill(); 9925 } 9926 } catch (IOException e) { 9927 pw.println("Failure while dumping the app: " + r); 9928 pw.flush(); 9929 } catch (RemoteException e) { 9930 pw.println("Got a RemoteException while dumping the app " + r); 9931 pw.flush(); 9932 } 9933 } 9934 } 9935 } 9936 9937 final static class MemItem { 9938 final String label; 9939 final String shortLabel; 9940 final long pss; 9941 final int id; 9942 ArrayList<MemItem> subitems; 9943 9944 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 9945 label = _label; 9946 shortLabel = _shortLabel; 9947 pss = _pss; 9948 id = _id; 9949 } 9950 } 9951 9952 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 9953 boolean sort) { 9954 if (sort) { 9955 Collections.sort(items, new Comparator<MemItem>() { 9956 @Override 9957 public int compare(MemItem lhs, MemItem rhs) { 9958 if (lhs.pss < rhs.pss) { 9959 return 1; 9960 } else if (lhs.pss > rhs.pss) { 9961 return -1; 9962 } 9963 return 0; 9964 } 9965 }); 9966 } 9967 9968 for (int i=0; i<items.size(); i++) { 9969 MemItem mi = items.get(i); 9970 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 9971 if (mi.subitems != null) { 9972 dumpMemItems(pw, prefix + " ", mi.subitems, true); 9973 } 9974 } 9975 } 9976 9977 // These are in KB. 9978 static final long[] DUMP_MEM_BUCKETS = new long[] { 9979 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 9980 120*1024, 160*1024, 200*1024, 9981 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 9982 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 9983 }; 9984 9985 static final void appendMemBucket(StringBuilder out, long memKB, String label, 9986 boolean stackLike) { 9987 int start = label.lastIndexOf('.'); 9988 if (start >= 0) start++; 9989 else start = 0; 9990 int end = label.length(); 9991 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 9992 if (DUMP_MEM_BUCKETS[i] >= memKB) { 9993 long bucket = DUMP_MEM_BUCKETS[i]/1024; 9994 out.append(bucket); 9995 out.append(stackLike ? "MB." : "MB "); 9996 out.append(label, start, end); 9997 return; 9998 } 9999 } 10000 out.append(memKB/1024); 10001 out.append(stackLike ? "MB." : "MB "); 10002 out.append(label, start, end); 10003 } 10004 10005 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10006 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10007 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10008 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10009 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10010 }; 10011 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10012 "System", "Persistent", "Foreground", 10013 "Visible", "Perceptible", "Heavy Weight", 10014 "Backup", "A Services", "Home", "Previous", 10015 "B Services", "Background" 10016 }; 10017 10018 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10019 PrintWriter pw, String prefix, String[] args, boolean brief, 10020 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10021 boolean dumpAll = false; 10022 boolean oomOnly = false; 10023 10024 int opti = 0; 10025 while (opti < args.length) { 10026 String opt = args[opti]; 10027 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10028 break; 10029 } 10030 opti++; 10031 if ("-a".equals(opt)) { 10032 dumpAll = true; 10033 } else if ("--oom".equals(opt)) { 10034 oomOnly = true; 10035 } else if ("-h".equals(opt)) { 10036 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10037 pw.println(" -a: include all available information for each process."); 10038 pw.println(" --oom: only show processes organized by oom adj."); 10039 pw.println("If [process] is specified it can be the name or "); 10040 pw.println("pid of a specific process to dump."); 10041 return; 10042 } else { 10043 pw.println("Unknown argument: " + opt + "; use -h for help"); 10044 } 10045 } 10046 10047 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10048 if (procs == null) { 10049 return; 10050 } 10051 10052 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10053 long uptime = SystemClock.uptimeMillis(); 10054 long realtime = SystemClock.elapsedRealtime(); 10055 10056 if (procs.size() == 1 || isCheckinRequest) { 10057 dumpAll = true; 10058 } 10059 10060 if (isCheckinRequest) { 10061 // short checkin version 10062 pw.println(uptime + "," + realtime); 10063 pw.flush(); 10064 } else { 10065 pw.println("Applications Memory Usage (kB):"); 10066 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10067 } 10068 10069 String[] innerArgs = new String[args.length-opti]; 10070 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10071 10072 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10073 long nativePss=0, dalvikPss=0, otherPss=0; 10074 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10075 10076 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10077 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10078 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10079 10080 long totalPss = 0; 10081 10082 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10083 ProcessRecord r = procs.get(i); 10084 if (r.thread != null) { 10085 if (!isCheckinRequest && dumpAll) { 10086 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10087 pw.flush(); 10088 } 10089 Debug.MemoryInfo mi = null; 10090 if (dumpAll) { 10091 try { 10092 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10093 } catch (RemoteException e) { 10094 if (!isCheckinRequest) { 10095 pw.println("Got RemoteException!"); 10096 pw.flush(); 10097 } 10098 } 10099 } else { 10100 mi = new Debug.MemoryInfo(); 10101 Debug.getMemoryInfo(r.pid, mi); 10102 } 10103 10104 if (!isCheckinRequest && mi != null) { 10105 long myTotalPss = mi.getTotalPss(); 10106 totalPss += myTotalPss; 10107 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10108 r.processName, myTotalPss, 0); 10109 procMems.add(pssItem); 10110 10111 nativePss += mi.nativePss; 10112 dalvikPss += mi.dalvikPss; 10113 otherPss += mi.otherPss; 10114 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10115 long mem = mi.getOtherPss(j); 10116 miscPss[j] += mem; 10117 otherPss -= mem; 10118 } 10119 10120 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10121 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10122 || oomIndex == (oomPss.length-1)) { 10123 oomPss[oomIndex] += myTotalPss; 10124 if (oomProcs[oomIndex] == null) { 10125 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10126 } 10127 oomProcs[oomIndex].add(pssItem); 10128 break; 10129 } 10130 } 10131 } 10132 } 10133 } 10134 10135 if (!isCheckinRequest && procs.size() > 1) { 10136 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10137 10138 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10139 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10140 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10141 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10142 String label = Debug.MemoryInfo.getOtherLabel(j); 10143 catMems.add(new MemItem(label, label, miscPss[j], j)); 10144 } 10145 10146 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10147 for (int j=0; j<oomPss.length; j++) { 10148 if (oomPss[j] != 0) { 10149 String label = DUMP_MEM_OOM_LABEL[j]; 10150 MemItem item = new MemItem(label, label, oomPss[j], 10151 DUMP_MEM_OOM_ADJ[j]); 10152 item.subitems = oomProcs[j]; 10153 oomMems.add(item); 10154 } 10155 } 10156 10157 if (outTag != null || outStack != null) { 10158 if (outTag != null) { 10159 appendMemBucket(outTag, totalPss, "total", false); 10160 } 10161 if (outStack != null) { 10162 appendMemBucket(outStack, totalPss, "total", true); 10163 } 10164 boolean firstLine = true; 10165 for (int i=0; i<oomMems.size(); i++) { 10166 MemItem miCat = oomMems.get(i); 10167 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10168 continue; 10169 } 10170 if (miCat.id < ProcessList.SERVICE_ADJ 10171 || miCat.id == ProcessList.HOME_APP_ADJ 10172 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10173 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10174 outTag.append(" / "); 10175 } 10176 if (outStack != null) { 10177 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10178 if (firstLine) { 10179 outStack.append(":"); 10180 firstLine = false; 10181 } 10182 outStack.append("\n\t at "); 10183 } else { 10184 outStack.append("$"); 10185 } 10186 } 10187 for (int j=0; j<miCat.subitems.size(); j++) { 10188 MemItem mi = miCat.subitems.get(j); 10189 if (j > 0) { 10190 if (outTag != null) { 10191 outTag.append(" "); 10192 } 10193 if (outStack != null) { 10194 outStack.append("$"); 10195 } 10196 } 10197 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10198 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10199 } 10200 if (outStack != null) { 10201 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10202 } 10203 } 10204 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10205 outStack.append("("); 10206 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10207 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10208 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10209 outStack.append(":"); 10210 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10211 } 10212 } 10213 outStack.append(")"); 10214 } 10215 } 10216 } 10217 } 10218 10219 if (!brief && !oomOnly) { 10220 pw.println(); 10221 pw.println("Total PSS by process:"); 10222 dumpMemItems(pw, " ", procMems, true); 10223 pw.println(); 10224 } 10225 pw.println("Total PSS by OOM adjustment:"); 10226 dumpMemItems(pw, " ", oomMems, false); 10227 if (!oomOnly) { 10228 PrintWriter out = categoryPw != null ? categoryPw : pw; 10229 out.println(); 10230 out.println("Total PSS by category:"); 10231 dumpMemItems(out, " ", catMems, true); 10232 } 10233 pw.println(); 10234 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10235 final int[] SINGLE_LONG_FORMAT = new int[] { 10236 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10237 }; 10238 long[] longOut = new long[1]; 10239 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10240 SINGLE_LONG_FORMAT, null, longOut, null); 10241 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10242 longOut[0] = 0; 10243 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10244 SINGLE_LONG_FORMAT, null, longOut, null); 10245 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10246 longOut[0] = 0; 10247 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10248 SINGLE_LONG_FORMAT, null, longOut, null); 10249 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10250 longOut[0] = 0; 10251 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10252 SINGLE_LONG_FORMAT, null, longOut, null); 10253 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10254 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10255 pw.print(shared); pw.println(" kB"); 10256 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10257 pw.print(voltile); pw.println(" kB volatile"); 10258 } 10259 } 10260 10261 /** 10262 * Searches array of arguments for the specified string 10263 * @param args array of argument strings 10264 * @param value value to search for 10265 * @return true if the value is contained in the array 10266 */ 10267 private static boolean scanArgs(String[] args, String value) { 10268 if (args != null) { 10269 for (String arg : args) { 10270 if (value.equals(arg)) { 10271 return true; 10272 } 10273 } 10274 } 10275 return false; 10276 } 10277 10278 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10279 ContentProviderRecord cpr, boolean always) { 10280 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10281 10282 if (!inLaunching || always) { 10283 synchronized (cpr) { 10284 cpr.launchingApp = null; 10285 cpr.notifyAll(); 10286 } 10287 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10288 String names[] = cpr.info.authority.split(";"); 10289 for (int j = 0; j < names.length; j++) { 10290 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10291 } 10292 } 10293 10294 for (int i=0; i<cpr.connections.size(); i++) { 10295 ContentProviderConnection conn = cpr.connections.get(i); 10296 if (conn.waiting) { 10297 // If this connection is waiting for the provider, then we don't 10298 // need to mess with its process unless we are always removing 10299 // or for some reason the provider is not currently launching. 10300 if (inLaunching && !always) { 10301 continue; 10302 } 10303 } 10304 ProcessRecord capp = conn.client; 10305 conn.dead = true; 10306 if (conn.stableCount > 0) { 10307 if (!capp.persistent && capp.thread != null 10308 && capp.pid != 0 10309 && capp.pid != MY_PID) { 10310 Slog.i(TAG, "Kill " + capp.processName 10311 + " (pid " + capp.pid + "): provider " + cpr.info.name 10312 + " in dying process " + (proc != null ? proc.processName : "??")); 10313 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10314 capp.processName, capp.setAdj, "dying provider " 10315 + cpr.name.toShortString()); 10316 Process.killProcessQuiet(capp.pid); 10317 } 10318 } else if (capp.thread != null && conn.provider.provider != null) { 10319 try { 10320 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10321 } catch (RemoteException e) { 10322 } 10323 // In the protocol here, we don't expect the client to correctly 10324 // clean up this connection, we'll just remove it. 10325 cpr.connections.remove(i); 10326 conn.client.conProviders.remove(conn); 10327 } 10328 } 10329 10330 if (inLaunching && always) { 10331 mLaunchingProviders.remove(cpr); 10332 } 10333 return inLaunching; 10334 } 10335 10336 /** 10337 * Main code for cleaning up a process when it has gone away. This is 10338 * called both as a result of the process dying, or directly when stopping 10339 * a process when running in single process mode. 10340 */ 10341 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10342 boolean restarting, boolean allowRestart, int index) { 10343 if (index >= 0) { 10344 mLruProcesses.remove(index); 10345 } 10346 10347 mProcessesToGc.remove(app); 10348 10349 // Dismiss any open dialogs. 10350 if (app.crashDialog != null) { 10351 app.crashDialog.dismiss(); 10352 app.crashDialog = null; 10353 } 10354 if (app.anrDialog != null) { 10355 app.anrDialog.dismiss(); 10356 app.anrDialog = null; 10357 } 10358 if (app.waitDialog != null) { 10359 app.waitDialog.dismiss(); 10360 app.waitDialog = null; 10361 } 10362 10363 app.crashing = false; 10364 app.notResponding = false; 10365 10366 app.resetPackageList(); 10367 app.unlinkDeathRecipient(); 10368 app.thread = null; 10369 app.forcingToForeground = null; 10370 app.foregroundServices = false; 10371 app.foregroundActivities = false; 10372 app.hasShownUi = false; 10373 app.hasAboveClient = false; 10374 10375 mServices.killServicesLocked(app, allowRestart); 10376 10377 boolean restart = false; 10378 10379 // Remove published content providers. 10380 if (!app.pubProviders.isEmpty()) { 10381 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10382 while (it.hasNext()) { 10383 ContentProviderRecord cpr = it.next(); 10384 10385 final boolean always = app.bad || !allowRestart; 10386 if (removeDyingProviderLocked(app, cpr, always) || always) { 10387 // We left the provider in the launching list, need to 10388 // restart it. 10389 restart = true; 10390 } 10391 10392 cpr.provider = null; 10393 cpr.proc = null; 10394 } 10395 app.pubProviders.clear(); 10396 } 10397 10398 // Take care of any launching providers waiting for this process. 10399 if (checkAppInLaunchingProvidersLocked(app, false)) { 10400 restart = true; 10401 } 10402 10403 // Unregister from connected content providers. 10404 if (!app.conProviders.isEmpty()) { 10405 for (int i=0; i<app.conProviders.size(); i++) { 10406 ContentProviderConnection conn = app.conProviders.get(i); 10407 conn.provider.connections.remove(conn); 10408 } 10409 app.conProviders.clear(); 10410 } 10411 10412 // At this point there may be remaining entries in mLaunchingProviders 10413 // where we were the only one waiting, so they are no longer of use. 10414 // Look for these and clean up if found. 10415 // XXX Commented out for now. Trying to figure out a way to reproduce 10416 // the actual situation to identify what is actually going on. 10417 if (false) { 10418 for (int i=0; i<mLaunchingProviders.size(); i++) { 10419 ContentProviderRecord cpr = (ContentProviderRecord) 10420 mLaunchingProviders.get(i); 10421 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10422 synchronized (cpr) { 10423 cpr.launchingApp = null; 10424 cpr.notifyAll(); 10425 } 10426 } 10427 } 10428 } 10429 10430 skipCurrentReceiverLocked(app); 10431 10432 // Unregister any receivers. 10433 if (app.receivers.size() > 0) { 10434 Iterator<ReceiverList> it = app.receivers.iterator(); 10435 while (it.hasNext()) { 10436 removeReceiverLocked(it.next()); 10437 } 10438 app.receivers.clear(); 10439 } 10440 10441 // If the app is undergoing backup, tell the backup manager about it 10442 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10443 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10444 try { 10445 IBackupManager bm = IBackupManager.Stub.asInterface( 10446 ServiceManager.getService(Context.BACKUP_SERVICE)); 10447 bm.agentDisconnected(app.info.packageName); 10448 } catch (RemoteException e) { 10449 // can't happen; backup manager is local 10450 } 10451 } 10452 10453 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10454 ProcessChangeItem item = mPendingProcessChanges.get(i); 10455 if (item.pid == app.pid) { 10456 mPendingProcessChanges.remove(i); 10457 mAvailProcessChanges.add(item); 10458 } 10459 } 10460 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10461 10462 // If the caller is restarting this app, then leave it in its 10463 // current lists and let the caller take care of it. 10464 if (restarting) { 10465 return; 10466 } 10467 10468 if (!app.persistent || app.isolated) { 10469 if (DEBUG_PROCESSES) Slog.v(TAG, 10470 "Removing non-persistent process during cleanup: " + app); 10471 mProcessNames.remove(app.processName, app.uid); 10472 mIsolatedProcesses.remove(app.uid); 10473 if (mHeavyWeightProcess == app) { 10474 mHeavyWeightProcess = null; 10475 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10476 } 10477 } else if (!app.removed) { 10478 // This app is persistent, so we need to keep its record around. 10479 // If it is not already on the pending app list, add it there 10480 // and start a new process for it. 10481 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10482 mPersistentStartingProcesses.add(app); 10483 restart = true; 10484 } 10485 } 10486 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10487 "Clean-up removing on hold: " + app); 10488 mProcessesOnHold.remove(app); 10489 10490 if (app == mHomeProcess) { 10491 mHomeProcess = null; 10492 } 10493 if (app == mPreviousProcess) { 10494 mPreviousProcess = null; 10495 } 10496 10497 if (restart && !app.isolated) { 10498 // We have components that still need to be running in the 10499 // process, so re-launch it. 10500 mProcessNames.put(app.processName, app.uid, app); 10501 startProcessLocked(app, "restart", app.processName); 10502 } else if (app.pid > 0 && app.pid != MY_PID) { 10503 // Goodbye! 10504 synchronized (mPidsSelfLocked) { 10505 mPidsSelfLocked.remove(app.pid); 10506 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10507 } 10508 app.setPid(0); 10509 } 10510 } 10511 10512 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10513 // Look through the content providers we are waiting to have launched, 10514 // and if any run in this process then either schedule a restart of 10515 // the process or kill the client waiting for it if this process has 10516 // gone bad. 10517 int NL = mLaunchingProviders.size(); 10518 boolean restart = false; 10519 for (int i=0; i<NL; i++) { 10520 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10521 if (cpr.launchingApp == app) { 10522 if (!alwaysBad && !app.bad) { 10523 restart = true; 10524 } else { 10525 removeDyingProviderLocked(app, cpr, true); 10526 NL = mLaunchingProviders.size(); 10527 } 10528 } 10529 } 10530 return restart; 10531 } 10532 10533 // ========================================================= 10534 // SERVICES 10535 // ========================================================= 10536 10537 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10538 int flags) { 10539 enforceNotIsolatedCaller("getServices"); 10540 synchronized (this) { 10541 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10542 } 10543 } 10544 10545 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10546 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10547 synchronized (this) { 10548 return mServices.getRunningServiceControlPanelLocked(name); 10549 } 10550 } 10551 10552 public ComponentName startService(IApplicationThread caller, Intent service, 10553 String resolvedType) { 10554 enforceNotIsolatedCaller("startService"); 10555 // Refuse possible leaked file descriptors 10556 if (service != null && service.hasFileDescriptors() == true) { 10557 throw new IllegalArgumentException("File descriptors passed in Intent"); 10558 } 10559 10560 if (DEBUG_SERVICE) 10561 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10562 synchronized(this) { 10563 final int callingPid = Binder.getCallingPid(); 10564 final int callingUid = Binder.getCallingUid(); 10565 final long origId = Binder.clearCallingIdentity(); 10566 ComponentName res = mServices.startServiceLocked(caller, service, 10567 resolvedType, callingPid, callingUid); 10568 Binder.restoreCallingIdentity(origId); 10569 return res; 10570 } 10571 } 10572 10573 ComponentName startServiceInPackage(int uid, 10574 Intent service, String resolvedType) { 10575 synchronized(this) { 10576 if (DEBUG_SERVICE) 10577 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10578 final long origId = Binder.clearCallingIdentity(); 10579 ComponentName res = mServices.startServiceLocked(null, service, 10580 resolvedType, -1, uid); 10581 Binder.restoreCallingIdentity(origId); 10582 return res; 10583 } 10584 } 10585 10586 public int stopService(IApplicationThread caller, Intent service, 10587 String resolvedType) { 10588 enforceNotIsolatedCaller("stopService"); 10589 // Refuse possible leaked file descriptors 10590 if (service != null && service.hasFileDescriptors() == true) { 10591 throw new IllegalArgumentException("File descriptors passed in Intent"); 10592 } 10593 10594 synchronized(this) { 10595 return mServices.stopServiceLocked(caller, service, resolvedType); 10596 } 10597 } 10598 10599 public IBinder peekService(Intent service, String resolvedType) { 10600 enforceNotIsolatedCaller("peekService"); 10601 // Refuse possible leaked file descriptors 10602 if (service != null && service.hasFileDescriptors() == true) { 10603 throw new IllegalArgumentException("File descriptors passed in Intent"); 10604 } 10605 synchronized(this) { 10606 return mServices.peekServiceLocked(service, resolvedType); 10607 } 10608 } 10609 10610 public boolean stopServiceToken(ComponentName className, IBinder token, 10611 int startId) { 10612 synchronized(this) { 10613 return mServices.stopServiceTokenLocked(className, token, startId); 10614 } 10615 } 10616 10617 public void setServiceForeground(ComponentName className, IBinder token, 10618 int id, Notification notification, boolean removeNotification) { 10619 synchronized(this) { 10620 mServices.setServiceForegroundLocked(className, token, id, notification, 10621 removeNotification); 10622 } 10623 } 10624 10625 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10626 String className, int flags) { 10627 boolean result = false; 10628 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10629 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10630 if (ActivityManager.checkUidPermission( 10631 android.Manifest.permission.INTERACT_ACROSS_USERS, 10632 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10633 ComponentName comp = new ComponentName(aInfo.packageName, className); 10634 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10635 + " requests FLAG_SINGLE_USER, but app does not hold " 10636 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10637 Slog.w(TAG, msg); 10638 throw new SecurityException(msg); 10639 } 10640 result = true; 10641 } 10642 } else if (componentProcessName == aInfo.packageName) { 10643 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10644 } else if ("system".equals(componentProcessName)) { 10645 result = true; 10646 } 10647 if (DEBUG_MU) { 10648 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10649 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10650 } 10651 return result; 10652 } 10653 10654 public int bindService(IApplicationThread caller, IBinder token, 10655 Intent service, String resolvedType, 10656 IServiceConnection connection, int flags, int userId) { 10657 enforceNotIsolatedCaller("bindService"); 10658 // Refuse possible leaked file descriptors 10659 if (service != null && service.hasFileDescriptors() == true) { 10660 throw new IllegalArgumentException("File descriptors passed in Intent"); 10661 } 10662 10663 checkValidCaller(Binder.getCallingUid(), userId); 10664 10665 synchronized(this) { 10666 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10667 connection, flags, userId); 10668 } 10669 } 10670 10671 public boolean unbindService(IServiceConnection connection) { 10672 synchronized (this) { 10673 return mServices.unbindServiceLocked(connection); 10674 } 10675 } 10676 10677 public void publishService(IBinder token, Intent intent, IBinder service) { 10678 // Refuse possible leaked file descriptors 10679 if (intent != null && intent.hasFileDescriptors() == true) { 10680 throw new IllegalArgumentException("File descriptors passed in Intent"); 10681 } 10682 10683 synchronized(this) { 10684 if (!(token instanceof ServiceRecord)) { 10685 throw new IllegalArgumentException("Invalid service token"); 10686 } 10687 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10688 } 10689 } 10690 10691 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10692 // Refuse possible leaked file descriptors 10693 if (intent != null && intent.hasFileDescriptors() == true) { 10694 throw new IllegalArgumentException("File descriptors passed in Intent"); 10695 } 10696 10697 synchronized(this) { 10698 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10699 } 10700 } 10701 10702 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10703 synchronized(this) { 10704 if (!(token instanceof ServiceRecord)) { 10705 throw new IllegalArgumentException("Invalid service token"); 10706 } 10707 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10708 } 10709 } 10710 10711 // ========================================================= 10712 // BACKUP AND RESTORE 10713 // ========================================================= 10714 10715 // Cause the target app to be launched if necessary and its backup agent 10716 // instantiated. The backup agent will invoke backupAgentCreated() on the 10717 // activity manager to announce its creation. 10718 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10719 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10720 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10721 10722 synchronized(this) { 10723 // !!! TODO: currently no check here that we're already bound 10724 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10725 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10726 synchronized (stats) { 10727 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10728 } 10729 10730 // Backup agent is now in use, its package can't be stopped. 10731 try { 10732 AppGlobals.getPackageManager().setPackageStoppedState( 10733 app.packageName, false, UserHandle.getUserId(app.uid)); 10734 } catch (RemoteException e) { 10735 } catch (IllegalArgumentException e) { 10736 Slog.w(TAG, "Failed trying to unstop package " 10737 + app.packageName + ": " + e); 10738 } 10739 10740 BackupRecord r = new BackupRecord(ss, app, backupMode); 10741 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10742 ? new ComponentName(app.packageName, app.backupAgentName) 10743 : new ComponentName("android", "FullBackupAgent"); 10744 // startProcessLocked() returns existing proc's record if it's already running 10745 ProcessRecord proc = startProcessLocked(app.processName, app, 10746 false, 0, "backup", hostingName, false, false); 10747 if (proc == null) { 10748 Slog.e(TAG, "Unable to start backup agent process " + r); 10749 return false; 10750 } 10751 10752 r.app = proc; 10753 mBackupTarget = r; 10754 mBackupAppName = app.packageName; 10755 10756 // Try not to kill the process during backup 10757 updateOomAdjLocked(proc); 10758 10759 // If the process is already attached, schedule the creation of the backup agent now. 10760 // If it is not yet live, this will be done when it attaches to the framework. 10761 if (proc.thread != null) { 10762 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10763 try { 10764 proc.thread.scheduleCreateBackupAgent(app, 10765 compatibilityInfoForPackageLocked(app), backupMode); 10766 } catch (RemoteException e) { 10767 // Will time out on the backup manager side 10768 } 10769 } else { 10770 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10771 } 10772 // Invariants: at this point, the target app process exists and the application 10773 // is either already running or in the process of coming up. mBackupTarget and 10774 // mBackupAppName describe the app, so that when it binds back to the AM we 10775 // know that it's scheduled for a backup-agent operation. 10776 } 10777 10778 return true; 10779 } 10780 10781 // A backup agent has just come up 10782 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10783 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10784 + " = " + agent); 10785 10786 synchronized(this) { 10787 if (!agentPackageName.equals(mBackupAppName)) { 10788 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10789 return; 10790 } 10791 } 10792 10793 long oldIdent = Binder.clearCallingIdentity(); 10794 try { 10795 IBackupManager bm = IBackupManager.Stub.asInterface( 10796 ServiceManager.getService(Context.BACKUP_SERVICE)); 10797 bm.agentConnected(agentPackageName, agent); 10798 } catch (RemoteException e) { 10799 // can't happen; the backup manager service is local 10800 } catch (Exception e) { 10801 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10802 e.printStackTrace(); 10803 } finally { 10804 Binder.restoreCallingIdentity(oldIdent); 10805 } 10806 } 10807 10808 // done with this agent 10809 public void unbindBackupAgent(ApplicationInfo appInfo) { 10810 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10811 if (appInfo == null) { 10812 Slog.w(TAG, "unbind backup agent for null app"); 10813 return; 10814 } 10815 10816 synchronized(this) { 10817 if (mBackupAppName == null) { 10818 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10819 return; 10820 } 10821 10822 if (!mBackupAppName.equals(appInfo.packageName)) { 10823 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10824 return; 10825 } 10826 10827 ProcessRecord proc = mBackupTarget.app; 10828 mBackupTarget = null; 10829 mBackupAppName = null; 10830 10831 // Not backing this app up any more; reset its OOM adjustment 10832 updateOomAdjLocked(proc); 10833 10834 // If the app crashed during backup, 'thread' will be null here 10835 if (proc.thread != null) { 10836 try { 10837 proc.thread.scheduleDestroyBackupAgent(appInfo, 10838 compatibilityInfoForPackageLocked(appInfo)); 10839 } catch (Exception e) { 10840 Slog.e(TAG, "Exception when unbinding backup agent:"); 10841 e.printStackTrace(); 10842 } 10843 } 10844 } 10845 } 10846 // ========================================================= 10847 // BROADCASTS 10848 // ========================================================= 10849 10850 private final List getStickiesLocked(String action, IntentFilter filter, 10851 List cur) { 10852 final ContentResolver resolver = mContext.getContentResolver(); 10853 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10854 if (list == null) { 10855 return cur; 10856 } 10857 int N = list.size(); 10858 for (int i=0; i<N; i++) { 10859 Intent intent = list.get(i); 10860 if (filter.match(resolver, intent, true, TAG) >= 0) { 10861 if (cur == null) { 10862 cur = new ArrayList<Intent>(); 10863 } 10864 cur.add(intent); 10865 } 10866 } 10867 return cur; 10868 } 10869 10870 boolean isPendingBroadcastProcessLocked(int pid) { 10871 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 10872 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 10873 } 10874 10875 void skipPendingBroadcastLocked(int pid) { 10876 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 10877 for (BroadcastQueue queue : mBroadcastQueues) { 10878 queue.skipPendingBroadcastLocked(pid); 10879 } 10880 } 10881 10882 // The app just attached; send any pending broadcasts that it should receive 10883 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 10884 boolean didSomething = false; 10885 for (BroadcastQueue queue : mBroadcastQueues) { 10886 didSomething |= queue.sendPendingBroadcastsLocked(app); 10887 } 10888 return didSomething; 10889 } 10890 10891 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 10892 IIntentReceiver receiver, IntentFilter filter, String permission) { 10893 enforceNotIsolatedCaller("registerReceiver"); 10894 int callingUid; 10895 synchronized(this) { 10896 ProcessRecord callerApp = null; 10897 if (caller != null) { 10898 callerApp = getRecordForAppLocked(caller); 10899 if (callerApp == null) { 10900 throw new SecurityException( 10901 "Unable to find app for caller " + caller 10902 + " (pid=" + Binder.getCallingPid() 10903 + ") when registering receiver " + receiver); 10904 } 10905 if (callerApp.info.uid != Process.SYSTEM_UID && 10906 !callerApp.pkgList.contains(callerPackage)) { 10907 throw new SecurityException("Given caller package " + callerPackage 10908 + " is not running in process " + callerApp); 10909 } 10910 callingUid = callerApp.info.uid; 10911 } else { 10912 callerPackage = null; 10913 callingUid = Binder.getCallingUid(); 10914 } 10915 10916 List allSticky = null; 10917 10918 // Look for any matching sticky broadcasts... 10919 Iterator actions = filter.actionsIterator(); 10920 if (actions != null) { 10921 while (actions.hasNext()) { 10922 String action = (String)actions.next(); 10923 allSticky = getStickiesLocked(action, filter, allSticky); 10924 } 10925 } else { 10926 allSticky = getStickiesLocked(null, filter, allSticky); 10927 } 10928 10929 // The first sticky in the list is returned directly back to 10930 // the client. 10931 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10932 10933 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 10934 + ": " + sticky); 10935 10936 if (receiver == null) { 10937 return sticky; 10938 } 10939 10940 ReceiverList rl 10941 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10942 if (rl == null) { 10943 rl = new ReceiverList(this, callerApp, 10944 Binder.getCallingPid(), 10945 Binder.getCallingUid(), receiver); 10946 if (rl.app != null) { 10947 rl.app.receivers.add(rl); 10948 } else { 10949 try { 10950 receiver.asBinder().linkToDeath(rl, 0); 10951 } catch (RemoteException e) { 10952 return sticky; 10953 } 10954 rl.linkedToDeath = true; 10955 } 10956 mRegisteredReceivers.put(receiver.asBinder(), rl); 10957 } 10958 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 10959 permission, callingUid); 10960 rl.add(bf); 10961 if (!bf.debugCheck()) { 10962 Slog.w(TAG, "==> For Dynamic broadast"); 10963 } 10964 mReceiverResolver.addFilter(bf); 10965 10966 // Enqueue broadcasts for all existing stickies that match 10967 // this filter. 10968 if (allSticky != null) { 10969 ArrayList receivers = new ArrayList(); 10970 receivers.add(bf); 10971 10972 int N = allSticky.size(); 10973 for (int i=0; i<N; i++) { 10974 Intent intent = (Intent)allSticky.get(i); 10975 BroadcastQueue queue = broadcastQueueForIntent(intent); 10976 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 10977 null, -1, -1, null, receivers, null, 0, null, null, 10978 false, true, true, false); 10979 queue.enqueueParallelBroadcastLocked(r); 10980 queue.scheduleBroadcastsLocked(); 10981 } 10982 } 10983 10984 return sticky; 10985 } 10986 } 10987 10988 public void unregisterReceiver(IIntentReceiver receiver) { 10989 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 10990 10991 final long origId = Binder.clearCallingIdentity(); 10992 try { 10993 boolean doTrim = false; 10994 10995 synchronized(this) { 10996 ReceiverList rl 10997 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10998 if (rl != null) { 10999 if (rl.curBroadcast != null) { 11000 BroadcastRecord r = rl.curBroadcast; 11001 final boolean doNext = finishReceiverLocked( 11002 receiver.asBinder(), r.resultCode, r.resultData, 11003 r.resultExtras, r.resultAbort, true); 11004 if (doNext) { 11005 doTrim = true; 11006 r.queue.processNextBroadcast(false); 11007 } 11008 } 11009 11010 if (rl.app != null) { 11011 rl.app.receivers.remove(rl); 11012 } 11013 removeReceiverLocked(rl); 11014 if (rl.linkedToDeath) { 11015 rl.linkedToDeath = false; 11016 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11017 } 11018 } 11019 } 11020 11021 // If we actually concluded any broadcasts, we might now be able 11022 // to trim the recipients' apps from our working set 11023 if (doTrim) { 11024 trimApplications(); 11025 return; 11026 } 11027 11028 } finally { 11029 Binder.restoreCallingIdentity(origId); 11030 } 11031 } 11032 11033 void removeReceiverLocked(ReceiverList rl) { 11034 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11035 int N = rl.size(); 11036 for (int i=0; i<N; i++) { 11037 mReceiverResolver.removeFilter(rl.get(i)); 11038 } 11039 } 11040 11041 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 11042 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11043 ProcessRecord r = mLruProcesses.get(i); 11044 if (r.thread != null) { 11045 try { 11046 r.thread.dispatchPackageBroadcast(cmd, packages); 11047 } catch (RemoteException ex) { 11048 } 11049 } 11050 } 11051 } 11052 11053 private final int broadcastIntentLocked(ProcessRecord callerApp, 11054 String callerPackage, Intent intent, String resolvedType, 11055 IIntentReceiver resultTo, int resultCode, String resultData, 11056 Bundle map, String requiredPermission, 11057 boolean ordered, boolean sticky, int callingPid, int callingUid, 11058 int userId) { 11059 intent = new Intent(intent); 11060 11061 // By default broadcasts do not go to stopped apps. 11062 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11063 11064 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11065 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11066 + " ordered=" + ordered + " userid=" + userId); 11067 if ((resultTo != null) && !ordered) { 11068 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11069 } 11070 11071 boolean onlySendToCaller = false; 11072 11073 // If the caller is trying to send this broadcast to a different 11074 // user, verify that is allowed. 11075 if (UserHandle.getUserId(callingUid) != userId) { 11076 if (checkComponentPermission( 11077 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11078 callingPid, callingUid, -1, true) 11079 != PackageManager.PERMISSION_GRANTED) { 11080 if (checkComponentPermission( 11081 android.Manifest.permission.INTERACT_ACROSS_USERS, 11082 callingPid, callingUid, -1, true) 11083 == PackageManager.PERMISSION_GRANTED) { 11084 onlySendToCaller = true; 11085 } else { 11086 String msg = "Permission Denial: " + intent.getAction() 11087 + " broadcast from " + callerPackage 11088 + " asks to send as user " + userId 11089 + " but is calling from user " + UserHandle.getUserId(callingUid) 11090 + "; this requires " 11091 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11092 Slog.w(TAG, msg); 11093 throw new SecurityException(msg); 11094 } 11095 } 11096 } 11097 11098 // Handle special intents: if this broadcast is from the package 11099 // manager about a package being removed, we need to remove all of 11100 // its activities from the history stack. 11101 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11102 intent.getAction()); 11103 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11104 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11105 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11106 || uidRemoved) { 11107 if (checkComponentPermission( 11108 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11109 callingPid, callingUid, -1, true) 11110 == PackageManager.PERMISSION_GRANTED) { 11111 if (uidRemoved) { 11112 final Bundle intentExtras = intent.getExtras(); 11113 final int uid = intentExtras != null 11114 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11115 if (uid >= 0) { 11116 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11117 synchronized (bs) { 11118 bs.removeUidStatsLocked(uid); 11119 } 11120 } 11121 } else { 11122 // If resources are unvailble just force stop all 11123 // those packages and flush the attribute cache as well. 11124 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11125 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11126 if (list != null && (list.length > 0)) { 11127 for (String pkg : list) { 11128 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11129 } 11130 sendPackageBroadcastLocked( 11131 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 11132 } 11133 } else { 11134 Uri data = intent.getData(); 11135 String ssp; 11136 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11137 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11138 forceStopPackageLocked(ssp, 11139 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11140 false, userId); 11141 } 11142 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11143 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11144 new String[] {ssp}); 11145 } 11146 } 11147 } 11148 } 11149 } else { 11150 String msg = "Permission Denial: " + intent.getAction() 11151 + " broadcast from " + callerPackage + " (pid=" + callingPid 11152 + ", uid=" + callingUid + ")" 11153 + " requires " 11154 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11155 Slog.w(TAG, msg); 11156 throw new SecurityException(msg); 11157 } 11158 11159 // Special case for adding a package: by default turn on compatibility 11160 // mode. 11161 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11162 Uri data = intent.getData(); 11163 String ssp; 11164 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11165 mCompatModePackages.handlePackageAddedLocked(ssp, 11166 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11167 } 11168 } 11169 11170 /* 11171 * If this is the time zone changed action, queue up a message that will reset the timezone 11172 * of all currently running processes. This message will get queued up before the broadcast 11173 * happens. 11174 */ 11175 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11176 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11177 } 11178 11179 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11180 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11181 } 11182 11183 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11184 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11185 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11186 } 11187 11188 /* 11189 * Prevent non-system code (defined here to be non-persistent 11190 * processes) from sending protected broadcasts. 11191 */ 11192 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11193 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11194 callingUid == 0) { 11195 // Always okay. 11196 } else if (callerApp == null || !callerApp.persistent) { 11197 try { 11198 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11199 intent.getAction())) { 11200 String msg = "Permission Denial: not allowed to send broadcast " 11201 + intent.getAction() + " from pid=" 11202 + callingPid + ", uid=" + callingUid; 11203 Slog.w(TAG, msg); 11204 throw new SecurityException(msg); 11205 } 11206 } catch (RemoteException e) { 11207 Slog.w(TAG, "Remote exception", e); 11208 return ActivityManager.BROADCAST_SUCCESS; 11209 } 11210 } 11211 11212 // Add to the sticky list if requested. 11213 if (sticky) { 11214 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11215 callingPid, callingUid) 11216 != PackageManager.PERMISSION_GRANTED) { 11217 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11218 + callingPid + ", uid=" + callingUid 11219 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11220 Slog.w(TAG, msg); 11221 throw new SecurityException(msg); 11222 } 11223 if (requiredPermission != null) { 11224 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11225 + " and enforce permission " + requiredPermission); 11226 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11227 } 11228 if (intent.getComponent() != null) { 11229 throw new SecurityException( 11230 "Sticky broadcasts can't target a specific component"); 11231 } 11232 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11233 if (list == null) { 11234 list = new ArrayList<Intent>(); 11235 mStickyBroadcasts.put(intent.getAction(), list); 11236 } 11237 int N = list.size(); 11238 int i; 11239 for (i=0; i<N; i++) { 11240 if (intent.filterEquals(list.get(i))) { 11241 // This sticky already exists, replace it. 11242 list.set(i, new Intent(intent)); 11243 break; 11244 } 11245 } 11246 if (i >= N) { 11247 list.add(new Intent(intent)); 11248 } 11249 } 11250 11251 // Figure out who all will receive this broadcast. 11252 List receivers = null; 11253 List<BroadcastFilter> registeredReceivers = null; 11254 try { 11255 // Need to resolve the intent to interested receivers... 11256 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11257 == 0) { 11258 receivers = AppGlobals.getPackageManager().queryIntentReceivers( 11259 intent, resolvedType, STOCK_PM_FLAGS, userId); 11260 } 11261 if (intent.getComponent() == null) { 11262 registeredReceivers = mReceiverResolver.queryIntent(intent, 11263 resolvedType, false, userId); 11264 } 11265 } catch (RemoteException ex) { 11266 // pm is in same process, this will never happen. 11267 } 11268 11269 final boolean replacePending = 11270 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11271 11272 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11273 + " replacePending=" + replacePending); 11274 11275 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11276 if (!ordered && NR > 0) { 11277 // If we are not serializing this broadcast, then send the 11278 // registered receivers separately so they don't wait for the 11279 // components to be launched. 11280 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11281 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11282 callerPackage, callingPid, callingUid, requiredPermission, 11283 registeredReceivers, resultTo, resultCode, resultData, map, 11284 ordered, sticky, false, onlySendToCaller); 11285 if (DEBUG_BROADCAST) Slog.v( 11286 TAG, "Enqueueing parallel broadcast " + r); 11287 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11288 if (!replaced) { 11289 queue.enqueueParallelBroadcastLocked(r); 11290 queue.scheduleBroadcastsLocked(); 11291 } 11292 registeredReceivers = null; 11293 NR = 0; 11294 } 11295 11296 // Merge into one list. 11297 int ir = 0; 11298 if (receivers != null) { 11299 // A special case for PACKAGE_ADDED: do not allow the package 11300 // being added to see this broadcast. This prevents them from 11301 // using this as a back door to get run as soon as they are 11302 // installed. Maybe in the future we want to have a special install 11303 // broadcast or such for apps, but we'd like to deliberately make 11304 // this decision. 11305 String skipPackages[] = null; 11306 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11307 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11308 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11309 Uri data = intent.getData(); 11310 if (data != null) { 11311 String pkgName = data.getSchemeSpecificPart(); 11312 if (pkgName != null) { 11313 skipPackages = new String[] { pkgName }; 11314 } 11315 } 11316 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11317 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11318 } 11319 if (skipPackages != null && (skipPackages.length > 0)) { 11320 for (String skipPackage : skipPackages) { 11321 if (skipPackage != null) { 11322 int NT = receivers.size(); 11323 for (int it=0; it<NT; it++) { 11324 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11325 if (curt.activityInfo.packageName.equals(skipPackage)) { 11326 receivers.remove(it); 11327 it--; 11328 NT--; 11329 } 11330 } 11331 } 11332 } 11333 } 11334 11335 int NT = receivers != null ? receivers.size() : 0; 11336 int it = 0; 11337 ResolveInfo curt = null; 11338 BroadcastFilter curr = null; 11339 while (it < NT && ir < NR) { 11340 if (curt == null) { 11341 curt = (ResolveInfo)receivers.get(it); 11342 } 11343 if (curr == null) { 11344 curr = registeredReceivers.get(ir); 11345 } 11346 if (curr.getPriority() >= curt.priority) { 11347 // Insert this broadcast record into the final list. 11348 receivers.add(it, curr); 11349 ir++; 11350 curr = null; 11351 it++; 11352 NT++; 11353 } else { 11354 // Skip to the next ResolveInfo in the final list. 11355 it++; 11356 curt = null; 11357 } 11358 } 11359 } 11360 while (ir < NR) { 11361 if (receivers == null) { 11362 receivers = new ArrayList(); 11363 } 11364 receivers.add(registeredReceivers.get(ir)); 11365 ir++; 11366 } 11367 11368 if ((receivers != null && receivers.size() > 0) 11369 || resultTo != null) { 11370 BroadcastQueue queue = broadcastQueueForIntent(intent); 11371 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11372 callerPackage, callingPid, callingUid, requiredPermission, 11373 receivers, resultTo, resultCode, resultData, map, ordered, 11374 sticky, false, onlySendToCaller); 11375 if (DEBUG_BROADCAST) Slog.v( 11376 TAG, "Enqueueing ordered broadcast " + r 11377 + ": prev had " + queue.mOrderedBroadcasts.size()); 11378 if (DEBUG_BROADCAST) { 11379 int seq = r.intent.getIntExtra("seq", -1); 11380 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11381 } 11382 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11383 if (!replaced) { 11384 queue.enqueueOrderedBroadcastLocked(r); 11385 queue.scheduleBroadcastsLocked(); 11386 } 11387 } 11388 11389 return ActivityManager.BROADCAST_SUCCESS; 11390 } 11391 11392 final Intent verifyBroadcastLocked(Intent intent) { 11393 // Refuse possible leaked file descriptors 11394 if (intent != null && intent.hasFileDescriptors() == true) { 11395 throw new IllegalArgumentException("File descriptors passed in Intent"); 11396 } 11397 11398 int flags = intent.getFlags(); 11399 11400 if (!mProcessesReady) { 11401 // if the caller really truly claims to know what they're doing, go 11402 // ahead and allow the broadcast without launching any receivers 11403 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11404 intent = new Intent(intent); 11405 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11406 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11407 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11408 + " before boot completion"); 11409 throw new IllegalStateException("Cannot broadcast before boot completed"); 11410 } 11411 } 11412 11413 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11414 throw new IllegalArgumentException( 11415 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11416 } 11417 11418 return intent; 11419 } 11420 11421 public final int broadcastIntent(IApplicationThread caller, 11422 Intent intent, String resolvedType, IIntentReceiver resultTo, 11423 int resultCode, String resultData, Bundle map, 11424 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11425 enforceNotIsolatedCaller("broadcastIntent"); 11426 synchronized(this) { 11427 intent = verifyBroadcastLocked(intent); 11428 11429 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11430 final int callingPid = Binder.getCallingPid(); 11431 final int callingUid = Binder.getCallingUid(); 11432 final long origId = Binder.clearCallingIdentity(); 11433 int res = broadcastIntentLocked(callerApp, 11434 callerApp != null ? callerApp.info.packageName : null, 11435 intent, resolvedType, resultTo, 11436 resultCode, resultData, map, requiredPermission, serialized, sticky, 11437 callingPid, callingUid, userId); 11438 Binder.restoreCallingIdentity(origId); 11439 return res; 11440 } 11441 } 11442 11443 int broadcastIntentInPackage(String packageName, int uid, 11444 Intent intent, String resolvedType, IIntentReceiver resultTo, 11445 int resultCode, String resultData, Bundle map, 11446 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11447 synchronized(this) { 11448 intent = verifyBroadcastLocked(intent); 11449 11450 final long origId = Binder.clearCallingIdentity(); 11451 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11452 resultTo, resultCode, resultData, map, requiredPermission, 11453 serialized, sticky, -1, uid, userId); 11454 Binder.restoreCallingIdentity(origId); 11455 return res; 11456 } 11457 } 11458 11459 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 11460 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11461 // Refuse possible leaked file descriptors 11462 if (intent != null && intent.hasFileDescriptors() == true) { 11463 throw new IllegalArgumentException("File descriptors passed in Intent"); 11464 } 11465 11466 synchronized(this) { 11467 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11468 != PackageManager.PERMISSION_GRANTED) { 11469 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11470 + Binder.getCallingPid() 11471 + ", uid=" + Binder.getCallingUid() 11472 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11473 Slog.w(TAG, msg); 11474 throw new SecurityException(msg); 11475 } 11476 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11477 if (list != null) { 11478 int N = list.size(); 11479 int i; 11480 for (i=0; i<N; i++) { 11481 if (intent.filterEquals(list.get(i))) { 11482 list.remove(i); 11483 break; 11484 } 11485 } 11486 } 11487 } 11488 } 11489 11490 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11491 String resultData, Bundle resultExtras, boolean resultAbort, 11492 boolean explicit) { 11493 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11494 if (r == null) { 11495 Slog.w(TAG, "finishReceiver called but not found on queue"); 11496 return false; 11497 } 11498 11499 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11500 explicit); 11501 } 11502 11503 public void finishReceiver(IBinder who, int resultCode, String resultData, 11504 Bundle resultExtras, boolean resultAbort) { 11505 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11506 11507 // Refuse possible leaked file descriptors 11508 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11509 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11510 } 11511 11512 final long origId = Binder.clearCallingIdentity(); 11513 try { 11514 boolean doNext = false; 11515 BroadcastRecord r = null; 11516 11517 synchronized(this) { 11518 r = broadcastRecordForReceiverLocked(who); 11519 if (r != null) { 11520 doNext = r.queue.finishReceiverLocked(r, resultCode, 11521 resultData, resultExtras, resultAbort, true); 11522 } 11523 } 11524 11525 if (doNext) { 11526 r.queue.processNextBroadcast(false); 11527 } 11528 trimApplications(); 11529 } finally { 11530 Binder.restoreCallingIdentity(origId); 11531 } 11532 } 11533 11534 // ========================================================= 11535 // INSTRUMENTATION 11536 // ========================================================= 11537 11538 public boolean startInstrumentation(ComponentName className, 11539 String profileFile, int flags, Bundle arguments, 11540 IInstrumentationWatcher watcher) { 11541 enforceNotIsolatedCaller("startInstrumentation"); 11542 // Refuse possible leaked file descriptors 11543 if (arguments != null && arguments.hasFileDescriptors()) { 11544 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11545 } 11546 11547 synchronized(this) { 11548 InstrumentationInfo ii = null; 11549 ApplicationInfo ai = null; 11550 try { 11551 ii = mContext.getPackageManager().getInstrumentationInfo( 11552 className, STOCK_PM_FLAGS); 11553 ai = mContext.getPackageManager().getApplicationInfo( 11554 ii.targetPackage, STOCK_PM_FLAGS); 11555 } catch (PackageManager.NameNotFoundException e) { 11556 } 11557 if (ii == null) { 11558 reportStartInstrumentationFailure(watcher, className, 11559 "Unable to find instrumentation info for: " + className); 11560 return false; 11561 } 11562 if (ai == null) { 11563 reportStartInstrumentationFailure(watcher, className, 11564 "Unable to find instrumentation target package: " + ii.targetPackage); 11565 return false; 11566 } 11567 11568 int match = mContext.getPackageManager().checkSignatures( 11569 ii.targetPackage, ii.packageName); 11570 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11571 String msg = "Permission Denial: starting instrumentation " 11572 + className + " from pid=" 11573 + Binder.getCallingPid() 11574 + ", uid=" + Binder.getCallingPid() 11575 + " not allowed because package " + ii.packageName 11576 + " does not have a signature matching the target " 11577 + ii.targetPackage; 11578 reportStartInstrumentationFailure(watcher, className, msg); 11579 throw new SecurityException(msg); 11580 } 11581 11582 int userId = UserHandle.getCallingUserId(); 11583 final long origId = Binder.clearCallingIdentity(); 11584 // Instrumentation can kill and relaunch even persistent processes 11585 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11586 ProcessRecord app = addAppLocked(ai, false); 11587 app.instrumentationClass = className; 11588 app.instrumentationInfo = ai; 11589 app.instrumentationProfileFile = profileFile; 11590 app.instrumentationArguments = arguments; 11591 app.instrumentationWatcher = watcher; 11592 app.instrumentationResultClass = className; 11593 Binder.restoreCallingIdentity(origId); 11594 } 11595 11596 return true; 11597 } 11598 11599 /** 11600 * Report errors that occur while attempting to start Instrumentation. Always writes the 11601 * error to the logs, but if somebody is watching, send the report there too. This enables 11602 * the "am" command to report errors with more information. 11603 * 11604 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11605 * @param cn The component name of the instrumentation. 11606 * @param report The error report. 11607 */ 11608 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11609 ComponentName cn, String report) { 11610 Slog.w(TAG, report); 11611 try { 11612 if (watcher != null) { 11613 Bundle results = new Bundle(); 11614 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11615 results.putString("Error", report); 11616 watcher.instrumentationStatus(cn, -1, results); 11617 } 11618 } catch (RemoteException e) { 11619 Slog.w(TAG, e); 11620 } 11621 } 11622 11623 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11624 if (app.instrumentationWatcher != null) { 11625 try { 11626 // NOTE: IInstrumentationWatcher *must* be oneway here 11627 app.instrumentationWatcher.instrumentationFinished( 11628 app.instrumentationClass, 11629 resultCode, 11630 results); 11631 } catch (RemoteException e) { 11632 } 11633 } 11634 app.instrumentationWatcher = null; 11635 app.instrumentationClass = null; 11636 app.instrumentationInfo = null; 11637 app.instrumentationProfileFile = null; 11638 app.instrumentationArguments = null; 11639 11640 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 11641 } 11642 11643 public void finishInstrumentation(IApplicationThread target, 11644 int resultCode, Bundle results) { 11645 int userId = UserHandle.getCallingUserId(); 11646 // Refuse possible leaked file descriptors 11647 if (results != null && results.hasFileDescriptors()) { 11648 throw new IllegalArgumentException("File descriptors passed in Intent"); 11649 } 11650 11651 synchronized(this) { 11652 ProcessRecord app = getRecordForAppLocked(target); 11653 if (app == null) { 11654 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11655 return; 11656 } 11657 final long origId = Binder.clearCallingIdentity(); 11658 finishInstrumentationLocked(app, resultCode, results); 11659 Binder.restoreCallingIdentity(origId); 11660 } 11661 } 11662 11663 // ========================================================= 11664 // CONFIGURATION 11665 // ========================================================= 11666 11667 public ConfigurationInfo getDeviceConfigurationInfo() { 11668 ConfigurationInfo config = new ConfigurationInfo(); 11669 synchronized (this) { 11670 config.reqTouchScreen = mConfiguration.touchscreen; 11671 config.reqKeyboardType = mConfiguration.keyboard; 11672 config.reqNavigation = mConfiguration.navigation; 11673 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11674 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11675 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11676 } 11677 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11678 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11679 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11680 } 11681 config.reqGlEsVersion = GL_ES_VERSION; 11682 } 11683 return config; 11684 } 11685 11686 public Configuration getConfiguration() { 11687 Configuration ci; 11688 synchronized(this) { 11689 ci = new Configuration(mConfiguration); 11690 } 11691 return ci; 11692 } 11693 11694 public void updatePersistentConfiguration(Configuration values) { 11695 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11696 "updateConfiguration()"); 11697 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11698 "updateConfiguration()"); 11699 if (values == null) { 11700 throw new NullPointerException("Configuration must not be null"); 11701 } 11702 11703 synchronized(this) { 11704 final long origId = Binder.clearCallingIdentity(); 11705 updateConfigurationLocked(values, null, true, false); 11706 Binder.restoreCallingIdentity(origId); 11707 } 11708 } 11709 11710 public void updateConfiguration(Configuration values) { 11711 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11712 "updateConfiguration()"); 11713 11714 synchronized(this) { 11715 if (values == null && mWindowManager != null) { 11716 // sentinel: fetch the current configuration from the window manager 11717 values = mWindowManager.computeNewConfiguration(); 11718 } 11719 11720 if (mWindowManager != null) { 11721 mProcessList.applyDisplaySize(mWindowManager); 11722 } 11723 11724 final long origId = Binder.clearCallingIdentity(); 11725 if (values != null) { 11726 Settings.System.clearConfiguration(values); 11727 } 11728 updateConfigurationLocked(values, null, false, false); 11729 Binder.restoreCallingIdentity(origId); 11730 } 11731 } 11732 11733 /** 11734 * Do either or both things: (1) change the current configuration, and (2) 11735 * make sure the given activity is running with the (now) current 11736 * configuration. Returns true if the activity has been left running, or 11737 * false if <var>starting</var> is being destroyed to match the new 11738 * configuration. 11739 * @param persistent TODO 11740 */ 11741 boolean updateConfigurationLocked(Configuration values, 11742 ActivityRecord starting, boolean persistent, boolean initLocale) { 11743 // do nothing if we are headless 11744 if (mHeadless) return true; 11745 11746 int changes = 0; 11747 11748 boolean kept = true; 11749 11750 if (values != null) { 11751 Configuration newConfig = new Configuration(mConfiguration); 11752 changes = newConfig.updateFrom(values); 11753 if (changes != 0) { 11754 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 11755 Slog.i(TAG, "Updating configuration to: " + values); 11756 } 11757 11758 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 11759 11760 if (values.locale != null && !initLocale) { 11761 saveLocaleLocked(values.locale, 11762 !values.locale.equals(mConfiguration.locale), 11763 values.userSetLocale); 11764 } 11765 11766 mConfigurationSeq++; 11767 if (mConfigurationSeq <= 0) { 11768 mConfigurationSeq = 1; 11769 } 11770 newConfig.seq = mConfigurationSeq; 11771 mConfiguration = newConfig; 11772 Slog.i(TAG, "Config changed: " + newConfig); 11773 11774 final Configuration configCopy = new Configuration(mConfiguration); 11775 11776 // TODO: If our config changes, should we auto dismiss any currently 11777 // showing dialogs? 11778 mShowDialogs = shouldShowDialogs(newConfig); 11779 11780 AttributeCache ac = AttributeCache.instance(); 11781 if (ac != null) { 11782 ac.updateConfiguration(configCopy); 11783 } 11784 11785 // Make sure all resources in our process are updated 11786 // right now, so that anyone who is going to retrieve 11787 // resource values after we return will be sure to get 11788 // the new ones. This is especially important during 11789 // boot, where the first config change needs to guarantee 11790 // all resources have that config before following boot 11791 // code is executed. 11792 mSystemThread.applyConfigurationToResources(configCopy); 11793 11794 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 11795 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11796 msg.obj = new Configuration(configCopy); 11797 mHandler.sendMessage(msg); 11798 } 11799 11800 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11801 ProcessRecord app = mLruProcesses.get(i); 11802 try { 11803 if (app.thread != null) { 11804 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 11805 + app.processName + " new config " + mConfiguration); 11806 app.thread.scheduleConfigurationChanged(configCopy); 11807 } 11808 } catch (Exception e) { 11809 } 11810 } 11811 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11812 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11813 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 11814 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11815 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11816 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 11817 broadcastIntentLocked(null, null, 11818 new Intent(Intent.ACTION_LOCALE_CHANGED), 11819 null, null, 0, null, null, 11820 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 11821 } 11822 } 11823 } 11824 11825 if (changes != 0 && starting == null) { 11826 // If the configuration changed, and the caller is not already 11827 // in the process of starting an activity, then find the top 11828 // activity to check if its configuration needs to change. 11829 starting = mMainStack.topRunningActivityLocked(null); 11830 } 11831 11832 if (starting != null) { 11833 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 11834 // And we need to make sure at this point that all other activities 11835 // are made visible with the correct configuration. 11836 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 11837 } 11838 11839 if (values != null && mWindowManager != null) { 11840 mWindowManager.setNewConfiguration(mConfiguration); 11841 } 11842 11843 return kept; 11844 } 11845 11846 /** 11847 * Decide based on the configuration whether we should shouw the ANR, 11848 * crash, etc dialogs. The idea is that if there is no affordnace to 11849 * press the on-screen buttons, we shouldn't show the dialog. 11850 * 11851 * A thought: SystemUI might also want to get told about this, the Power 11852 * dialog / global actions also might want different behaviors. 11853 */ 11854 private static final boolean shouldShowDialogs(Configuration config) { 11855 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 11856 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 11857 } 11858 11859 /** 11860 * Save the locale. You must be inside a synchronized (this) block. 11861 */ 11862 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11863 if(isDiff) { 11864 SystemProperties.set("user.language", l.getLanguage()); 11865 SystemProperties.set("user.region", l.getCountry()); 11866 } 11867 11868 if(isPersist) { 11869 SystemProperties.set("persist.sys.language", l.getLanguage()); 11870 SystemProperties.set("persist.sys.country", l.getCountry()); 11871 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11872 } 11873 } 11874 11875 @Override 11876 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 11877 ActivityRecord srec = ActivityRecord.forToken(token); 11878 return srec != null && srec.task.affinity != null && 11879 srec.task.affinity.equals(destAffinity); 11880 } 11881 11882 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 11883 Intent resultData) { 11884 ComponentName dest = destIntent.getComponent(); 11885 11886 synchronized (this) { 11887 ActivityRecord srec = ActivityRecord.forToken(token); 11888 if (srec == null) { 11889 return false; 11890 } 11891 ArrayList<ActivityRecord> history = srec.stack.mHistory; 11892 final int start = history.indexOf(srec); 11893 if (start < 0) { 11894 // Current activity is not in history stack; do nothing. 11895 return false; 11896 } 11897 int finishTo = start - 1; 11898 ActivityRecord parent = null; 11899 boolean foundParentInTask = false; 11900 if (dest != null) { 11901 TaskRecord tr = srec.task; 11902 for (int i = start - 1; i >= 0; i--) { 11903 ActivityRecord r = history.get(i); 11904 if (tr != r.task) { 11905 // Couldn't find parent in the same task; stop at the one above this. 11906 // (Root of current task; in-app "home" behavior) 11907 // Always at least finish the current activity. 11908 finishTo = Math.min(start - 1, i + 1); 11909 parent = history.get(finishTo); 11910 break; 11911 } else if (r.info.packageName.equals(dest.getPackageName()) && 11912 r.info.name.equals(dest.getClassName())) { 11913 finishTo = i; 11914 parent = r; 11915 foundParentInTask = true; 11916 break; 11917 } 11918 } 11919 } 11920 11921 if (mController != null) { 11922 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 11923 if (next != null) { 11924 // ask watcher if this is allowed 11925 boolean resumeOK = true; 11926 try { 11927 resumeOK = mController.activityResuming(next.packageName); 11928 } catch (RemoteException e) { 11929 mController = null; 11930 } 11931 11932 if (!resumeOK) { 11933 return false; 11934 } 11935 } 11936 } 11937 final long origId = Binder.clearCallingIdentity(); 11938 for (int i = start; i > finishTo; i--) { 11939 ActivityRecord r = history.get(i); 11940 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 11941 "navigate-up"); 11942 // Only return the supplied result for the first activity finished 11943 resultCode = Activity.RESULT_CANCELED; 11944 resultData = null; 11945 } 11946 11947 if (parent != null && foundParentInTask) { 11948 final int parentLaunchMode = parent.info.launchMode; 11949 final int destIntentFlags = destIntent.getFlags(); 11950 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 11951 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 11952 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 11953 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 11954 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 11955 } else { 11956 try { 11957 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 11958 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 11959 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 11960 null, aInfo, parent.appToken, null, 11961 0, -1, parent.launchedFromUid, 0, null, true, null); 11962 foundParentInTask = res == ActivityManager.START_SUCCESS; 11963 } catch (RemoteException e) { 11964 foundParentInTask = false; 11965 } 11966 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 11967 resultData, "navigate-up"); 11968 } 11969 } 11970 Binder.restoreCallingIdentity(origId); 11971 return foundParentInTask; 11972 } 11973 } 11974 11975 public int getLaunchedFromUid(IBinder activityToken) { 11976 ActivityRecord srec = ActivityRecord.forToken(activityToken); 11977 if (srec == null) { 11978 return -1; 11979 } 11980 return srec.launchedFromUid; 11981 } 11982 11983 // ========================================================= 11984 // LIFETIME MANAGEMENT 11985 // ========================================================= 11986 11987 // Returns which broadcast queue the app is the current [or imminent] receiver 11988 // on, or 'null' if the app is not an active broadcast recipient. 11989 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 11990 BroadcastRecord r = app.curReceiver; 11991 if (r != null) { 11992 return r.queue; 11993 } 11994 11995 // It's not the current receiver, but it might be starting up to become one 11996 synchronized (this) { 11997 for (BroadcastQueue queue : mBroadcastQueues) { 11998 r = queue.mPendingBroadcast; 11999 if (r != null && r.curApp == app) { 12000 // found it; report which queue it's in 12001 return queue; 12002 } 12003 } 12004 } 12005 12006 return null; 12007 } 12008 12009 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12010 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12011 if (mAdjSeq == app.adjSeq) { 12012 // This adjustment has already been computed. If we are calling 12013 // from the top, we may have already computed our adjustment with 12014 // an earlier hidden adjustment that isn't really for us... if 12015 // so, use the new hidden adjustment. 12016 if (!recursed && app.hidden) { 12017 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12018 app.hasActivities ? hiddenAdj : emptyAdj; 12019 } 12020 return app.curRawAdj; 12021 } 12022 12023 if (app.thread == null) { 12024 app.adjSeq = mAdjSeq; 12025 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12026 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12027 } 12028 12029 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12030 app.adjSource = null; 12031 app.adjTarget = null; 12032 app.empty = false; 12033 app.hidden = false; 12034 12035 final int activitiesSize = app.activities.size(); 12036 12037 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12038 // The max adjustment doesn't allow this app to be anything 12039 // below foreground, so it is not worth doing work for it. 12040 app.adjType = "fixed"; 12041 app.adjSeq = mAdjSeq; 12042 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12043 app.hasActivities = false; 12044 app.foregroundActivities = false; 12045 app.keeping = true; 12046 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12047 // System process can do UI, and when they do we want to have 12048 // them trim their memory after the user leaves the UI. To 12049 // facilitate this, here we need to determine whether or not it 12050 // is currently showing UI. 12051 app.systemNoUi = true; 12052 if (app == TOP_APP) { 12053 app.systemNoUi = false; 12054 app.hasActivities = true; 12055 } else if (activitiesSize > 0) { 12056 for (int j = 0; j < activitiesSize; j++) { 12057 final ActivityRecord r = app.activities.get(j); 12058 if (r.visible) { 12059 app.systemNoUi = false; 12060 } 12061 if (r.app == app) { 12062 app.hasActivities = true; 12063 } 12064 } 12065 } 12066 return (app.curAdj=app.maxAdj); 12067 } 12068 12069 app.keeping = false; 12070 app.systemNoUi = false; 12071 app.hasActivities = false; 12072 12073 // Determine the importance of the process, starting with most 12074 // important to least, and assign an appropriate OOM adjustment. 12075 int adj; 12076 int schedGroup; 12077 boolean foregroundActivities = false; 12078 boolean interesting = false; 12079 BroadcastQueue queue; 12080 if (app == TOP_APP) { 12081 // The last app on the list is the foreground app. 12082 adj = ProcessList.FOREGROUND_APP_ADJ; 12083 schedGroup = Process.THREAD_GROUP_DEFAULT; 12084 app.adjType = "top-activity"; 12085 foregroundActivities = true; 12086 interesting = true; 12087 app.hasActivities = true; 12088 } else if (app.instrumentationClass != null) { 12089 // Don't want to kill running instrumentation. 12090 adj = ProcessList.FOREGROUND_APP_ADJ; 12091 schedGroup = Process.THREAD_GROUP_DEFAULT; 12092 app.adjType = "instrumentation"; 12093 interesting = true; 12094 } else if ((queue = isReceivingBroadcast(app)) != null) { 12095 // An app that is currently receiving a broadcast also 12096 // counts as being in the foreground for OOM killer purposes. 12097 // It's placed in a sched group based on the nature of the 12098 // broadcast as reflected by which queue it's active in. 12099 adj = ProcessList.FOREGROUND_APP_ADJ; 12100 schedGroup = (queue == mFgBroadcastQueue) 12101 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12102 app.adjType = "broadcast"; 12103 } else if (app.executingServices.size() > 0) { 12104 // An app that is currently executing a service callback also 12105 // counts as being in the foreground. 12106 adj = ProcessList.FOREGROUND_APP_ADJ; 12107 schedGroup = Process.THREAD_GROUP_DEFAULT; 12108 app.adjType = "exec-service"; 12109 } else { 12110 // Assume process is hidden (has activities); we will correct 12111 // later if this is not the case. 12112 adj = hiddenAdj; 12113 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12114 app.hidden = true; 12115 app.adjType = "bg-activities"; 12116 } 12117 12118 boolean hasStoppingActivities = false; 12119 12120 // Examine all activities if not already foreground. 12121 if (!foregroundActivities && activitiesSize > 0) { 12122 for (int j = 0; j < activitiesSize; j++) { 12123 final ActivityRecord r = app.activities.get(j); 12124 if (r.visible) { 12125 // App has a visible activity; only upgrade adjustment. 12126 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12127 adj = ProcessList.VISIBLE_APP_ADJ; 12128 app.adjType = "visible"; 12129 } 12130 schedGroup = Process.THREAD_GROUP_DEFAULT; 12131 app.hidden = false; 12132 app.hasActivities = true; 12133 foregroundActivities = true; 12134 break; 12135 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12136 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12137 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12138 app.adjType = "pausing"; 12139 } 12140 app.hidden = false; 12141 foregroundActivities = true; 12142 } else if (r.state == ActivityState.STOPPING) { 12143 // We will apply the actual adjustment later, because 12144 // we want to allow this process to immediately go through 12145 // any memory trimming that is in effect. 12146 app.hidden = false; 12147 foregroundActivities = true; 12148 hasStoppingActivities = true; 12149 } 12150 if (r.app == app) { 12151 app.hasActivities = true; 12152 } 12153 } 12154 } 12155 12156 if (adj == hiddenAdj && !app.hasActivities) { 12157 // Whoops, this process is completely empty as far as we know 12158 // at this point. 12159 adj = emptyAdj; 12160 app.empty = true; 12161 app.adjType = "bg-empty"; 12162 } 12163 12164 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12165 if (app.foregroundServices) { 12166 // The user is aware of this app, so make it visible. 12167 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12168 app.hidden = false; 12169 app.adjType = "foreground-service"; 12170 schedGroup = Process.THREAD_GROUP_DEFAULT; 12171 } else if (app.forcingToForeground != null) { 12172 // The user is aware of this app, so make it visible. 12173 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12174 app.hidden = false; 12175 app.adjType = "force-foreground"; 12176 app.adjSource = app.forcingToForeground; 12177 schedGroup = Process.THREAD_GROUP_DEFAULT; 12178 } 12179 } 12180 12181 if (app.foregroundServices) { 12182 interesting = true; 12183 } 12184 12185 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12186 // We don't want to kill the current heavy-weight process. 12187 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12188 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12189 app.hidden = false; 12190 app.adjType = "heavy"; 12191 } 12192 12193 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12194 // This process is hosting what we currently consider to be the 12195 // home app, so we don't want to let it go into the background. 12196 adj = ProcessList.HOME_APP_ADJ; 12197 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12198 app.hidden = false; 12199 app.adjType = "home"; 12200 } 12201 12202 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12203 && app.activities.size() > 0) { 12204 // This was the previous process that showed UI to the user. 12205 // We want to try to keep it around more aggressively, to give 12206 // a good experience around switching between two apps. 12207 adj = ProcessList.PREVIOUS_APP_ADJ; 12208 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12209 app.hidden = false; 12210 app.adjType = "previous"; 12211 } 12212 12213 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12214 + " reason=" + app.adjType); 12215 12216 // By default, we use the computed adjustment. It may be changed if 12217 // there are applications dependent on our services or providers, but 12218 // this gives us a baseline and makes sure we don't get into an 12219 // infinite recursion. 12220 app.adjSeq = mAdjSeq; 12221 app.curRawAdj = app.nonStoppingAdj = adj; 12222 12223 if (mBackupTarget != null && app == mBackupTarget.app) { 12224 // If possible we want to avoid killing apps while they're being backed up 12225 if (adj > ProcessList.BACKUP_APP_ADJ) { 12226 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12227 adj = ProcessList.BACKUP_APP_ADJ; 12228 app.adjType = "backup"; 12229 app.hidden = false; 12230 } 12231 } 12232 12233 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12234 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12235 final long now = SystemClock.uptimeMillis(); 12236 // This process is more important if the top activity is 12237 // bound to the service. 12238 Iterator<ServiceRecord> jt = app.services.iterator(); 12239 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12240 ServiceRecord s = jt.next(); 12241 if (s.startRequested) { 12242 if (app.hasShownUi && app != mHomeProcess) { 12243 // If this process has shown some UI, let it immediately 12244 // go to the LRU list because it may be pretty heavy with 12245 // UI stuff. We'll tag it with a label just to help 12246 // debug and understand what is going on. 12247 if (adj > ProcessList.SERVICE_ADJ) { 12248 app.adjType = "started-bg-ui-services"; 12249 } 12250 } else { 12251 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12252 // This service has seen some activity within 12253 // recent memory, so we will keep its process ahead 12254 // of the background processes. 12255 if (adj > ProcessList.SERVICE_ADJ) { 12256 adj = ProcessList.SERVICE_ADJ; 12257 app.adjType = "started-services"; 12258 app.hidden = false; 12259 } 12260 } 12261 // If we have let the service slide into the background 12262 // state, still have some text describing what it is doing 12263 // even though the service no longer has an impact. 12264 if (adj > ProcessList.SERVICE_ADJ) { 12265 app.adjType = "started-bg-services"; 12266 } 12267 } 12268 // Don't kill this process because it is doing work; it 12269 // has said it is doing work. 12270 app.keeping = true; 12271 } 12272 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12273 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12274 Iterator<ArrayList<ConnectionRecord>> kt 12275 = s.connections.values().iterator(); 12276 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12277 ArrayList<ConnectionRecord> clist = kt.next(); 12278 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12279 // XXX should compute this based on the max of 12280 // all connected clients. 12281 ConnectionRecord cr = clist.get(i); 12282 if (cr.binding.client == app) { 12283 // Binding to ourself is not interesting. 12284 continue; 12285 } 12286 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12287 ProcessRecord client = cr.binding.client; 12288 int clientAdj = adj; 12289 int myHiddenAdj = hiddenAdj; 12290 if (myHiddenAdj > client.hiddenAdj) { 12291 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12292 myHiddenAdj = client.hiddenAdj; 12293 } else { 12294 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12295 } 12296 } 12297 int myEmptyAdj = emptyAdj; 12298 if (myEmptyAdj > client.emptyAdj) { 12299 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12300 myEmptyAdj = client.emptyAdj; 12301 } else { 12302 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12303 } 12304 } 12305 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12306 myEmptyAdj, TOP_APP, true, doingAll); 12307 String adjType = null; 12308 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12309 // Not doing bind OOM management, so treat 12310 // this guy more like a started service. 12311 if (app.hasShownUi && app != mHomeProcess) { 12312 // If this process has shown some UI, let it immediately 12313 // go to the LRU list because it may be pretty heavy with 12314 // UI stuff. We'll tag it with a label just to help 12315 // debug and understand what is going on. 12316 if (adj > clientAdj) { 12317 adjType = "bound-bg-ui-services"; 12318 } 12319 app.hidden = false; 12320 clientAdj = adj; 12321 } else { 12322 if (now >= (s.lastActivity 12323 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12324 // This service has not seen activity within 12325 // recent memory, so allow it to drop to the 12326 // LRU list if there is no other reason to keep 12327 // it around. We'll also tag it with a label just 12328 // to help debug and undertand what is going on. 12329 if (adj > clientAdj) { 12330 adjType = "bound-bg-services"; 12331 } 12332 clientAdj = adj; 12333 } 12334 } 12335 } 12336 if (adj > clientAdj) { 12337 // If this process has recently shown UI, and 12338 // the process that is binding to it is less 12339 // important than being visible, then we don't 12340 // care about the binding as much as we care 12341 // about letting this process get into the LRU 12342 // list to be killed and restarted if needed for 12343 // memory. 12344 if (app.hasShownUi && app != mHomeProcess 12345 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12346 adjType = "bound-bg-ui-services"; 12347 } else { 12348 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12349 |Context.BIND_IMPORTANT)) != 0) { 12350 adj = clientAdj; 12351 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12352 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12353 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12354 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12355 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12356 adj = clientAdj; 12357 } else { 12358 app.pendingUiClean = true; 12359 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12360 adj = ProcessList.VISIBLE_APP_ADJ; 12361 } 12362 } 12363 if (!client.hidden) { 12364 app.hidden = false; 12365 } 12366 if (client.keeping) { 12367 app.keeping = true; 12368 } 12369 adjType = "service"; 12370 } 12371 } 12372 if (adjType != null) { 12373 app.adjType = adjType; 12374 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12375 .REASON_SERVICE_IN_USE; 12376 app.adjSource = cr.binding.client; 12377 app.adjSourceOom = clientAdj; 12378 app.adjTarget = s.name; 12379 } 12380 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12381 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12382 schedGroup = Process.THREAD_GROUP_DEFAULT; 12383 } 12384 } 12385 } 12386 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12387 ActivityRecord a = cr.activity; 12388 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12389 (a.visible || a.state == ActivityState.RESUMED 12390 || a.state == ActivityState.PAUSING)) { 12391 adj = ProcessList.FOREGROUND_APP_ADJ; 12392 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12393 schedGroup = Process.THREAD_GROUP_DEFAULT; 12394 } 12395 app.hidden = false; 12396 app.adjType = "service"; 12397 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12398 .REASON_SERVICE_IN_USE; 12399 app.adjSource = a; 12400 app.adjSourceOom = adj; 12401 app.adjTarget = s.name; 12402 } 12403 } 12404 } 12405 } 12406 } 12407 } 12408 12409 // Finally, if this process has active services running in it, we 12410 // would like to avoid killing it unless it would prevent the current 12411 // application from running. By default we put the process in 12412 // with the rest of the background processes; as we scan through 12413 // its services we may bump it up from there. 12414 if (adj > hiddenAdj) { 12415 adj = hiddenAdj; 12416 app.hidden = false; 12417 app.adjType = "bg-services"; 12418 } 12419 } 12420 12421 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12422 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12423 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12424 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12425 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12426 ContentProviderRecord cpr = jt.next(); 12427 for (int i = cpr.connections.size()-1; 12428 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12429 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12430 i--) { 12431 ContentProviderConnection conn = cpr.connections.get(i); 12432 ProcessRecord client = conn.client; 12433 if (client == app) { 12434 // Being our own client is not interesting. 12435 continue; 12436 } 12437 int myHiddenAdj = hiddenAdj; 12438 if (myHiddenAdj > client.hiddenAdj) { 12439 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12440 myHiddenAdj = client.hiddenAdj; 12441 } else { 12442 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12443 } 12444 } 12445 int myEmptyAdj = emptyAdj; 12446 if (myEmptyAdj > client.emptyAdj) { 12447 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12448 myEmptyAdj = client.emptyAdj; 12449 } else { 12450 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12451 } 12452 } 12453 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12454 myEmptyAdj, TOP_APP, true, doingAll); 12455 if (adj > clientAdj) { 12456 if (app.hasShownUi && app != mHomeProcess 12457 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12458 app.adjType = "bg-ui-provider"; 12459 } else { 12460 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12461 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12462 app.adjType = "provider"; 12463 } 12464 if (!client.hidden) { 12465 app.hidden = false; 12466 } 12467 if (client.keeping) { 12468 app.keeping = true; 12469 } 12470 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12471 .REASON_PROVIDER_IN_USE; 12472 app.adjSource = client; 12473 app.adjSourceOom = clientAdj; 12474 app.adjTarget = cpr.name; 12475 } 12476 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12477 schedGroup = Process.THREAD_GROUP_DEFAULT; 12478 } 12479 } 12480 // If the provider has external (non-framework) process 12481 // dependencies, ensure that its adjustment is at least 12482 // FOREGROUND_APP_ADJ. 12483 if (cpr.hasExternalProcessHandles()) { 12484 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12485 adj = ProcessList.FOREGROUND_APP_ADJ; 12486 schedGroup = Process.THREAD_GROUP_DEFAULT; 12487 app.hidden = false; 12488 app.keeping = true; 12489 app.adjType = "provider"; 12490 app.adjTarget = cpr.name; 12491 } 12492 } 12493 } 12494 } 12495 12496 if (adj == ProcessList.SERVICE_ADJ) { 12497 if (doingAll) { 12498 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12499 mNewNumServiceProcs++; 12500 } 12501 if (app.serviceb) { 12502 adj = ProcessList.SERVICE_B_ADJ; 12503 } 12504 } else { 12505 app.serviceb = false; 12506 } 12507 12508 app.nonStoppingAdj = adj; 12509 12510 if (hasStoppingActivities) { 12511 // Only upgrade adjustment. 12512 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12513 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12514 app.adjType = "stopping"; 12515 } 12516 } 12517 12518 app.curRawAdj = adj; 12519 12520 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12521 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12522 if (adj > app.maxAdj) { 12523 adj = app.maxAdj; 12524 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12525 schedGroup = Process.THREAD_GROUP_DEFAULT; 12526 } 12527 } 12528 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12529 app.keeping = true; 12530 } 12531 12532 if (app.hasAboveClient) { 12533 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12534 // then we need to drop its adjustment to be lower than the service's 12535 // in order to honor the request. We want to drop it by one adjustment 12536 // level... but there is special meaning applied to various levels so 12537 // we will skip some of them. 12538 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12539 // System process will not get dropped, ever 12540 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12541 adj = ProcessList.VISIBLE_APP_ADJ; 12542 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12543 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12544 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12545 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12546 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12547 adj++; 12548 } 12549 } 12550 12551 int importance = app.memImportance; 12552 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12553 app.curAdj = adj; 12554 app.curSchedGroup = schedGroup; 12555 if (!interesting) { 12556 // For this reporting, if there is not something explicitly 12557 // interesting in this process then we will push it to the 12558 // background importance. 12559 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12560 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12561 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12562 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12563 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12564 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12565 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12566 } else if (adj >= ProcessList.SERVICE_ADJ) { 12567 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12568 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12569 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12570 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12571 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12572 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12573 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12574 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12575 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12576 } else { 12577 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12578 } 12579 } 12580 12581 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12582 if (foregroundActivities != app.foregroundActivities) { 12583 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12584 } 12585 if (changes != 0) { 12586 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12587 app.memImportance = importance; 12588 app.foregroundActivities = foregroundActivities; 12589 int i = mPendingProcessChanges.size()-1; 12590 ProcessChangeItem item = null; 12591 while (i >= 0) { 12592 item = mPendingProcessChanges.get(i); 12593 if (item.pid == app.pid) { 12594 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12595 break; 12596 } 12597 i--; 12598 } 12599 if (i < 0) { 12600 // No existing item in pending changes; need a new one. 12601 final int NA = mAvailProcessChanges.size(); 12602 if (NA > 0) { 12603 item = mAvailProcessChanges.remove(NA-1); 12604 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12605 } else { 12606 item = new ProcessChangeItem(); 12607 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12608 } 12609 item.changes = 0; 12610 item.pid = app.pid; 12611 item.uid = app.info.uid; 12612 if (mPendingProcessChanges.size() == 0) { 12613 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12614 "*** Enqueueing dispatch processes changed!"); 12615 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12616 } 12617 mPendingProcessChanges.add(item); 12618 } 12619 item.changes |= changes; 12620 item.importance = importance; 12621 item.foregroundActivities = foregroundActivities; 12622 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12623 + Integer.toHexString(System.identityHashCode(item)) 12624 + " " + app.toShortString() + ": changes=" + item.changes 12625 + " importance=" + item.importance 12626 + " foreground=" + item.foregroundActivities 12627 + " type=" + app.adjType + " source=" + app.adjSource 12628 + " target=" + app.adjTarget); 12629 } 12630 12631 return app.curRawAdj; 12632 } 12633 12634 /** 12635 * Ask a given process to GC right now. 12636 */ 12637 final void performAppGcLocked(ProcessRecord app) { 12638 try { 12639 app.lastRequestedGc = SystemClock.uptimeMillis(); 12640 if (app.thread != null) { 12641 if (app.reportLowMemory) { 12642 app.reportLowMemory = false; 12643 app.thread.scheduleLowMemory(); 12644 } else { 12645 app.thread.processInBackground(); 12646 } 12647 } 12648 } catch (Exception e) { 12649 // whatever. 12650 } 12651 } 12652 12653 /** 12654 * Returns true if things are idle enough to perform GCs. 12655 */ 12656 private final boolean canGcNowLocked() { 12657 boolean processingBroadcasts = false; 12658 for (BroadcastQueue q : mBroadcastQueues) { 12659 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12660 processingBroadcasts = true; 12661 } 12662 } 12663 return !processingBroadcasts 12664 && (mSleeping || (mMainStack.mResumedActivity != null && 12665 mMainStack.mResumedActivity.idle)); 12666 } 12667 12668 /** 12669 * Perform GCs on all processes that are waiting for it, but only 12670 * if things are idle. 12671 */ 12672 final void performAppGcsLocked() { 12673 final int N = mProcessesToGc.size(); 12674 if (N <= 0) { 12675 return; 12676 } 12677 if (canGcNowLocked()) { 12678 while (mProcessesToGc.size() > 0) { 12679 ProcessRecord proc = mProcessesToGc.remove(0); 12680 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12681 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12682 <= SystemClock.uptimeMillis()) { 12683 // To avoid spamming the system, we will GC processes one 12684 // at a time, waiting a few seconds between each. 12685 performAppGcLocked(proc); 12686 scheduleAppGcsLocked(); 12687 return; 12688 } else { 12689 // It hasn't been long enough since we last GCed this 12690 // process... put it in the list to wait for its time. 12691 addProcessToGcListLocked(proc); 12692 break; 12693 } 12694 } 12695 } 12696 12697 scheduleAppGcsLocked(); 12698 } 12699 } 12700 12701 /** 12702 * If all looks good, perform GCs on all processes waiting for them. 12703 */ 12704 final void performAppGcsIfAppropriateLocked() { 12705 if (canGcNowLocked()) { 12706 performAppGcsLocked(); 12707 return; 12708 } 12709 // Still not idle, wait some more. 12710 scheduleAppGcsLocked(); 12711 } 12712 12713 /** 12714 * Schedule the execution of all pending app GCs. 12715 */ 12716 final void scheduleAppGcsLocked() { 12717 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12718 12719 if (mProcessesToGc.size() > 0) { 12720 // Schedule a GC for the time to the next process. 12721 ProcessRecord proc = mProcessesToGc.get(0); 12722 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12723 12724 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12725 long now = SystemClock.uptimeMillis(); 12726 if (when < (now+GC_TIMEOUT)) { 12727 when = now + GC_TIMEOUT; 12728 } 12729 mHandler.sendMessageAtTime(msg, when); 12730 } 12731 } 12732 12733 /** 12734 * Add a process to the array of processes waiting to be GCed. Keeps the 12735 * list in sorted order by the last GC time. The process can't already be 12736 * on the list. 12737 */ 12738 final void addProcessToGcListLocked(ProcessRecord proc) { 12739 boolean added = false; 12740 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 12741 if (mProcessesToGc.get(i).lastRequestedGc < 12742 proc.lastRequestedGc) { 12743 added = true; 12744 mProcessesToGc.add(i+1, proc); 12745 break; 12746 } 12747 } 12748 if (!added) { 12749 mProcessesToGc.add(0, proc); 12750 } 12751 } 12752 12753 /** 12754 * Set up to ask a process to GC itself. This will either do it 12755 * immediately, or put it on the list of processes to gc the next 12756 * time things are idle. 12757 */ 12758 final void scheduleAppGcLocked(ProcessRecord app) { 12759 long now = SystemClock.uptimeMillis(); 12760 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 12761 return; 12762 } 12763 if (!mProcessesToGc.contains(app)) { 12764 addProcessToGcListLocked(app); 12765 scheduleAppGcsLocked(); 12766 } 12767 } 12768 12769 final void checkExcessivePowerUsageLocked(boolean doKills) { 12770 updateCpuStatsNow(); 12771 12772 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12773 boolean doWakeKills = doKills; 12774 boolean doCpuKills = doKills; 12775 if (mLastPowerCheckRealtime == 0) { 12776 doWakeKills = false; 12777 } 12778 if (mLastPowerCheckUptime == 0) { 12779 doCpuKills = false; 12780 } 12781 if (stats.isScreenOn()) { 12782 doWakeKills = false; 12783 } 12784 final long curRealtime = SystemClock.elapsedRealtime(); 12785 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 12786 final long curUptime = SystemClock.uptimeMillis(); 12787 final long uptimeSince = curUptime - mLastPowerCheckUptime; 12788 mLastPowerCheckRealtime = curRealtime; 12789 mLastPowerCheckUptime = curUptime; 12790 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 12791 doWakeKills = false; 12792 } 12793 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 12794 doCpuKills = false; 12795 } 12796 int i = mLruProcesses.size(); 12797 while (i > 0) { 12798 i--; 12799 ProcessRecord app = mLruProcesses.get(i); 12800 if (!app.keeping) { 12801 long wtime; 12802 synchronized (stats) { 12803 wtime = stats.getProcessWakeTime(app.info.uid, 12804 app.pid, curRealtime); 12805 } 12806 long wtimeUsed = wtime - app.lastWakeTime; 12807 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 12808 if (DEBUG_POWER) { 12809 StringBuilder sb = new StringBuilder(128); 12810 sb.append("Wake for "); 12811 app.toShortString(sb); 12812 sb.append(": over "); 12813 TimeUtils.formatDuration(realtimeSince, sb); 12814 sb.append(" used "); 12815 TimeUtils.formatDuration(wtimeUsed, sb); 12816 sb.append(" ("); 12817 sb.append((wtimeUsed*100)/realtimeSince); 12818 sb.append("%)"); 12819 Slog.i(TAG, sb.toString()); 12820 sb.setLength(0); 12821 sb.append("CPU for "); 12822 app.toShortString(sb); 12823 sb.append(": over "); 12824 TimeUtils.formatDuration(uptimeSince, sb); 12825 sb.append(" used "); 12826 TimeUtils.formatDuration(cputimeUsed, sb); 12827 sb.append(" ("); 12828 sb.append((cputimeUsed*100)/uptimeSince); 12829 sb.append("%)"); 12830 Slog.i(TAG, sb.toString()); 12831 } 12832 // If a process has held a wake lock for more 12833 // than 50% of the time during this period, 12834 // that sounds bad. Kill! 12835 if (doWakeKills && realtimeSince > 0 12836 && ((wtimeUsed*100)/realtimeSince) >= 50) { 12837 synchronized (stats) { 12838 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 12839 realtimeSince, wtimeUsed); 12840 } 12841 Slog.w(TAG, "Excessive wake lock in " + app.processName 12842 + " (pid " + app.pid + "): held " + wtimeUsed 12843 + " during " + realtimeSince); 12844 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12845 app.processName, app.setAdj, "excessive wake lock"); 12846 Process.killProcessQuiet(app.pid); 12847 } else if (doCpuKills && uptimeSince > 0 12848 && ((cputimeUsed*100)/uptimeSince) >= 50) { 12849 synchronized (stats) { 12850 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 12851 uptimeSince, cputimeUsed); 12852 } 12853 Slog.w(TAG, "Excessive CPU in " + app.processName 12854 + " (pid " + app.pid + "): used " + cputimeUsed 12855 + " during " + uptimeSince); 12856 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12857 app.processName, app.setAdj, "excessive cpu"); 12858 Process.killProcessQuiet(app.pid); 12859 } else { 12860 app.lastWakeTime = wtime; 12861 app.lastCpuTime = app.curCpuTime; 12862 } 12863 } 12864 } 12865 } 12866 12867 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 12868 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 12869 app.hiddenAdj = hiddenAdj; 12870 app.emptyAdj = emptyAdj; 12871 12872 if (app.thread == null) { 12873 return false; 12874 } 12875 12876 final boolean wasKeeping = app.keeping; 12877 12878 boolean success = true; 12879 12880 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 12881 12882 if (app.curRawAdj != app.setRawAdj) { 12883 if (wasKeeping && !app.keeping) { 12884 // This app is no longer something we want to keep. Note 12885 // its current wake lock time to later know to kill it if 12886 // it is not behaving well. 12887 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12888 synchronized (stats) { 12889 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 12890 app.pid, SystemClock.elapsedRealtime()); 12891 } 12892 app.lastCpuTime = app.curCpuTime; 12893 } 12894 12895 app.setRawAdj = app.curRawAdj; 12896 } 12897 12898 if (app.curAdj != app.setAdj) { 12899 if (Process.setOomAdj(app.pid, app.curAdj)) { 12900 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 12901 TAG, "Set " + app.pid + " " + app.processName + 12902 " adj " + app.curAdj + ": " + app.adjType); 12903 app.setAdj = app.curAdj; 12904 } else { 12905 success = false; 12906 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 12907 } 12908 } 12909 if (app.setSchedGroup != app.curSchedGroup) { 12910 app.setSchedGroup = app.curSchedGroup; 12911 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 12912 "Setting process group of " + app.processName 12913 + " to " + app.curSchedGroup); 12914 if (app.waitingToKill != null && 12915 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 12916 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 12917 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 12918 app.processName, app.setAdj, app.waitingToKill); 12919 app.killedBackground = true; 12920 Process.killProcessQuiet(app.pid); 12921 success = false; 12922 } else { 12923 if (true) { 12924 long oldId = Binder.clearCallingIdentity(); 12925 try { 12926 Process.setProcessGroup(app.pid, app.curSchedGroup); 12927 } catch (Exception e) { 12928 Slog.w(TAG, "Failed setting process group of " + app.pid 12929 + " to " + app.curSchedGroup); 12930 e.printStackTrace(); 12931 } finally { 12932 Binder.restoreCallingIdentity(oldId); 12933 } 12934 } else { 12935 if (app.thread != null) { 12936 try { 12937 app.thread.setSchedulingGroup(app.curSchedGroup); 12938 } catch (RemoteException e) { 12939 } 12940 } 12941 } 12942 } 12943 } 12944 return success; 12945 } 12946 12947 private final ActivityRecord resumedAppLocked() { 12948 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 12949 if (resumedActivity == null || resumedActivity.app == null) { 12950 resumedActivity = mMainStack.mPausingActivity; 12951 if (resumedActivity == null || resumedActivity.app == null) { 12952 resumedActivity = mMainStack.topRunningActivityLocked(null); 12953 } 12954 } 12955 return resumedActivity; 12956 } 12957 12958 final boolean updateOomAdjLocked(ProcessRecord app) { 12959 final ActivityRecord TOP_ACT = resumedAppLocked(); 12960 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12961 int curAdj = app.curAdj; 12962 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12963 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12964 12965 mAdjSeq++; 12966 12967 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 12968 TOP_APP, false); 12969 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 12970 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 12971 if (nowHidden != wasHidden) { 12972 // Changed to/from hidden state, so apps after it in the LRU 12973 // list may also be changed. 12974 updateOomAdjLocked(); 12975 } 12976 return success; 12977 } 12978 12979 final void updateOomAdjLocked() { 12980 final ActivityRecord TOP_ACT = resumedAppLocked(); 12981 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12982 12983 if (false) { 12984 RuntimeException e = new RuntimeException(); 12985 e.fillInStackTrace(); 12986 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12987 } 12988 12989 mAdjSeq++; 12990 mNewNumServiceProcs = 0; 12991 12992 // Let's determine how many processes we have running vs. 12993 // how many slots we have for background processes; we may want 12994 // to put multiple processes in a slot of there are enough of 12995 // them. 12996 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 12997 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 12998 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 12999 if (emptyFactor < 1) emptyFactor = 1; 13000 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13001 if (hiddenFactor < 1) hiddenFactor = 1; 13002 int stepHidden = 0; 13003 int stepEmpty = 0; 13004 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13005 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13006 int numHidden = 0; 13007 int numEmpty = 0; 13008 int numTrimming = 0; 13009 13010 mNumNonHiddenProcs = 0; 13011 mNumHiddenProcs = 0; 13012 13013 // First update the OOM adjustment for each of the 13014 // application processes based on their current state. 13015 int i = mLruProcesses.size(); 13016 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13017 int nextHiddenAdj = curHiddenAdj+1; 13018 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13019 int nextEmptyAdj = curEmptyAdj+2; 13020 while (i > 0) { 13021 i--; 13022 ProcessRecord app = mLruProcesses.get(i); 13023 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13024 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13025 if (!app.killedBackground) { 13026 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13027 // This process was assigned as a hidden process... step the 13028 // hidden level. 13029 mNumHiddenProcs++; 13030 if (curHiddenAdj != nextHiddenAdj) { 13031 stepHidden++; 13032 if (stepHidden >= hiddenFactor) { 13033 stepHidden = 0; 13034 curHiddenAdj = nextHiddenAdj; 13035 nextHiddenAdj += 2; 13036 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13037 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13038 } 13039 } 13040 } 13041 numHidden++; 13042 if (numHidden > hiddenProcessLimit) { 13043 Slog.i(TAG, "No longer want " + app.processName 13044 + " (pid " + app.pid + "): hidden #" + numHidden); 13045 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13046 app.processName, app.setAdj, "too many background"); 13047 app.killedBackground = true; 13048 Process.killProcessQuiet(app.pid); 13049 } 13050 } else { 13051 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13052 // This process was assigned as an empty process... step the 13053 // empty level. 13054 if (curEmptyAdj != nextEmptyAdj) { 13055 stepEmpty++; 13056 if (stepEmpty >= emptyFactor) { 13057 stepEmpty = 0; 13058 curEmptyAdj = nextEmptyAdj; 13059 nextEmptyAdj += 2; 13060 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13061 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13062 } 13063 } 13064 } 13065 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13066 mNumNonHiddenProcs++; 13067 } 13068 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13069 numEmpty++; 13070 if (numEmpty > emptyProcessLimit) { 13071 Slog.i(TAG, "No longer want " + app.processName 13072 + " (pid " + app.pid + "): empty #" + numEmpty); 13073 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13074 app.processName, app.setAdj, "too many background"); 13075 app.killedBackground = true; 13076 Process.killProcessQuiet(app.pid); 13077 } 13078 } 13079 } 13080 if (app.isolated && app.services.size() <= 0) { 13081 // If this is an isolated process, and there are no 13082 // services running in it, then the process is no longer 13083 // needed. We agressively kill these because we can by 13084 // definition not re-use the same process again, and it is 13085 // good to avoid having whatever code was running in them 13086 // left sitting around after no longer needed. 13087 Slog.i(TAG, "Isolated process " + app.processName 13088 + " (pid " + app.pid + ") no longer needed"); 13089 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13090 app.processName, app.setAdj, "isolated not needed"); 13091 app.killedBackground = true; 13092 Process.killProcessQuiet(app.pid); 13093 } 13094 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13095 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13096 && !app.killedBackground) { 13097 numTrimming++; 13098 } 13099 } 13100 } 13101 13102 mNumServiceProcs = mNewNumServiceProcs; 13103 13104 // Now determine the memory trimming level of background processes. 13105 // Unfortunately we need to start at the back of the list to do this 13106 // properly. We only do this if the number of background apps we 13107 // are managing to keep around is less than half the maximum we desire; 13108 // if we are keeping a good number around, we'll let them use whatever 13109 // memory they want. 13110 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13111 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13112 final int numHiddenAndEmpty = numHidden + numEmpty; 13113 final int N = mLruProcesses.size(); 13114 int factor = numTrimming/3; 13115 int minFactor = 2; 13116 if (mHomeProcess != null) minFactor++; 13117 if (mPreviousProcess != null) minFactor++; 13118 if (factor < minFactor) factor = minFactor; 13119 int step = 0; 13120 int fgTrimLevel; 13121 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13122 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13123 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13124 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13125 } else { 13126 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13127 } 13128 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13129 for (i=0; i<N; i++) { 13130 ProcessRecord app = mLruProcesses.get(i); 13131 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13132 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13133 && !app.killedBackground) { 13134 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13135 try { 13136 app.thread.scheduleTrimMemory(curLevel); 13137 } catch (RemoteException e) { 13138 } 13139 if (false) { 13140 // For now we won't do this; our memory trimming seems 13141 // to be good enough at this point that destroying 13142 // activities causes more harm than good. 13143 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13144 && app != mHomeProcess && app != mPreviousProcess) { 13145 // Need to do this on its own message because the stack may not 13146 // be in a consistent state at this point. 13147 // For these apps we will also finish their activities 13148 // to help them free memory. 13149 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13150 } 13151 } 13152 } 13153 app.trimMemoryLevel = curLevel; 13154 step++; 13155 if (step >= factor) { 13156 step = 0; 13157 switch (curLevel) { 13158 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13159 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13160 break; 13161 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13162 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13163 break; 13164 } 13165 } 13166 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13167 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13168 && app.thread != null) { 13169 try { 13170 app.thread.scheduleTrimMemory( 13171 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13172 } catch (RemoteException e) { 13173 } 13174 } 13175 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13176 } else { 13177 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13178 && app.pendingUiClean) { 13179 // If this application is now in the background and it 13180 // had done UI, then give it the special trim level to 13181 // have it free UI resources. 13182 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13183 if (app.trimMemoryLevel < level && app.thread != null) { 13184 try { 13185 app.thread.scheduleTrimMemory(level); 13186 } catch (RemoteException e) { 13187 } 13188 } 13189 app.pendingUiClean = false; 13190 } 13191 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13192 try { 13193 app.thread.scheduleTrimMemory(fgTrimLevel); 13194 } catch (RemoteException e) { 13195 } 13196 } 13197 app.trimMemoryLevel = fgTrimLevel; 13198 } 13199 } 13200 } else { 13201 final int N = mLruProcesses.size(); 13202 for (i=0; i<N; i++) { 13203 ProcessRecord app = mLruProcesses.get(i); 13204 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13205 && app.pendingUiClean) { 13206 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13207 && app.thread != null) { 13208 try { 13209 app.thread.scheduleTrimMemory( 13210 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13211 } catch (RemoteException e) { 13212 } 13213 } 13214 app.pendingUiClean = false; 13215 } 13216 app.trimMemoryLevel = 0; 13217 } 13218 } 13219 13220 if (mAlwaysFinishActivities) { 13221 // Need to do this on its own message because the stack may not 13222 // be in a consistent state at this point. 13223 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13224 } 13225 } 13226 13227 final void trimApplications() { 13228 synchronized (this) { 13229 int i; 13230 13231 // First remove any unused application processes whose package 13232 // has been removed. 13233 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13234 final ProcessRecord app = mRemovedProcesses.get(i); 13235 if (app.activities.size() == 0 13236 && app.curReceiver == null && app.services.size() == 0) { 13237 Slog.i( 13238 TAG, "Exiting empty application process " 13239 + app.processName + " (" 13240 + (app.thread != null ? app.thread.asBinder() : null) 13241 + ")\n"); 13242 if (app.pid > 0 && app.pid != MY_PID) { 13243 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13244 app.processName, app.setAdj, "empty"); 13245 Process.killProcessQuiet(app.pid); 13246 } else { 13247 try { 13248 app.thread.scheduleExit(); 13249 } catch (Exception e) { 13250 // Ignore exceptions. 13251 } 13252 } 13253 cleanUpApplicationRecordLocked(app, false, true, -1); 13254 mRemovedProcesses.remove(i); 13255 13256 if (app.persistent) { 13257 if (app.persistent) { 13258 addAppLocked(app.info, false); 13259 } 13260 } 13261 } 13262 } 13263 13264 // Now update the oom adj for all processes. 13265 updateOomAdjLocked(); 13266 } 13267 } 13268 13269 /** This method sends the specified signal to each of the persistent apps */ 13270 public void signalPersistentProcesses(int sig) throws RemoteException { 13271 if (sig != Process.SIGNAL_USR1) { 13272 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13273 } 13274 13275 synchronized (this) { 13276 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13277 != PackageManager.PERMISSION_GRANTED) { 13278 throw new SecurityException("Requires permission " 13279 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13280 } 13281 13282 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13283 ProcessRecord r = mLruProcesses.get(i); 13284 if (r.thread != null && r.persistent) { 13285 Process.sendSignal(r.pid, sig); 13286 } 13287 } 13288 } 13289 } 13290 13291 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13292 if (proc == null || proc == mProfileProc) { 13293 proc = mProfileProc; 13294 path = mProfileFile; 13295 profileType = mProfileType; 13296 clearProfilerLocked(); 13297 } 13298 if (proc == null) { 13299 return; 13300 } 13301 try { 13302 proc.thread.profilerControl(false, path, null, profileType); 13303 } catch (RemoteException e) { 13304 throw new IllegalStateException("Process disappeared"); 13305 } 13306 } 13307 13308 private void clearProfilerLocked() { 13309 if (mProfileFd != null) { 13310 try { 13311 mProfileFd.close(); 13312 } catch (IOException e) { 13313 } 13314 } 13315 mProfileApp = null; 13316 mProfileProc = null; 13317 mProfileFile = null; 13318 mProfileType = 0; 13319 mAutoStopProfiler = false; 13320 } 13321 13322 public boolean profileControl(String process, boolean start, 13323 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13324 13325 try { 13326 synchronized (this) { 13327 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13328 // its own permission. 13329 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13330 != PackageManager.PERMISSION_GRANTED) { 13331 throw new SecurityException("Requires permission " 13332 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13333 } 13334 13335 if (start && fd == null) { 13336 throw new IllegalArgumentException("null fd"); 13337 } 13338 13339 ProcessRecord proc = null; 13340 if (process != null) { 13341 try { 13342 int pid = Integer.parseInt(process); 13343 synchronized (mPidsSelfLocked) { 13344 proc = mPidsSelfLocked.get(pid); 13345 } 13346 } catch (NumberFormatException e) { 13347 } 13348 13349 if (proc == null) { 13350 HashMap<String, SparseArray<ProcessRecord>> all 13351 = mProcessNames.getMap(); 13352 SparseArray<ProcessRecord> procs = all.get(process); 13353 if (procs != null && procs.size() > 0) { 13354 proc = procs.valueAt(0); 13355 } 13356 } 13357 } 13358 13359 if (start && (proc == null || proc.thread == null)) { 13360 throw new IllegalArgumentException("Unknown process: " + process); 13361 } 13362 13363 if (start) { 13364 stopProfilerLocked(null, null, 0); 13365 setProfileApp(proc.info, proc.processName, path, fd, false); 13366 mProfileProc = proc; 13367 mProfileType = profileType; 13368 try { 13369 fd = fd.dup(); 13370 } catch (IOException e) { 13371 fd = null; 13372 } 13373 proc.thread.profilerControl(start, path, fd, profileType); 13374 fd = null; 13375 mProfileFd = null; 13376 } else { 13377 stopProfilerLocked(proc, path, profileType); 13378 if (fd != null) { 13379 try { 13380 fd.close(); 13381 } catch (IOException e) { 13382 } 13383 } 13384 } 13385 13386 return true; 13387 } 13388 } catch (RemoteException e) { 13389 throw new IllegalStateException("Process disappeared"); 13390 } finally { 13391 if (fd != null) { 13392 try { 13393 fd.close(); 13394 } catch (IOException e) { 13395 } 13396 } 13397 } 13398 } 13399 13400 public boolean dumpHeap(String process, boolean managed, 13401 String path, ParcelFileDescriptor fd) throws RemoteException { 13402 13403 try { 13404 synchronized (this) { 13405 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13406 // its own permission (same as profileControl). 13407 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13408 != PackageManager.PERMISSION_GRANTED) { 13409 throw new SecurityException("Requires permission " 13410 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13411 } 13412 13413 if (fd == null) { 13414 throw new IllegalArgumentException("null fd"); 13415 } 13416 13417 ProcessRecord proc = null; 13418 try { 13419 int pid = Integer.parseInt(process); 13420 synchronized (mPidsSelfLocked) { 13421 proc = mPidsSelfLocked.get(pid); 13422 } 13423 } catch (NumberFormatException e) { 13424 } 13425 13426 if (proc == null) { 13427 HashMap<String, SparseArray<ProcessRecord>> all 13428 = mProcessNames.getMap(); 13429 SparseArray<ProcessRecord> procs = all.get(process); 13430 if (procs != null && procs.size() > 0) { 13431 proc = procs.valueAt(0); 13432 } 13433 } 13434 13435 if (proc == null || proc.thread == null) { 13436 throw new IllegalArgumentException("Unknown process: " + process); 13437 } 13438 13439 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13440 if (!isDebuggable) { 13441 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13442 throw new SecurityException("Process not debuggable: " + proc); 13443 } 13444 } 13445 13446 proc.thread.dumpHeap(managed, path, fd); 13447 fd = null; 13448 return true; 13449 } 13450 } catch (RemoteException e) { 13451 throw new IllegalStateException("Process disappeared"); 13452 } finally { 13453 if (fd != null) { 13454 try { 13455 fd.close(); 13456 } catch (IOException e) { 13457 } 13458 } 13459 } 13460 } 13461 13462 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13463 public void monitor() { 13464 synchronized (this) { } 13465 } 13466 13467 void onCoreSettingsChange(Bundle settings) { 13468 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13469 ProcessRecord processRecord = mLruProcesses.get(i); 13470 try { 13471 if (processRecord.thread != null) { 13472 processRecord.thread.setCoreSettings(settings); 13473 } 13474 } catch (RemoteException re) { 13475 /* ignore */ 13476 } 13477 } 13478 } 13479 13480 // Multi-user methods 13481 13482 public boolean switchUser(int userId) { 13483 final int callingUid = Binder.getCallingUid(); 13484 if (callingUid != 0 && callingUid != Process.myUid()) { 13485 Slog.e(TAG, "Trying to switch user from unauthorized app"); 13486 return false; 13487 } 13488 if (mCurrentUserId == userId) 13489 return true; 13490 13491 synchronized (this) { 13492 // Check if user is already logged in, otherwise check if user exists first before 13493 // adding to the list of logged in users. 13494 if (mLoggedInUsers.indexOfKey(userId) < 0) { 13495 if (!userExists(userId)) { 13496 return false; 13497 } 13498 mLoggedInUsers.append(userId, userId); 13499 } 13500 13501 mCurrentUserId = userId; 13502 boolean haveActivities = mMainStack.switchUser(userId); 13503 if (!haveActivities) { 13504 startHomeActivityLocked(userId); 13505 } 13506 13507 } 13508 13509 // Inform of user switch 13510 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13511 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13512 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS); 13513 13514 return true; 13515 } 13516 13517 @Override 13518 public UserInfo getCurrentUser() throws RemoteException { 13519 final int callingUid = Binder.getCallingUid(); 13520 if (callingUid != 0 && callingUid != Process.myUid()) { 13521 Slog.e(TAG, "Trying to get user from unauthorized app"); 13522 return null; 13523 } 13524 return getUserManager().getUserInfo(mCurrentUserId); 13525 } 13526 13527 private void onUserRemoved(Intent intent) { 13528 int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 13529 if (extraUserId < 1) return; 13530 13531 // Kill all the processes for the user 13532 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 13533 synchronized (this) { 13534 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 13535 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 13536 SparseArray<ProcessRecord> uids = uidMap.getValue(); 13537 for (int i = 0; i < uids.size(); i++) { 13538 if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) { 13539 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 13540 } 13541 } 13542 } 13543 13544 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 13545 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 13546 false, false, true, true, extraUserId); 13547 } 13548 } 13549 } 13550 13551 private boolean userExists(int userId) { 13552 UserInfo user = getUserManager().getUserInfo(userId); 13553 return user != null; 13554 } 13555 13556 UserManager getUserManager() { 13557 if (mUserManager == null) { 13558 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13559 } 13560 return mUserManager; 13561 } 13562 13563 private void checkValidCaller(int uid, int userId) { 13564 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13565 13566 throw new SecurityException("Caller uid=" + uid 13567 + " is not privileged to communicate with user=" + userId); 13568 } 13569 13570 private int applyUserId(int uid, int userId) { 13571 return UserHandle.getUid(userId, uid); 13572 } 13573 13574 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13575 if (info == null) return null; 13576 ApplicationInfo newInfo = new ApplicationInfo(info); 13577 newInfo.uid = applyUserId(info.uid, userId); 13578 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13579 + info.packageName; 13580 return newInfo; 13581 } 13582 13583 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13584 if (aInfo == null 13585 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13586 return aInfo; 13587 } 13588 13589 ActivityInfo info = new ActivityInfo(aInfo); 13590 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13591 return info; 13592 } 13593} 13594