ActivityManagerService.java revision ce09f5a53c8408d995c116a4430c000574d9875a
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.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.UserManagerService; 85import com.android.server.wm.AppTransition; 86import com.android.server.wm.WindowManagerService; 87import com.google.android.collect.Lists; 88import com.google.android.collect.Maps; 89 90import libcore.io.IoUtils; 91 92import org.xmlpull.v1.XmlPullParser; 93import org.xmlpull.v1.XmlPullParserException; 94import org.xmlpull.v1.XmlSerializer; 95 96import android.app.Activity; 97import android.app.ActivityManager; 98import android.app.ActivityManager.RunningTaskInfo; 99import android.app.ActivityManager.StackInfo; 100import android.app.ActivityManagerInternal; 101import android.app.ActivityManagerNative; 102import android.app.ActivityOptions; 103import android.app.ActivityThread; 104import android.app.AlertDialog; 105import android.app.AppGlobals; 106import android.app.ApplicationErrorReport; 107import android.app.Dialog; 108import android.app.IActivityController; 109import android.app.IApplicationThread; 110import android.app.IInstrumentationWatcher; 111import android.app.INotificationManager; 112import android.app.IProcessObserver; 113import android.app.IServiceConnection; 114import android.app.IStopUserCallback; 115import android.app.IUiAutomationConnection; 116import android.app.IUserSwitchObserver; 117import android.app.Instrumentation; 118import android.app.Notification; 119import android.app.NotificationManager; 120import android.app.PendingIntent; 121import android.app.backup.IBackupManager; 122import android.content.ActivityNotFoundException; 123import android.content.BroadcastReceiver; 124import android.content.ClipData; 125import android.content.ComponentCallbacks2; 126import android.content.ComponentName; 127import android.content.ContentProvider; 128import android.content.ContentResolver; 129import android.content.Context; 130import android.content.DialogInterface; 131import android.content.IContentProvider; 132import android.content.IIntentReceiver; 133import android.content.IIntentSender; 134import android.content.Intent; 135import android.content.IntentFilter; 136import android.content.IntentSender; 137import android.content.pm.ActivityInfo; 138import android.content.pm.ApplicationInfo; 139import android.content.pm.ConfigurationInfo; 140import android.content.pm.IPackageDataObserver; 141import android.content.pm.IPackageManager; 142import android.content.pm.InstrumentationInfo; 143import android.content.pm.PackageInfo; 144import android.content.pm.PackageManager; 145import android.content.pm.ParceledListSlice; 146import android.content.pm.UserInfo; 147import android.content.pm.PackageManager.NameNotFoundException; 148import android.content.pm.PathPermission; 149import android.content.pm.ProviderInfo; 150import android.content.pm.ResolveInfo; 151import android.content.pm.ServiceInfo; 152import android.content.res.CompatibilityInfo; 153import android.content.res.Configuration; 154import android.net.Proxy; 155import android.net.ProxyInfo; 156import android.net.Uri; 157import android.os.Binder; 158import android.os.Build; 159import android.os.Bundle; 160import android.os.Debug; 161import android.os.DropBoxManager; 162import android.os.Environment; 163import android.os.FactoryTest; 164import android.os.FileObserver; 165import android.os.FileUtils; 166import android.os.Handler; 167import android.os.IBinder; 168import android.os.IPermissionController; 169import android.os.IRemoteCallback; 170import android.os.IUserManager; 171import android.os.Looper; 172import android.os.Message; 173import android.os.Parcel; 174import android.os.ParcelFileDescriptor; 175import android.os.Process; 176import android.os.RemoteCallbackList; 177import android.os.RemoteException; 178import android.os.SELinux; 179import android.os.ServiceManager; 180import android.os.StrictMode; 181import android.os.SystemClock; 182import android.os.SystemProperties; 183import android.os.UpdateLock; 184import android.os.UserHandle; 185import android.os.UserManager; 186import android.provider.Settings; 187import android.text.format.DateUtils; 188import android.text.format.Time; 189import android.util.AtomicFile; 190import android.util.EventLog; 191import android.util.Log; 192import android.util.Pair; 193import android.util.PrintWriterPrinter; 194import android.util.Slog; 195import android.util.SparseArray; 196import android.util.TimeUtils; 197import android.util.Xml; 198import android.view.Gravity; 199import android.view.LayoutInflater; 200import android.view.View; 201import android.view.WindowManager; 202import dalvik.system.VMRuntime; 203 204import java.io.BufferedInputStream; 205import java.io.BufferedOutputStream; 206import java.io.DataInputStream; 207import java.io.DataOutputStream; 208import java.io.File; 209import java.io.FileDescriptor; 210import java.io.FileInputStream; 211import java.io.FileNotFoundException; 212import java.io.FileOutputStream; 213import java.io.IOException; 214import java.io.InputStreamReader; 215import java.io.PrintWriter; 216import java.io.StringWriter; 217import java.lang.ref.WeakReference; 218import java.util.ArrayList; 219import java.util.Arrays; 220import java.util.Collections; 221import java.util.Comparator; 222import java.util.HashMap; 223import java.util.HashSet; 224import java.util.Iterator; 225import java.util.List; 226import java.util.Locale; 227import java.util.Map; 228import java.util.Set; 229import java.util.concurrent.atomic.AtomicBoolean; 230import java.util.concurrent.atomic.AtomicLong; 231 232public final class ActivityManagerService extends ActivityManagerNative 233 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 234 235 private static final String USER_DATA_DIR = "/data/user/"; 236 // File that stores last updated system version and called preboot receivers 237 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 238 239 static final String TAG = "ActivityManager"; 240 static final String TAG_MU = "ActivityManagerServiceMU"; 241 static final boolean DEBUG = false; 242 static final boolean localLOGV = DEBUG; 243 static final boolean DEBUG_BACKUP = localLOGV || false; 244 static final boolean DEBUG_BROADCAST = localLOGV || false; 245 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 246 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_CLEANUP = localLOGV || false; 248 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 249 static final boolean DEBUG_FOCUS = false; 250 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 251 static final boolean DEBUG_MU = localLOGV || false; 252 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 253 static final boolean DEBUG_LRU = localLOGV || false; 254 static final boolean DEBUG_PAUSE = localLOGV || false; 255 static final boolean DEBUG_POWER = localLOGV || false; 256 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 257 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 258 static final boolean DEBUG_PROCESSES = localLOGV || false; 259 static final boolean DEBUG_PROVIDER = localLOGV || false; 260 static final boolean DEBUG_RESULTS = localLOGV || false; 261 static final boolean DEBUG_SERVICE = localLOGV || false; 262 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 263 static final boolean DEBUG_STACK = localLOGV || false; 264 static final boolean DEBUG_SWITCH = localLOGV || false; 265 static final boolean DEBUG_TASKS = localLOGV || false; 266 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 267 static final boolean DEBUG_TRANSITION = localLOGV || false; 268 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 269 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 270 static final boolean DEBUG_VISBILITY = localLOGV || false; 271 static final boolean DEBUG_PSS = localLOGV || false; 272 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 273 static final boolean DEBUG_RECENTS = localLOGV || false; 274 static final boolean VALIDATE_TOKENS = false; 275 static final boolean SHOW_ACTIVITY_START_TIME = true; 276 277 // Control over CPU and battery monitoring. 278 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 279 static final boolean MONITOR_CPU_USAGE = true; 280 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 281 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 282 static final boolean MONITOR_THREAD_CPU_USAGE = false; 283 284 // The flags that are set for all calls we make to the package manager. 285 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 286 287 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 288 289 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 290 291 // Maximum number recent bitmaps to keep in memory. 292 static final int MAX_RECENT_BITMAPS = 5; 293 294 // Amount of time after a call to stopAppSwitches() during which we will 295 // prevent further untrusted switches from happening. 296 static final long APP_SWITCH_DELAY_TIME = 5*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real. 300 static final int PROC_START_TIMEOUT = 10*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real, when the process was 304 // started with a wrapper for instrumentation (such as Valgrind) because it 305 // could take much longer than usual. 306 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 307 308 // How long to wait after going idle before forcing apps to GC. 309 static final int GC_TIMEOUT = 5*1000; 310 311 // The minimum amount of time between successive GC requests for a process. 312 static final int GC_MIN_INTERVAL = 60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process. 315 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process 318 // when the request is due to the memory state being lowered. 319 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 320 321 // The rate at which we check for apps using excessive power -- 15 mins. 322 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on wake locks to start killing things. 326 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on CPU usage to start killing things. 330 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // How long we allow a receiver to run before giving up on it. 333 static final int BROADCAST_FG_TIMEOUT = 10*1000; 334 static final int BROADCAST_BG_TIMEOUT = 60*1000; 335 336 // How long we wait until we timeout on key dispatching. 337 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 338 339 // How long we wait until we timeout on key dispatching during instrumentation. 340 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 341 342 // Amount of time we wait for observers to handle a user switch before 343 // giving up on them and unfreezing the screen. 344 static final int USER_SWITCH_TIMEOUT = 2*1000; 345 346 // Maximum number of users we allow to be running at a time. 347 static final int MAX_RUNNING_USERS = 3; 348 349 // How long to wait in getAssistContextExtras for the activity and foreground services 350 // to respond with the result. 351 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 352 353 // Maximum number of persisted Uri grants a package is allowed 354 static final int MAX_PERSISTED_URI_GRANTS = 128; 355 356 static final int MY_PID = Process.myPid(); 357 358 static final String[] EMPTY_STRING_ARRAY = new String[0]; 359 360 // How many bytes to write into the dropbox log before truncating 361 static final int DROPBOX_MAX_SIZE = 256 * 1024; 362 363 // Access modes for handleIncomingUser. 364 static final int ALLOW_NON_FULL = 0; 365 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 366 static final int ALLOW_FULL_ONLY = 2; 367 368 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 369 370 /** All system services */ 371 SystemServiceManager mSystemServiceManager; 372 373 /** Run all ActivityStacks through this */ 374 ActivityStackSupervisor mStackSupervisor; 375 376 public IntentFirewall mIntentFirewall; 377 378 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 379 // default actuion automatically. Important for devices without direct input 380 // devices. 381 private boolean mShowDialogs = true; 382 383 BroadcastQueue mFgBroadcastQueue; 384 BroadcastQueue mBgBroadcastQueue; 385 // Convenient for easy iteration over the queues. Foreground is first 386 // so that dispatch of foreground broadcasts gets precedence. 387 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 388 389 BroadcastQueue broadcastQueueForIntent(Intent intent) { 390 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 391 if (DEBUG_BACKGROUND_BROADCAST) { 392 Slog.i(TAG, "Broadcast intent " + intent + " on " 393 + (isFg ? "foreground" : "background") 394 + " queue"); 395 } 396 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 397 } 398 399 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 400 for (BroadcastQueue queue : mBroadcastQueues) { 401 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 402 if (r != null) { 403 return r; 404 } 405 } 406 return null; 407 } 408 409 /** 410 * Activity we have told the window manager to have key focus. 411 */ 412 ActivityRecord mFocusedActivity = null; 413 414 /** 415 * List of intents that were used to start the most recent tasks. 416 */ 417 ArrayList<TaskRecord> mRecentTasks; 418 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 419 420 /** 421 * For addAppTask: cached of the last activity component that was added. 422 */ 423 ComponentName mLastAddedTaskComponent; 424 425 /** 426 * For addAppTask: cached of the last activity uid that was added. 427 */ 428 int mLastAddedTaskUid; 429 430 /** 431 * For addAppTask: cached of the last ActivityInfo that was added. 432 */ 433 ActivityInfo mLastAddedTaskActivity; 434 435 public class PendingAssistExtras extends Binder implements Runnable { 436 public final ActivityRecord activity; 437 public final Bundle extras; 438 public final Intent intent; 439 public final String hint; 440 public final int userHandle; 441 public boolean haveResult = false; 442 public Bundle result = null; 443 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 444 String _hint, int _userHandle) { 445 activity = _activity; 446 extras = _extras; 447 intent = _intent; 448 hint = _hint; 449 userHandle = _userHandle; 450 } 451 @Override 452 public void run() { 453 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 454 synchronized (this) { 455 haveResult = true; 456 notifyAll(); 457 } 458 } 459 } 460 461 final ArrayList<PendingAssistExtras> mPendingAssistExtras 462 = new ArrayList<PendingAssistExtras>(); 463 464 /** 465 * Process management. 466 */ 467 final ProcessList mProcessList = new ProcessList(); 468 469 /** 470 * All of the applications we currently have running organized by name. 471 * The keys are strings of the application package name (as 472 * returned by the package manager), and the keys are ApplicationRecord 473 * objects. 474 */ 475 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 476 477 /** 478 * Tracking long-term execution of processes to look for abuse and other 479 * bad app behavior. 480 */ 481 final ProcessStatsService mProcessStats; 482 483 /** 484 * The currently running isolated processes. 485 */ 486 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 487 488 /** 489 * Counter for assigning isolated process uids, to avoid frequently reusing the 490 * same ones. 491 */ 492 int mNextIsolatedProcessUid = 0; 493 494 /** 495 * The currently running heavy-weight process, if any. 496 */ 497 ProcessRecord mHeavyWeightProcess = null; 498 499 /** 500 * The last time that various processes have crashed. 501 */ 502 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 503 504 /** 505 * Information about a process that is currently marked as bad. 506 */ 507 static final class BadProcessInfo { 508 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 509 this.time = time; 510 this.shortMsg = shortMsg; 511 this.longMsg = longMsg; 512 this.stack = stack; 513 } 514 515 final long time; 516 final String shortMsg; 517 final String longMsg; 518 final String stack; 519 } 520 521 /** 522 * Set of applications that we consider to be bad, and will reject 523 * incoming broadcasts from (which the user has no control over). 524 * Processes are added to this set when they have crashed twice within 525 * a minimum amount of time; they are removed from it when they are 526 * later restarted (hopefully due to some user action). The value is the 527 * time it was added to the list. 528 */ 529 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 530 531 /** 532 * All of the processes we currently have running organized by pid. 533 * The keys are the pid running the application. 534 * 535 * <p>NOTE: This object is protected by its own lock, NOT the global 536 * activity manager lock! 537 */ 538 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 539 540 /** 541 * All of the processes that have been forced to be foreground. The key 542 * is the pid of the caller who requested it (we hold a death 543 * link on it). 544 */ 545 abstract class ForegroundToken implements IBinder.DeathRecipient { 546 int pid; 547 IBinder token; 548 } 549 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 550 551 /** 552 * List of records for processes that someone had tried to start before the 553 * system was ready. We don't start them at that point, but ensure they 554 * are started by the time booting is complete. 555 */ 556 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of persistent applications that are in the process 560 * of being started. 561 */ 562 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Processes that are being forcibly torn down. 566 */ 567 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * List of running applications, sorted by recent usage. 571 * The first entry in the list is the least recently used. 572 */ 573 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * Where in mLruProcesses that the processes hosting activities start. 577 */ 578 int mLruProcessActivityStart = 0; 579 580 /** 581 * Where in mLruProcesses that the processes hosting services start. 582 * This is after (lower index) than mLruProcessesActivityStart. 583 */ 584 int mLruProcessServiceStart = 0; 585 586 /** 587 * List of processes that should gc as soon as things are idle. 588 */ 589 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 590 591 /** 592 * Processes we want to collect PSS data from. 593 */ 594 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Last time we requested PSS data of all processes. 598 */ 599 long mLastFullPssTime = SystemClock.uptimeMillis(); 600 601 /** 602 * If set, the next time we collect PSS data we should do a full collection 603 * with data from native processes and the kernel. 604 */ 605 boolean mFullPssPending = false; 606 607 /** 608 * This is the process holding what we currently consider to be 609 * the "home" activity. 610 */ 611 ProcessRecord mHomeProcess; 612 613 /** 614 * This is the process holding the activity the user last visited that 615 * is in a different process from the one they are currently in. 616 */ 617 ProcessRecord mPreviousProcess; 618 619 /** 620 * The time at which the previous process was last visible. 621 */ 622 long mPreviousProcessVisibleTime; 623 624 /** 625 * Which uses have been started, so are allowed to run code. 626 */ 627 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 628 629 /** 630 * LRU list of history of current users. Most recently current is at the end. 631 */ 632 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 633 634 /** 635 * Constant array of the users that are currently started. 636 */ 637 int[] mStartedUserArray = new int[] { 0 }; 638 639 /** 640 * Registered observers of the user switching mechanics. 641 */ 642 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 643 = new RemoteCallbackList<IUserSwitchObserver>(); 644 645 /** 646 * Currently active user switch. 647 */ 648 Object mCurUserSwitchCallback; 649 650 /** 651 * Packages that the user has asked to have run in screen size 652 * compatibility mode instead of filling the screen. 653 */ 654 final CompatModePackages mCompatModePackages; 655 656 /** 657 * Set of IntentSenderRecord objects that are currently active. 658 */ 659 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 660 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 661 662 /** 663 * Fingerprints (hashCode()) of stack traces that we've 664 * already logged DropBox entries for. Guarded by itself. If 665 * something (rogue user app) forces this over 666 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 667 */ 668 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 669 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 670 671 /** 672 * Strict Mode background batched logging state. 673 * 674 * The string buffer is guarded by itself, and its lock is also 675 * used to determine if another batched write is already 676 * in-flight. 677 */ 678 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 679 680 /** 681 * Keeps track of all IIntentReceivers that have been registered for 682 * broadcasts. Hash keys are the receiver IBinder, hash value is 683 * a ReceiverList. 684 */ 685 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 686 new HashMap<IBinder, ReceiverList>(); 687 688 /** 689 * Resolver for broadcast intents to registered receivers. 690 * Holds BroadcastFilter (subclass of IntentFilter). 691 */ 692 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 693 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 694 @Override 695 protected boolean allowFilterResult( 696 BroadcastFilter filter, List<BroadcastFilter> dest) { 697 IBinder target = filter.receiverList.receiver.asBinder(); 698 for (int i=dest.size()-1; i>=0; i--) { 699 if (dest.get(i).receiverList.receiver.asBinder() == target) { 700 return false; 701 } 702 } 703 return true; 704 } 705 706 @Override 707 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 708 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 709 || userId == filter.owningUserId) { 710 return super.newResult(filter, match, userId); 711 } 712 return null; 713 } 714 715 @Override 716 protected BroadcastFilter[] newArray(int size) { 717 return new BroadcastFilter[size]; 718 } 719 720 @Override 721 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 722 return packageName.equals(filter.packageName); 723 } 724 }; 725 726 /** 727 * State of all active sticky broadcasts per user. Keys are the action of the 728 * sticky Intent, values are an ArrayList of all broadcasted intents with 729 * that action (which should usually be one). The SparseArray is keyed 730 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 731 * for stickies that are sent to all users. 732 */ 733 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 734 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 735 736 final ActiveServices mServices; 737 738 /** 739 * Backup/restore process management 740 */ 741 String mBackupAppName = null; 742 BackupRecord mBackupTarget = null; 743 744 final ProviderMap mProviderMap; 745 746 /** 747 * List of content providers who have clients waiting for them. The 748 * application is currently being launched and the provider will be 749 * removed from this list once it is published. 750 */ 751 final ArrayList<ContentProviderRecord> mLaunchingProviders 752 = new ArrayList<ContentProviderRecord>(); 753 754 /** 755 * File storing persisted {@link #mGrantedUriPermissions}. 756 */ 757 private final AtomicFile mGrantFile; 758 759 /** XML constants used in {@link #mGrantFile} */ 760 private static final String TAG_URI_GRANTS = "uri-grants"; 761 private static final String TAG_URI_GRANT = "uri-grant"; 762 private static final String ATTR_USER_HANDLE = "userHandle"; 763 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 764 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 765 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 766 private static final String ATTR_TARGET_PKG = "targetPkg"; 767 private static final String ATTR_URI = "uri"; 768 private static final String ATTR_MODE_FLAGS = "modeFlags"; 769 private static final String ATTR_CREATED_TIME = "createdTime"; 770 private static final String ATTR_PREFIX = "prefix"; 771 772 /** 773 * Global set of specific {@link Uri} permissions that have been granted. 774 * This optimized lookup structure maps from {@link UriPermission#targetUid} 775 * to {@link UriPermission#uri} to {@link UriPermission}. 776 */ 777 @GuardedBy("this") 778 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 779 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 780 781 public static class GrantUri { 782 public final int sourceUserId; 783 public final Uri uri; 784 public boolean prefix; 785 786 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 787 this.sourceUserId = sourceUserId; 788 this.uri = uri; 789 this.prefix = prefix; 790 } 791 792 @Override 793 public int hashCode() { 794 return toString().hashCode(); 795 } 796 797 @Override 798 public boolean equals(Object o) { 799 if (o instanceof GrantUri) { 800 GrantUri other = (GrantUri) o; 801 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 802 && prefix == other.prefix; 803 } 804 return false; 805 } 806 807 @Override 808 public String toString() { 809 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 810 if (prefix) result += " [prefix]"; 811 return result; 812 } 813 814 public String toSafeString() { 815 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 816 if (prefix) result += " [prefix]"; 817 return result; 818 } 819 820 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 821 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 822 ContentProvider.getUriWithoutUserId(uri), false); 823 } 824 } 825 826 CoreSettingsObserver mCoreSettingsObserver; 827 828 /** 829 * Thread-local storage used to carry caller permissions over through 830 * indirect content-provider access. 831 */ 832 private class Identity { 833 public int pid; 834 public int uid; 835 836 Identity(int _pid, int _uid) { 837 pid = _pid; 838 uid = _uid; 839 } 840 } 841 842 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 843 844 /** 845 * All information we have collected about the runtime performance of 846 * any user id that can impact battery performance. 847 */ 848 final BatteryStatsService mBatteryStatsService; 849 850 /** 851 * Information about component usage 852 */ 853 UsageStatsManagerInternal mUsageStatsService; 854 855 /** 856 * Information about and control over application operations 857 */ 858 final AppOpsService mAppOpsService; 859 860 /** 861 * Save recent tasks information across reboots. 862 */ 863 final TaskPersister mTaskPersister; 864 865 /** 866 * Current configuration information. HistoryRecord objects are given 867 * a reference to this object to indicate which configuration they are 868 * currently running in, so this object must be kept immutable. 869 */ 870 Configuration mConfiguration = new Configuration(); 871 872 /** 873 * Current sequencing integer of the configuration, for skipping old 874 * configurations. 875 */ 876 int mConfigurationSeq = 0; 877 878 /** 879 * Hardware-reported OpenGLES version. 880 */ 881 final int GL_ES_VERSION; 882 883 /** 884 * List of initialization arguments to pass to all processes when binding applications to them. 885 * For example, references to the commonly used services. 886 */ 887 HashMap<String, IBinder> mAppBindArgs; 888 889 /** 890 * Temporary to avoid allocations. Protected by main lock. 891 */ 892 final StringBuilder mStringBuilder = new StringBuilder(256); 893 894 /** 895 * Used to control how we initialize the service. 896 */ 897 ComponentName mTopComponent; 898 String mTopAction = Intent.ACTION_MAIN; 899 String mTopData; 900 boolean mProcessesReady = false; 901 boolean mSystemReady = false; 902 boolean mBooting = false; 903 boolean mCallFinishBooting = false; 904 boolean mBootAnimationComplete = false; 905 boolean mWaitingUpdate = false; 906 boolean mDidUpdate = false; 907 boolean mOnBattery = false; 908 boolean mLaunchWarningShown = false; 909 910 Context mContext; 911 912 int mFactoryTest; 913 914 boolean mCheckedForSetup; 915 916 /** 917 * The time at which we will allow normal application switches again, 918 * after a call to {@link #stopAppSwitches()}. 919 */ 920 long mAppSwitchesAllowedTime; 921 922 /** 923 * This is set to true after the first switch after mAppSwitchesAllowedTime 924 * is set; any switches after that will clear the time. 925 */ 926 boolean mDidAppSwitch; 927 928 /** 929 * Last time (in realtime) at which we checked for power usage. 930 */ 931 long mLastPowerCheckRealtime; 932 933 /** 934 * Last time (in uptime) at which we checked for power usage. 935 */ 936 long mLastPowerCheckUptime; 937 938 /** 939 * Set while we are wanting to sleep, to prevent any 940 * activities from being started/resumed. 941 */ 942 private boolean mSleeping = false; 943 944 /** 945 * Set while we are running a voice interaction. This overrides 946 * sleeping while it is active. 947 */ 948 private boolean mRunningVoice = false; 949 950 /** 951 * State of external calls telling us if the device is asleep. 952 */ 953 private boolean mWentToSleep = false; 954 955 /** 956 * State of external call telling us if the lock screen is shown. 957 */ 958 private boolean mLockScreenShown = false; 959 960 /** 961 * Set if we are shutting down the system, similar to sleeping. 962 */ 963 boolean mShuttingDown = false; 964 965 /** 966 * Current sequence id for oom_adj computation traversal. 967 */ 968 int mAdjSeq = 0; 969 970 /** 971 * Current sequence id for process LRU updating. 972 */ 973 int mLruSeq = 0; 974 975 /** 976 * Keep track of the non-cached/empty process we last found, to help 977 * determine how to distribute cached/empty processes next time. 978 */ 979 int mNumNonCachedProcs = 0; 980 981 /** 982 * Keep track of the number of cached hidden procs, to balance oom adj 983 * distribution between those and empty procs. 984 */ 985 int mNumCachedHiddenProcs = 0; 986 987 /** 988 * Keep track of the number of service processes we last found, to 989 * determine on the next iteration which should be B services. 990 */ 991 int mNumServiceProcs = 0; 992 int mNewNumAServiceProcs = 0; 993 int mNewNumServiceProcs = 0; 994 995 /** 996 * Allow the current computed overall memory level of the system to go down? 997 * This is set to false when we are killing processes for reasons other than 998 * memory management, so that the now smaller process list will not be taken as 999 * an indication that memory is tighter. 1000 */ 1001 boolean mAllowLowerMemLevel = false; 1002 1003 /** 1004 * The last computed memory level, for holding when we are in a state that 1005 * processes are going away for other reasons. 1006 */ 1007 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1008 1009 /** 1010 * The last total number of process we have, to determine if changes actually look 1011 * like a shrinking number of process due to lower RAM. 1012 */ 1013 int mLastNumProcesses; 1014 1015 /** 1016 * The uptime of the last time we performed idle maintenance. 1017 */ 1018 long mLastIdleTime = SystemClock.uptimeMillis(); 1019 1020 /** 1021 * Total time spent with RAM that has been added in the past since the last idle time. 1022 */ 1023 long mLowRamTimeSinceLastIdle = 0; 1024 1025 /** 1026 * If RAM is currently low, when that horrible situation started. 1027 */ 1028 long mLowRamStartTime = 0; 1029 1030 /** 1031 * For reporting to battery stats the current top application. 1032 */ 1033 private String mCurResumedPackage = null; 1034 private int mCurResumedUid = -1; 1035 1036 /** 1037 * For reporting to battery stats the apps currently running foreground 1038 * service. The ProcessMap is package/uid tuples; each of these contain 1039 * an array of the currently foreground processes. 1040 */ 1041 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1042 = new ProcessMap<ArrayList<ProcessRecord>>(); 1043 1044 /** 1045 * This is set if we had to do a delayed dexopt of an app before launching 1046 * it, to increase the ANR timeouts in that case. 1047 */ 1048 boolean mDidDexOpt; 1049 1050 /** 1051 * Set if the systemServer made a call to enterSafeMode. 1052 */ 1053 boolean mSafeMode; 1054 1055 String mDebugApp = null; 1056 boolean mWaitForDebugger = false; 1057 boolean mDebugTransient = false; 1058 String mOrigDebugApp = null; 1059 boolean mOrigWaitForDebugger = false; 1060 boolean mAlwaysFinishActivities = false; 1061 IActivityController mController = null; 1062 String mProfileApp = null; 1063 ProcessRecord mProfileProc = null; 1064 String mProfileFile; 1065 ParcelFileDescriptor mProfileFd; 1066 int mSamplingInterval = 0; 1067 boolean mAutoStopProfiler = false; 1068 int mProfileType = 0; 1069 String mOpenGlTraceApp = null; 1070 1071 static class ProcessChangeItem { 1072 static final int CHANGE_ACTIVITIES = 1<<0; 1073 static final int CHANGE_PROCESS_STATE = 1<<1; 1074 int changes; 1075 int uid; 1076 int pid; 1077 int processState; 1078 boolean foregroundActivities; 1079 } 1080 1081 final RemoteCallbackList<IProcessObserver> mProcessObservers 1082 = new RemoteCallbackList<IProcessObserver>(); 1083 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1084 1085 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1086 = new ArrayList<ProcessChangeItem>(); 1087 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1088 = new ArrayList<ProcessChangeItem>(); 1089 1090 /** 1091 * Runtime CPU use collection thread. This object's lock is used to 1092 * perform synchronization with the thread (notifying it to run). 1093 */ 1094 final Thread mProcessCpuThread; 1095 1096 /** 1097 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1098 * Must acquire this object's lock when accessing it. 1099 * NOTE: this lock will be held while doing long operations (trawling 1100 * through all processes in /proc), so it should never be acquired by 1101 * any critical paths such as when holding the main activity manager lock. 1102 */ 1103 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1104 MONITOR_THREAD_CPU_USAGE); 1105 final AtomicLong mLastCpuTime = new AtomicLong(0); 1106 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1107 1108 long mLastWriteTime = 0; 1109 1110 /** 1111 * Used to retain an update lock when the foreground activity is in 1112 * immersive mode. 1113 */ 1114 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1115 1116 /** 1117 * Set to true after the system has finished booting. 1118 */ 1119 boolean mBooted = false; 1120 1121 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1122 int mProcessLimitOverride = -1; 1123 1124 WindowManagerService mWindowManager; 1125 1126 final ActivityThread mSystemThread; 1127 1128 // Holds the current foreground user's id 1129 int mCurrentUserId = 0; 1130 // Holds the target user's id during a user switch 1131 int mTargetUserId = UserHandle.USER_NULL; 1132 // If there are multiple profiles for the current user, their ids are here 1133 // Currently only the primary user can have managed profiles 1134 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1135 1136 /** 1137 * Mapping from each known user ID to the profile group ID it is associated with. 1138 */ 1139 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1140 1141 private UserManagerService mUserManager; 1142 1143 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1144 final ProcessRecord mApp; 1145 final int mPid; 1146 final IApplicationThread mAppThread; 1147 1148 AppDeathRecipient(ProcessRecord app, int pid, 1149 IApplicationThread thread) { 1150 if (localLOGV) Slog.v( 1151 TAG, "New death recipient " + this 1152 + " for thread " + thread.asBinder()); 1153 mApp = app; 1154 mPid = pid; 1155 mAppThread = thread; 1156 } 1157 1158 @Override 1159 public void binderDied() { 1160 if (localLOGV) Slog.v( 1161 TAG, "Death received in " + this 1162 + " for thread " + mAppThread.asBinder()); 1163 synchronized(ActivityManagerService.this) { 1164 appDiedLocked(mApp, mPid, mAppThread); 1165 } 1166 } 1167 } 1168 1169 static final int SHOW_ERROR_MSG = 1; 1170 static final int SHOW_NOT_RESPONDING_MSG = 2; 1171 static final int SHOW_FACTORY_ERROR_MSG = 3; 1172 static final int UPDATE_CONFIGURATION_MSG = 4; 1173 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1174 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1175 static final int SERVICE_TIMEOUT_MSG = 12; 1176 static final int UPDATE_TIME_ZONE = 13; 1177 static final int SHOW_UID_ERROR_MSG = 14; 1178 static final int IM_FEELING_LUCKY_MSG = 15; 1179 static final int PROC_START_TIMEOUT_MSG = 20; 1180 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1181 static final int KILL_APPLICATION_MSG = 22; 1182 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1183 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1184 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1185 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1186 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1187 static final int CLEAR_DNS_CACHE_MSG = 28; 1188 static final int UPDATE_HTTP_PROXY_MSG = 29; 1189 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1190 static final int DISPATCH_PROCESSES_CHANGED = 31; 1191 static final int DISPATCH_PROCESS_DIED = 32; 1192 static final int REPORT_MEM_USAGE_MSG = 33; 1193 static final int REPORT_USER_SWITCH_MSG = 34; 1194 static final int CONTINUE_USER_SWITCH_MSG = 35; 1195 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1196 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1197 static final int PERSIST_URI_GRANTS_MSG = 38; 1198 static final int REQUEST_ALL_PSS_MSG = 39; 1199 static final int START_PROFILES_MSG = 40; 1200 static final int UPDATE_TIME = 41; 1201 static final int SYSTEM_USER_START_MSG = 42; 1202 static final int SYSTEM_USER_CURRENT_MSG = 43; 1203 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1204 static final int FINISH_BOOTING_MSG = 45; 1205 static final int START_USER_SWITCH_MSG = 46; 1206 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1207 1208 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1209 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1210 static final int FIRST_COMPAT_MODE_MSG = 300; 1211 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1212 1213 AlertDialog mUidAlert; 1214 CompatModeDialog mCompatModeDialog; 1215 long mLastMemUsageReportTime = 0; 1216 1217 private LockToAppRequestDialog mLockToAppRequest; 1218 1219 /** 1220 * Flag whether the current user is a "monkey", i.e. whether 1221 * the UI is driven by a UI automation tool. 1222 */ 1223 private boolean mUserIsMonkey; 1224 1225 /** Flag whether the device has a Recents UI */ 1226 boolean mHasRecents; 1227 1228 /** The dimensions of the thumbnails in the Recents UI. */ 1229 int mThumbnailWidth; 1230 int mThumbnailHeight; 1231 1232 final ServiceThread mHandlerThread; 1233 final MainHandler mHandler; 1234 1235 final class MainHandler extends Handler { 1236 public MainHandler(Looper looper) { 1237 super(looper, null, true); 1238 } 1239 1240 @Override 1241 public void handleMessage(Message msg) { 1242 switch (msg.what) { 1243 case SHOW_ERROR_MSG: { 1244 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1245 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1246 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1247 synchronized (ActivityManagerService.this) { 1248 ProcessRecord proc = (ProcessRecord)data.get("app"); 1249 AppErrorResult res = (AppErrorResult) data.get("result"); 1250 if (proc != null && proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has crash dialog: " + proc); 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 return; 1256 } 1257 boolean isBackground = (UserHandle.getAppId(proc.uid) 1258 >= Process.FIRST_APPLICATION_UID 1259 && proc.pid != MY_PID); 1260 for (int userId : mCurrentProfileIds) { 1261 isBackground &= (proc.userId != userId); 1262 } 1263 if (isBackground && !showBackground) { 1264 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1265 if (res != null) { 1266 res.set(0); 1267 } 1268 return; 1269 } 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new AppErrorDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 if (res != null) { 1279 res.set(0); 1280 } 1281 } 1282 } 1283 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_NOT_RESPONDING_MSG: { 1287 synchronized (ActivityManagerService.this) { 1288 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1289 ProcessRecord proc = (ProcessRecord)data.get("app"); 1290 if (proc != null && proc.anrDialog != null) { 1291 Slog.e(TAG, "App already has anr dialog: " + proc); 1292 return; 1293 } 1294 1295 Intent intent = new Intent("android.intent.action.ANR"); 1296 if (!mProcessesReady) { 1297 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1298 | Intent.FLAG_RECEIVER_FOREGROUND); 1299 } 1300 broadcastIntentLocked(null, null, intent, 1301 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1302 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1303 1304 if (mShowDialogs) { 1305 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1306 mContext, proc, (ActivityRecord)data.get("activity"), 1307 msg.arg1 != 0); 1308 d.show(); 1309 proc.anrDialog = d; 1310 } else { 1311 // Just kill the app if there is no dialog to be shown. 1312 killAppAtUsersRequest(proc, null); 1313 } 1314 } 1315 1316 ensureBootCompleted(); 1317 } break; 1318 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 ProcessRecord proc = (ProcessRecord) data.get("app"); 1322 if (proc == null) { 1323 Slog.e(TAG, "App not found when showing strict mode dialog."); 1324 break; 1325 } 1326 if (proc.crashDialog != null) { 1327 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1328 return; 1329 } 1330 AppErrorResult res = (AppErrorResult) data.get("result"); 1331 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1332 Dialog d = new StrictModeViolationDialog(mContext, 1333 ActivityManagerService.this, res, proc); 1334 d.show(); 1335 proc.crashDialog = d; 1336 } else { 1337 // The device is asleep, so just pretend that the user 1338 // saw a crash dialog and hit "force quit". 1339 res.set(0); 1340 } 1341 } 1342 ensureBootCompleted(); 1343 } break; 1344 case SHOW_FACTORY_ERROR_MSG: { 1345 Dialog d = new FactoryErrorDialog( 1346 mContext, msg.getData().getCharSequence("msg")); 1347 d.show(); 1348 ensureBootCompleted(); 1349 } break; 1350 case UPDATE_CONFIGURATION_MSG: { 1351 final ContentResolver resolver = mContext.getContentResolver(); 1352 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1353 } break; 1354 case GC_BACKGROUND_PROCESSES_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 performAppGcsIfAppropriateLocked(); 1357 } 1358 } break; 1359 case WAIT_FOR_DEBUGGER_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 ProcessRecord app = (ProcessRecord)msg.obj; 1362 if (msg.arg1 != 0) { 1363 if (!app.waitedForDebugger) { 1364 Dialog d = new AppWaitingForDebuggerDialog( 1365 ActivityManagerService.this, 1366 mContext, app); 1367 app.waitDialog = d; 1368 app.waitedForDebugger = true; 1369 d.show(); 1370 } 1371 } else { 1372 if (app.waitDialog != null) { 1373 app.waitDialog.dismiss(); 1374 app.waitDialog = null; 1375 } 1376 } 1377 } 1378 } break; 1379 case SERVICE_TIMEOUT_MSG: { 1380 if (mDidDexOpt) { 1381 mDidDexOpt = false; 1382 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1383 nmsg.obj = msg.obj; 1384 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1385 return; 1386 } 1387 mServices.serviceTimeout((ProcessRecord)msg.obj); 1388 } break; 1389 case UPDATE_TIME_ZONE: { 1390 synchronized (ActivityManagerService.this) { 1391 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1392 ProcessRecord r = mLruProcesses.get(i); 1393 if (r.thread != null) { 1394 try { 1395 r.thread.updateTimeZone(); 1396 } catch (RemoteException ex) { 1397 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1398 } 1399 } 1400 } 1401 } 1402 } break; 1403 case CLEAR_DNS_CACHE_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.clearDnsCache(); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1412 } 1413 } 1414 } 1415 } 1416 } break; 1417 case UPDATE_HTTP_PROXY_MSG: { 1418 ProxyInfo proxy = (ProxyInfo)msg.obj; 1419 String host = ""; 1420 String port = ""; 1421 String exclList = ""; 1422 Uri pacFileUrl = Uri.EMPTY; 1423 if (proxy != null) { 1424 host = proxy.getHost(); 1425 port = Integer.toString(proxy.getPort()); 1426 exclList = proxy.getExclusionListAsString(); 1427 pacFileUrl = proxy.getPacFileUrl(); 1428 } 1429 synchronized (ActivityManagerService.this) { 1430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1431 ProcessRecord r = mLruProcesses.get(i); 1432 if (r.thread != null) { 1433 try { 1434 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1435 } catch (RemoteException ex) { 1436 Slog.w(TAG, "Failed to update http proxy for: " + 1437 r.info.processName); 1438 } 1439 } 1440 } 1441 } 1442 } break; 1443 case SHOW_UID_ERROR_MSG: { 1444 String title = "System UIDs Inconsistent"; 1445 String text = "UIDs on the system are inconsistent, you need to wipe your" 1446 + " data partition or your device will be unstable."; 1447 Log.e(TAG, title + ": " + text); 1448 if (mShowDialogs) { 1449 // XXX This is a temporary dialog, no need to localize. 1450 AlertDialog d = new BaseErrorDialog(mContext); 1451 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1452 d.setCancelable(false); 1453 d.setTitle(title); 1454 d.setMessage(text); 1455 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1456 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1457 mUidAlert = d; 1458 d.show(); 1459 } 1460 } break; 1461 case IM_FEELING_LUCKY_MSG: { 1462 if (mUidAlert != null) { 1463 mUidAlert.dismiss(); 1464 mUidAlert = null; 1465 } 1466 } break; 1467 case PROC_START_TIMEOUT_MSG: { 1468 if (mDidDexOpt) { 1469 mDidDexOpt = false; 1470 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1471 nmsg.obj = msg.obj; 1472 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1473 return; 1474 } 1475 ProcessRecord app = (ProcessRecord)msg.obj; 1476 synchronized (ActivityManagerService.this) { 1477 processStartTimedOutLocked(app); 1478 } 1479 } break; 1480 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1483 } 1484 } break; 1485 case KILL_APPLICATION_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 int appid = msg.arg1; 1488 boolean restart = (msg.arg2 == 1); 1489 Bundle bundle = (Bundle)msg.obj; 1490 String pkg = bundle.getString("pkg"); 1491 String reason = bundle.getString("reason"); 1492 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1493 false, UserHandle.USER_ALL, reason); 1494 } 1495 } break; 1496 case FINALIZE_PENDING_INTENT_MSG: { 1497 ((PendingIntentRecord)msg.obj).completeFinalize(); 1498 } break; 1499 case POST_HEAVY_NOTIFICATION_MSG: { 1500 INotificationManager inm = NotificationManager.getService(); 1501 if (inm == null) { 1502 return; 1503 } 1504 1505 ActivityRecord root = (ActivityRecord)msg.obj; 1506 ProcessRecord process = root.app; 1507 if (process == null) { 1508 return; 1509 } 1510 1511 try { 1512 Context context = mContext.createPackageContext(process.info.packageName, 0); 1513 String text = mContext.getString(R.string.heavy_weight_notification, 1514 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1515 Notification notification = new Notification(); 1516 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1517 notification.when = 0; 1518 notification.flags = Notification.FLAG_ONGOING_EVENT; 1519 notification.tickerText = text; 1520 notification.defaults = 0; // please be quiet 1521 notification.sound = null; 1522 notification.vibrate = null; 1523 notification.color = mContext.getResources().getColor( 1524 com.android.internal.R.color.system_notification_accent_color); 1525 notification.setLatestEventInfo(context, text, 1526 mContext.getText(R.string.heavy_weight_notification_detail), 1527 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1528 PendingIntent.FLAG_CANCEL_CURRENT, null, 1529 new UserHandle(root.userId))); 1530 1531 try { 1532 int[] outId = new int[1]; 1533 inm.enqueueNotificationWithTag("android", "android", null, 1534 R.string.heavy_weight_notification, 1535 notification, outId, root.userId); 1536 } catch (RuntimeException e) { 1537 Slog.w(ActivityManagerService.TAG, 1538 "Error showing notification for heavy-weight app", e); 1539 } catch (RemoteException e) { 1540 } 1541 } catch (NameNotFoundException e) { 1542 Slog.w(TAG, "Unable to create context for heavy notification", e); 1543 } 1544 } break; 1545 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1546 INotificationManager inm = NotificationManager.getService(); 1547 if (inm == null) { 1548 return; 1549 } 1550 try { 1551 inm.cancelNotificationWithTag("android", null, 1552 R.string.heavy_weight_notification, msg.arg1); 1553 } catch (RuntimeException e) { 1554 Slog.w(ActivityManagerService.TAG, 1555 "Error canceling notification for service", e); 1556 } catch (RemoteException e) { 1557 } 1558 } break; 1559 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1560 synchronized (ActivityManagerService.this) { 1561 checkExcessivePowerUsageLocked(true); 1562 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1563 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1564 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1565 } 1566 } break; 1567 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1568 synchronized (ActivityManagerService.this) { 1569 ActivityRecord ar = (ActivityRecord)msg.obj; 1570 if (mCompatModeDialog != null) { 1571 if (mCompatModeDialog.mAppInfo.packageName.equals( 1572 ar.info.applicationInfo.packageName)) { 1573 return; 1574 } 1575 mCompatModeDialog.dismiss(); 1576 mCompatModeDialog = null; 1577 } 1578 if (ar != null && false) { 1579 if (mCompatModePackages.getPackageAskCompatModeLocked( 1580 ar.packageName)) { 1581 int mode = mCompatModePackages.computeCompatModeLocked( 1582 ar.info.applicationInfo); 1583 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1584 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1585 mCompatModeDialog = new CompatModeDialog( 1586 ActivityManagerService.this, mContext, 1587 ar.info.applicationInfo); 1588 mCompatModeDialog.show(); 1589 } 1590 } 1591 } 1592 } 1593 break; 1594 } 1595 case DISPATCH_PROCESSES_CHANGED: { 1596 dispatchProcessesChanged(); 1597 break; 1598 } 1599 case DISPATCH_PROCESS_DIED: { 1600 final int pid = msg.arg1; 1601 final int uid = msg.arg2; 1602 dispatchProcessDied(pid, uid); 1603 break; 1604 } 1605 case REPORT_MEM_USAGE_MSG: { 1606 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1607 Thread thread = new Thread() { 1608 @Override public void run() { 1609 final SparseArray<ProcessMemInfo> infoMap 1610 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1611 for (int i=0, N=memInfos.size(); i<N; i++) { 1612 ProcessMemInfo mi = memInfos.get(i); 1613 infoMap.put(mi.pid, mi); 1614 } 1615 updateCpuStatsNow(); 1616 synchronized (mProcessCpuTracker) { 1617 final int N = mProcessCpuTracker.countStats(); 1618 for (int i=0; i<N; i++) { 1619 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1620 if (st.vsize > 0) { 1621 long pss = Debug.getPss(st.pid, null); 1622 if (pss > 0) { 1623 if (infoMap.indexOfKey(st.pid) < 0) { 1624 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1625 ProcessList.NATIVE_ADJ, -1, "native", null); 1626 mi.pss = pss; 1627 memInfos.add(mi); 1628 } 1629 } 1630 } 1631 } 1632 } 1633 1634 long totalPss = 0; 1635 for (int i=0, N=memInfos.size(); i<N; i++) { 1636 ProcessMemInfo mi = memInfos.get(i); 1637 if (mi.pss == 0) { 1638 mi.pss = Debug.getPss(mi.pid, null); 1639 } 1640 totalPss += mi.pss; 1641 } 1642 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1643 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1644 if (lhs.oomAdj != rhs.oomAdj) { 1645 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1646 } 1647 if (lhs.pss != rhs.pss) { 1648 return lhs.pss < rhs.pss ? 1 : -1; 1649 } 1650 return 0; 1651 } 1652 }); 1653 1654 StringBuilder tag = new StringBuilder(128); 1655 StringBuilder stack = new StringBuilder(128); 1656 tag.append("Low on memory -- "); 1657 appendMemBucket(tag, totalPss, "total", false); 1658 appendMemBucket(stack, totalPss, "total", true); 1659 1660 StringBuilder logBuilder = new StringBuilder(1024); 1661 logBuilder.append("Low on memory:\n"); 1662 1663 boolean firstLine = true; 1664 int lastOomAdj = Integer.MIN_VALUE; 1665 for (int i=0, N=memInfos.size(); i<N; i++) { 1666 ProcessMemInfo mi = memInfos.get(i); 1667 1668 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1669 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1670 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1671 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1672 if (lastOomAdj != mi.oomAdj) { 1673 lastOomAdj = mi.oomAdj; 1674 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1675 tag.append(" / "); 1676 } 1677 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1678 if (firstLine) { 1679 stack.append(":"); 1680 firstLine = false; 1681 } 1682 stack.append("\n\t at "); 1683 } else { 1684 stack.append("$"); 1685 } 1686 } else { 1687 tag.append(" "); 1688 stack.append("$"); 1689 } 1690 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1691 appendMemBucket(tag, mi.pss, mi.name, false); 1692 } 1693 appendMemBucket(stack, mi.pss, mi.name, true); 1694 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1695 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1696 stack.append("("); 1697 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1698 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1699 stack.append(DUMP_MEM_OOM_LABEL[k]); 1700 stack.append(":"); 1701 stack.append(DUMP_MEM_OOM_ADJ[k]); 1702 } 1703 } 1704 stack.append(")"); 1705 } 1706 } 1707 1708 logBuilder.append(" "); 1709 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1710 logBuilder.append(' '); 1711 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1712 logBuilder.append(' '); 1713 ProcessList.appendRamKb(logBuilder, mi.pss); 1714 logBuilder.append(" kB: "); 1715 logBuilder.append(mi.name); 1716 logBuilder.append(" ("); 1717 logBuilder.append(mi.pid); 1718 logBuilder.append(") "); 1719 logBuilder.append(mi.adjType); 1720 logBuilder.append('\n'); 1721 if (mi.adjReason != null) { 1722 logBuilder.append(" "); 1723 logBuilder.append(mi.adjReason); 1724 logBuilder.append('\n'); 1725 } 1726 } 1727 1728 logBuilder.append(" "); 1729 ProcessList.appendRamKb(logBuilder, totalPss); 1730 logBuilder.append(" kB: TOTAL\n"); 1731 1732 long[] infos = new long[Debug.MEMINFO_COUNT]; 1733 Debug.getMemInfo(infos); 1734 logBuilder.append(" MemInfo: "); 1735 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1736 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1737 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1738 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1739 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1740 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1741 logBuilder.append(" ZRAM: "); 1742 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1743 logBuilder.append(" kB RAM, "); 1744 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1745 logBuilder.append(" kB swap total, "); 1746 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1747 logBuilder.append(" kB swap free\n"); 1748 } 1749 Slog.i(TAG, logBuilder.toString()); 1750 1751 StringBuilder dropBuilder = new StringBuilder(1024); 1752 /* 1753 StringWriter oomSw = new StringWriter(); 1754 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1755 StringWriter catSw = new StringWriter(); 1756 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1757 String[] emptyArgs = new String[] { }; 1758 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1759 oomPw.flush(); 1760 String oomString = oomSw.toString(); 1761 */ 1762 dropBuilder.append(stack); 1763 dropBuilder.append('\n'); 1764 dropBuilder.append('\n'); 1765 dropBuilder.append(logBuilder); 1766 dropBuilder.append('\n'); 1767 /* 1768 dropBuilder.append(oomString); 1769 dropBuilder.append('\n'); 1770 */ 1771 StringWriter catSw = new StringWriter(); 1772 synchronized (ActivityManagerService.this) { 1773 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1774 String[] emptyArgs = new String[] { }; 1775 catPw.println(); 1776 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1777 catPw.println(); 1778 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1779 false, false, null); 1780 catPw.println(); 1781 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1782 catPw.flush(); 1783 } 1784 dropBuilder.append(catSw.toString()); 1785 addErrorToDropBox("lowmem", null, "system_server", null, 1786 null, tag.toString(), dropBuilder.toString(), null, null); 1787 //Slog.i(TAG, "Sent to dropbox:"); 1788 //Slog.i(TAG, dropBuilder.toString()); 1789 synchronized (ActivityManagerService.this) { 1790 long now = SystemClock.uptimeMillis(); 1791 if (mLastMemUsageReportTime < now) { 1792 mLastMemUsageReportTime = now; 1793 } 1794 } 1795 } 1796 }; 1797 thread.start(); 1798 break; 1799 } 1800 case START_USER_SWITCH_MSG: { 1801 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1802 break; 1803 } 1804 case REPORT_USER_SWITCH_MSG: { 1805 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1806 break; 1807 } 1808 case CONTINUE_USER_SWITCH_MSG: { 1809 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1810 break; 1811 } 1812 case USER_SWITCH_TIMEOUT_MSG: { 1813 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1814 break; 1815 } 1816 case IMMERSIVE_MODE_LOCK_MSG: { 1817 final boolean nextState = (msg.arg1 != 0); 1818 if (mUpdateLock.isHeld() != nextState) { 1819 if (DEBUG_IMMERSIVE) { 1820 final ActivityRecord r = (ActivityRecord) msg.obj; 1821 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1822 } 1823 if (nextState) { 1824 mUpdateLock.acquire(); 1825 } else { 1826 mUpdateLock.release(); 1827 } 1828 } 1829 break; 1830 } 1831 case PERSIST_URI_GRANTS_MSG: { 1832 writeGrantedUriPermissions(); 1833 break; 1834 } 1835 case REQUEST_ALL_PSS_MSG: { 1836 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1837 break; 1838 } 1839 case START_PROFILES_MSG: { 1840 synchronized (ActivityManagerService.this) { 1841 startProfilesLocked(); 1842 } 1843 break; 1844 } 1845 case UPDATE_TIME: { 1846 synchronized (ActivityManagerService.this) { 1847 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1848 ProcessRecord r = mLruProcesses.get(i); 1849 if (r.thread != null) { 1850 try { 1851 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1852 } catch (RemoteException ex) { 1853 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1854 } 1855 } 1856 } 1857 } 1858 break; 1859 } 1860 case SYSTEM_USER_START_MSG: { 1861 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1862 Integer.toString(msg.arg1), msg.arg1); 1863 mSystemServiceManager.startUser(msg.arg1); 1864 break; 1865 } 1866 case SYSTEM_USER_CURRENT_MSG: { 1867 mBatteryStatsService.noteEvent( 1868 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1869 Integer.toString(msg.arg2), msg.arg2); 1870 mBatteryStatsService.noteEvent( 1871 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1872 Integer.toString(msg.arg1), msg.arg1); 1873 mSystemServiceManager.switchUser(msg.arg1); 1874 mLockToAppRequest.clearPrompt(); 1875 break; 1876 } 1877 case ENTER_ANIMATION_COMPLETE_MSG: { 1878 synchronized (ActivityManagerService.this) { 1879 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1880 if (r != null && r.app != null && r.app.thread != null) { 1881 try { 1882 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1883 } catch (RemoteException e) { 1884 } 1885 } 1886 } 1887 break; 1888 } 1889 case FINISH_BOOTING_MSG: { 1890 if (msg.arg1 != 0) { 1891 finishBooting(); 1892 } 1893 if (msg.arg2 != 0) { 1894 enableScreenAfterBoot(); 1895 } 1896 break; 1897 } 1898 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1899 try { 1900 Locale l = (Locale) msg.obj; 1901 IBinder service = ServiceManager.getService("mount"); 1902 IMountService mountService = IMountService.Stub.asInterface(service); 1903 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1904 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1905 } catch (RemoteException e) { 1906 Log.e(TAG, "Error storing locale for decryption UI", e); 1907 } 1908 break; 1909 } 1910 } 1911 } 1912 }; 1913 1914 static final int COLLECT_PSS_BG_MSG = 1; 1915 1916 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1917 @Override 1918 public void handleMessage(Message msg) { 1919 switch (msg.what) { 1920 case COLLECT_PSS_BG_MSG: { 1921 long start = SystemClock.uptimeMillis(); 1922 MemInfoReader memInfo = null; 1923 synchronized (ActivityManagerService.this) { 1924 if (mFullPssPending) { 1925 mFullPssPending = false; 1926 memInfo = new MemInfoReader(); 1927 } 1928 } 1929 if (memInfo != null) { 1930 updateCpuStatsNow(); 1931 long nativeTotalPss = 0; 1932 synchronized (mProcessCpuTracker) { 1933 final int N = mProcessCpuTracker.countStats(); 1934 for (int j=0; j<N; j++) { 1935 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1936 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1937 // This is definitely an application process; skip it. 1938 continue; 1939 } 1940 synchronized (mPidsSelfLocked) { 1941 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1942 // This is one of our own processes; skip it. 1943 continue; 1944 } 1945 } 1946 nativeTotalPss += Debug.getPss(st.pid, null); 1947 } 1948 } 1949 memInfo.readMemInfo(); 1950 synchronized (ActivityManagerService.this) { 1951 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1952 + (SystemClock.uptimeMillis()-start) + "ms"); 1953 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1954 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1955 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1956 +memInfo.getSlabSizeKb(), 1957 nativeTotalPss); 1958 } 1959 } 1960 1961 int i=0, num=0; 1962 long[] tmp = new long[1]; 1963 do { 1964 ProcessRecord proc; 1965 int procState; 1966 int pid; 1967 synchronized (ActivityManagerService.this) { 1968 if (i >= mPendingPssProcesses.size()) { 1969 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1970 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1971 mPendingPssProcesses.clear(); 1972 return; 1973 } 1974 proc = mPendingPssProcesses.get(i); 1975 procState = proc.pssProcState; 1976 if (proc.thread != null && procState == proc.setProcState) { 1977 pid = proc.pid; 1978 } else { 1979 proc = null; 1980 pid = 0; 1981 } 1982 i++; 1983 } 1984 if (proc != null) { 1985 long pss = Debug.getPss(pid, tmp); 1986 synchronized (ActivityManagerService.this) { 1987 if (proc.thread != null && proc.setProcState == procState 1988 && proc.pid == pid) { 1989 num++; 1990 proc.lastPssTime = SystemClock.uptimeMillis(); 1991 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1992 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1993 + ": " + pss + " lastPss=" + proc.lastPss 1994 + " state=" + ProcessList.makeProcStateString(procState)); 1995 if (proc.initialIdlePss == 0) { 1996 proc.initialIdlePss = pss; 1997 } 1998 proc.lastPss = pss; 1999 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 2000 proc.lastCachedPss = pss; 2001 } 2002 } 2003 } 2004 } 2005 } while (true); 2006 } 2007 } 2008 } 2009 }; 2010 2011 /** 2012 * Monitor for package changes and update our internal state. 2013 */ 2014 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 2015 @Override 2016 public void onPackageRemoved(String packageName, int uid) { 2017 // Remove all tasks with activities in the specified package from the list of recent tasks 2018 final int eventUserId = getChangingUserId(); 2019 synchronized (ActivityManagerService.this) { 2020 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2021 TaskRecord tr = mRecentTasks.get(i); 2022 if (tr.userId != eventUserId) continue; 2023 2024 ComponentName cn = tr.intent.getComponent(); 2025 if (cn != null && cn.getPackageName().equals(packageName)) { 2026 // If the package name matches, remove the task and kill the process 2027 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2028 } 2029 } 2030 } 2031 } 2032 2033 @Override 2034 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2035 onPackageModified(packageName); 2036 return true; 2037 } 2038 2039 @Override 2040 public void onPackageModified(String packageName) { 2041 final int eventUserId = getChangingUserId(); 2042 final IPackageManager pm = AppGlobals.getPackageManager(); 2043 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2044 new ArrayList<Pair<Intent, Integer>>(); 2045 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2046 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2047 // Copy the list of recent tasks so that we don't hold onto the lock on 2048 // ActivityManagerService for long periods while checking if components exist. 2049 synchronized (ActivityManagerService.this) { 2050 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2051 TaskRecord tr = mRecentTasks.get(i); 2052 if (tr.userId != eventUserId) continue; 2053 2054 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2055 } 2056 } 2057 // Check the recent tasks and filter out all tasks with components that no longer exist. 2058 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2059 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2060 ComponentName cn = p.first.getComponent(); 2061 if (cn != null && cn.getPackageName().equals(packageName)) { 2062 if (componentsKnownToExist.contains(cn)) { 2063 // If we know that the component still exists in the package, then skip 2064 continue; 2065 } 2066 try { 2067 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 2068 if (info != null) { 2069 componentsKnownToExist.add(cn); 2070 } else { 2071 tasksToRemove.add(p.second); 2072 } 2073 } catch (RemoteException e) { 2074 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 2075 } 2076 } 2077 } 2078 // Prune all the tasks with removed components from the list of recent tasks 2079 synchronized (ActivityManagerService.this) { 2080 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2081 // Remove the task but don't kill the process (since other components in that 2082 // package may still be running and in the background) 2083 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2084 } 2085 } 2086 } 2087 2088 @Override 2089 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2090 // Force stop the specified packages 2091 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2092 if (packages != null) { 2093 for (String pkg : packages) { 2094 synchronized (ActivityManagerService.this) { 2095 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2096 userId, "finished booting")) { 2097 return true; 2098 } 2099 } 2100 } 2101 } 2102 return false; 2103 } 2104 }; 2105 2106 public void setSystemProcess() { 2107 try { 2108 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2109 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2110 ServiceManager.addService("meminfo", new MemBinder(this)); 2111 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2112 ServiceManager.addService("dbinfo", new DbBinder(this)); 2113 if (MONITOR_CPU_USAGE) { 2114 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2115 } 2116 ServiceManager.addService("permission", new PermissionController(this)); 2117 2118 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2119 "android", STOCK_PM_FLAGS); 2120 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2121 2122 synchronized (this) { 2123 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2124 app.persistent = true; 2125 app.pid = MY_PID; 2126 app.maxAdj = ProcessList.SYSTEM_ADJ; 2127 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2128 mProcessNames.put(app.processName, app.uid, app); 2129 synchronized (mPidsSelfLocked) { 2130 mPidsSelfLocked.put(app.pid, app); 2131 } 2132 updateLruProcessLocked(app, false, null); 2133 updateOomAdjLocked(); 2134 } 2135 } catch (PackageManager.NameNotFoundException e) { 2136 throw new RuntimeException( 2137 "Unable to find android system package", e); 2138 } 2139 } 2140 2141 public void setWindowManager(WindowManagerService wm) { 2142 mWindowManager = wm; 2143 mStackSupervisor.setWindowManager(wm); 2144 } 2145 2146 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2147 mUsageStatsService = usageStatsManager; 2148 } 2149 2150 public void startObservingNativeCrashes() { 2151 final NativeCrashListener ncl = new NativeCrashListener(this); 2152 ncl.start(); 2153 } 2154 2155 public IAppOpsService getAppOpsService() { 2156 return mAppOpsService; 2157 } 2158 2159 static class MemBinder extends Binder { 2160 ActivityManagerService mActivityManagerService; 2161 MemBinder(ActivityManagerService activityManagerService) { 2162 mActivityManagerService = activityManagerService; 2163 } 2164 2165 @Override 2166 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2167 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2168 != PackageManager.PERMISSION_GRANTED) { 2169 pw.println("Permission Denial: can't dump meminfo from from pid=" 2170 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2171 + " without permission " + android.Manifest.permission.DUMP); 2172 return; 2173 } 2174 2175 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2176 } 2177 } 2178 2179 static class GraphicsBinder extends Binder { 2180 ActivityManagerService mActivityManagerService; 2181 GraphicsBinder(ActivityManagerService activityManagerService) { 2182 mActivityManagerService = activityManagerService; 2183 } 2184 2185 @Override 2186 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2187 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2188 != PackageManager.PERMISSION_GRANTED) { 2189 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2190 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2191 + " without permission " + android.Manifest.permission.DUMP); 2192 return; 2193 } 2194 2195 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2196 } 2197 } 2198 2199 static class DbBinder extends Binder { 2200 ActivityManagerService mActivityManagerService; 2201 DbBinder(ActivityManagerService activityManagerService) { 2202 mActivityManagerService = activityManagerService; 2203 } 2204 2205 @Override 2206 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2207 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2208 != PackageManager.PERMISSION_GRANTED) { 2209 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2210 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2211 + " without permission " + android.Manifest.permission.DUMP); 2212 return; 2213 } 2214 2215 mActivityManagerService.dumpDbInfo(fd, pw, args); 2216 } 2217 } 2218 2219 static class CpuBinder extends Binder { 2220 ActivityManagerService mActivityManagerService; 2221 CpuBinder(ActivityManagerService activityManagerService) { 2222 mActivityManagerService = activityManagerService; 2223 } 2224 2225 @Override 2226 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2227 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2228 != PackageManager.PERMISSION_GRANTED) { 2229 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2230 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2231 + " without permission " + android.Manifest.permission.DUMP); 2232 return; 2233 } 2234 2235 synchronized (mActivityManagerService.mProcessCpuTracker) { 2236 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2237 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2238 SystemClock.uptimeMillis())); 2239 } 2240 } 2241 } 2242 2243 public static final class Lifecycle extends SystemService { 2244 private final ActivityManagerService mService; 2245 2246 public Lifecycle(Context context) { 2247 super(context); 2248 mService = new ActivityManagerService(context); 2249 } 2250 2251 @Override 2252 public void onStart() { 2253 mService.start(); 2254 } 2255 2256 public ActivityManagerService getService() { 2257 return mService; 2258 } 2259 } 2260 2261 // Note: This method is invoked on the main thread but may need to attach various 2262 // handlers to other threads. So take care to be explicit about the looper. 2263 public ActivityManagerService(Context systemContext) { 2264 mContext = systemContext; 2265 mFactoryTest = FactoryTest.getMode(); 2266 mSystemThread = ActivityThread.currentActivityThread(); 2267 2268 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2269 2270 mHandlerThread = new ServiceThread(TAG, 2271 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2272 mHandlerThread.start(); 2273 mHandler = new MainHandler(mHandlerThread.getLooper()); 2274 2275 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2276 "foreground", BROADCAST_FG_TIMEOUT, false); 2277 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2278 "background", BROADCAST_BG_TIMEOUT, true); 2279 mBroadcastQueues[0] = mFgBroadcastQueue; 2280 mBroadcastQueues[1] = mBgBroadcastQueue; 2281 2282 mServices = new ActiveServices(this); 2283 mProviderMap = new ProviderMap(this); 2284 2285 // TODO: Move creation of battery stats service outside of activity manager service. 2286 File dataDir = Environment.getDataDirectory(); 2287 File systemDir = new File(dataDir, "system"); 2288 systemDir.mkdirs(); 2289 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2290 mBatteryStatsService.getActiveStatistics().readLocked(); 2291 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2292 mOnBattery = DEBUG_POWER ? true 2293 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2294 mBatteryStatsService.getActiveStatistics().setCallback(this); 2295 2296 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2297 2298 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2299 2300 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2301 2302 // User 0 is the first and only user that runs at boot. 2303 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2304 mUserLru.add(Integer.valueOf(0)); 2305 updateStartedUserArrayLocked(); 2306 2307 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2308 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2309 2310 mConfiguration.setToDefaults(); 2311 mConfiguration.setLocale(Locale.getDefault()); 2312 2313 mConfigurationSeq = mConfiguration.seq = 1; 2314 mProcessCpuTracker.init(); 2315 2316 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2317 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2318 mStackSupervisor = new ActivityStackSupervisor(this); 2319 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2320 2321 mProcessCpuThread = new Thread("CpuTracker") { 2322 @Override 2323 public void run() { 2324 while (true) { 2325 try { 2326 try { 2327 synchronized(this) { 2328 final long now = SystemClock.uptimeMillis(); 2329 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2330 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2331 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2332 // + ", write delay=" + nextWriteDelay); 2333 if (nextWriteDelay < nextCpuDelay) { 2334 nextCpuDelay = nextWriteDelay; 2335 } 2336 if (nextCpuDelay > 0) { 2337 mProcessCpuMutexFree.set(true); 2338 this.wait(nextCpuDelay); 2339 } 2340 } 2341 } catch (InterruptedException e) { 2342 } 2343 updateCpuStatsNow(); 2344 } catch (Exception e) { 2345 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2346 } 2347 } 2348 } 2349 }; 2350 2351 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2352 2353 Watchdog.getInstance().addMonitor(this); 2354 Watchdog.getInstance().addThread(mHandler); 2355 } 2356 2357 public void setSystemServiceManager(SystemServiceManager mgr) { 2358 mSystemServiceManager = mgr; 2359 } 2360 2361 private void start() { 2362 Process.removeAllProcessGroups(); 2363 mProcessCpuThread.start(); 2364 2365 mBatteryStatsService.publish(mContext); 2366 mAppOpsService.publish(mContext); 2367 Slog.d("AppOps", "AppOpsService published"); 2368 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2369 } 2370 2371 public void initPowerManagement() { 2372 mStackSupervisor.initPowerManagement(); 2373 mBatteryStatsService.initPowerManagement(); 2374 } 2375 2376 @Override 2377 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2378 throws RemoteException { 2379 if (code == SYSPROPS_TRANSACTION) { 2380 // We need to tell all apps about the system property change. 2381 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2382 synchronized(this) { 2383 final int NP = mProcessNames.getMap().size(); 2384 for (int ip=0; ip<NP; ip++) { 2385 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2386 final int NA = apps.size(); 2387 for (int ia=0; ia<NA; ia++) { 2388 ProcessRecord app = apps.valueAt(ia); 2389 if (app.thread != null) { 2390 procs.add(app.thread.asBinder()); 2391 } 2392 } 2393 } 2394 } 2395 2396 int N = procs.size(); 2397 for (int i=0; i<N; i++) { 2398 Parcel data2 = Parcel.obtain(); 2399 try { 2400 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2401 } catch (RemoteException e) { 2402 } 2403 data2.recycle(); 2404 } 2405 } 2406 try { 2407 return super.onTransact(code, data, reply, flags); 2408 } catch (RuntimeException e) { 2409 // The activity manager only throws security exceptions, so let's 2410 // log all others. 2411 if (!(e instanceof SecurityException)) { 2412 Slog.wtf(TAG, "Activity Manager Crash", e); 2413 } 2414 throw e; 2415 } 2416 } 2417 2418 void updateCpuStats() { 2419 final long now = SystemClock.uptimeMillis(); 2420 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2421 return; 2422 } 2423 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2424 synchronized (mProcessCpuThread) { 2425 mProcessCpuThread.notify(); 2426 } 2427 } 2428 } 2429 2430 void updateCpuStatsNow() { 2431 synchronized (mProcessCpuTracker) { 2432 mProcessCpuMutexFree.set(false); 2433 final long now = SystemClock.uptimeMillis(); 2434 boolean haveNewCpuStats = false; 2435 2436 if (MONITOR_CPU_USAGE && 2437 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2438 mLastCpuTime.set(now); 2439 haveNewCpuStats = true; 2440 mProcessCpuTracker.update(); 2441 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2442 //Slog.i(TAG, "Total CPU usage: " 2443 // + mProcessCpu.getTotalCpuPercent() + "%"); 2444 2445 // Slog the cpu usage if the property is set. 2446 if ("true".equals(SystemProperties.get("events.cpu"))) { 2447 int user = mProcessCpuTracker.getLastUserTime(); 2448 int system = mProcessCpuTracker.getLastSystemTime(); 2449 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2450 int irq = mProcessCpuTracker.getLastIrqTime(); 2451 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2452 int idle = mProcessCpuTracker.getLastIdleTime(); 2453 2454 int total = user + system + iowait + irq + softIrq + idle; 2455 if (total == 0) total = 1; 2456 2457 EventLog.writeEvent(EventLogTags.CPU, 2458 ((user+system+iowait+irq+softIrq) * 100) / total, 2459 (user * 100) / total, 2460 (system * 100) / total, 2461 (iowait * 100) / total, 2462 (irq * 100) / total, 2463 (softIrq * 100) / total); 2464 } 2465 } 2466 2467 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2468 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2469 synchronized(bstats) { 2470 synchronized(mPidsSelfLocked) { 2471 if (haveNewCpuStats) { 2472 if (mOnBattery) { 2473 int perc = bstats.startAddingCpuLocked(); 2474 int totalUTime = 0; 2475 int totalSTime = 0; 2476 final int N = mProcessCpuTracker.countStats(); 2477 for (int i=0; i<N; i++) { 2478 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2479 if (!st.working) { 2480 continue; 2481 } 2482 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2483 int otherUTime = (st.rel_utime*perc)/100; 2484 int otherSTime = (st.rel_stime*perc)/100; 2485 totalUTime += otherUTime; 2486 totalSTime += otherSTime; 2487 if (pr != null) { 2488 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2489 if (ps == null || !ps.isActive()) { 2490 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2491 pr.info.uid, pr.processName); 2492 } 2493 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2494 st.rel_stime-otherSTime); 2495 ps.addSpeedStepTimes(cpuSpeedTimes); 2496 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2497 } else { 2498 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2499 if (ps == null || !ps.isActive()) { 2500 st.batteryStats = ps = bstats.getProcessStatsLocked( 2501 bstats.mapUid(st.uid), st.name); 2502 } 2503 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2504 st.rel_stime-otherSTime); 2505 ps.addSpeedStepTimes(cpuSpeedTimes); 2506 } 2507 } 2508 bstats.finishAddingCpuLocked(perc, totalUTime, 2509 totalSTime, cpuSpeedTimes); 2510 } 2511 } 2512 } 2513 2514 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2515 mLastWriteTime = now; 2516 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2517 } 2518 } 2519 } 2520 } 2521 2522 @Override 2523 public void batteryNeedsCpuUpdate() { 2524 updateCpuStatsNow(); 2525 } 2526 2527 @Override 2528 public void batteryPowerChanged(boolean onBattery) { 2529 // When plugging in, update the CPU stats first before changing 2530 // the plug state. 2531 updateCpuStatsNow(); 2532 synchronized (this) { 2533 synchronized(mPidsSelfLocked) { 2534 mOnBattery = DEBUG_POWER ? true : onBattery; 2535 } 2536 } 2537 } 2538 2539 /** 2540 * Initialize the application bind args. These are passed to each 2541 * process when the bindApplication() IPC is sent to the process. They're 2542 * lazily setup to make sure the services are running when they're asked for. 2543 */ 2544 private HashMap<String, IBinder> getCommonServicesLocked() { 2545 if (mAppBindArgs == null) { 2546 mAppBindArgs = new HashMap<String, IBinder>(); 2547 2548 // Setup the application init args 2549 mAppBindArgs.put("package", ServiceManager.getService("package")); 2550 mAppBindArgs.put("window", ServiceManager.getService("window")); 2551 mAppBindArgs.put(Context.ALARM_SERVICE, 2552 ServiceManager.getService(Context.ALARM_SERVICE)); 2553 } 2554 return mAppBindArgs; 2555 } 2556 2557 final void setFocusedActivityLocked(ActivityRecord r) { 2558 if (mFocusedActivity != r) { 2559 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2560 mFocusedActivity = r; 2561 if (r.task != null && r.task.voiceInteractor != null) { 2562 startRunningVoiceLocked(); 2563 } else { 2564 finishRunningVoiceLocked(); 2565 } 2566 mStackSupervisor.setFocusedStack(r); 2567 if (r != null) { 2568 mWindowManager.setFocusedApp(r.appToken, true); 2569 } 2570 applyUpdateLockStateLocked(r); 2571 } 2572 } 2573 2574 final void clearFocusedActivity(ActivityRecord r) { 2575 if (mFocusedActivity == r) { 2576 mFocusedActivity = null; 2577 } 2578 } 2579 2580 @Override 2581 public void setFocusedStack(int stackId) { 2582 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2583 synchronized (ActivityManagerService.this) { 2584 ActivityStack stack = mStackSupervisor.getStack(stackId); 2585 if (stack != null) { 2586 ActivityRecord r = stack.topRunningActivityLocked(null); 2587 if (r != null) { 2588 setFocusedActivityLocked(r); 2589 } 2590 } 2591 } 2592 } 2593 2594 @Override 2595 public void notifyActivityDrawn(IBinder token) { 2596 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2597 synchronized (this) { 2598 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2599 if (r != null) { 2600 r.task.stack.notifyActivityDrawnLocked(r); 2601 } 2602 } 2603 } 2604 2605 final void applyUpdateLockStateLocked(ActivityRecord r) { 2606 // Modifications to the UpdateLock state are done on our handler, outside 2607 // the activity manager's locks. The new state is determined based on the 2608 // state *now* of the relevant activity record. The object is passed to 2609 // the handler solely for logging detail, not to be consulted/modified. 2610 final boolean nextState = r != null && r.immersive; 2611 mHandler.sendMessage( 2612 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2613 } 2614 2615 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2616 Message msg = Message.obtain(); 2617 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2618 msg.obj = r.task.askedCompatMode ? null : r; 2619 mHandler.sendMessage(msg); 2620 } 2621 2622 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2623 String what, Object obj, ProcessRecord srcApp) { 2624 app.lastActivityTime = now; 2625 2626 if (app.activities.size() > 0) { 2627 // Don't want to touch dependent processes that are hosting activities. 2628 return index; 2629 } 2630 2631 int lrui = mLruProcesses.lastIndexOf(app); 2632 if (lrui < 0) { 2633 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2634 + what + " " + obj + " from " + srcApp); 2635 return index; 2636 } 2637 2638 if (lrui >= index) { 2639 // Don't want to cause this to move dependent processes *back* in the 2640 // list as if they were less frequently used. 2641 return index; 2642 } 2643 2644 if (lrui >= mLruProcessActivityStart) { 2645 // Don't want to touch dependent processes that are hosting activities. 2646 return index; 2647 } 2648 2649 mLruProcesses.remove(lrui); 2650 if (index > 0) { 2651 index--; 2652 } 2653 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2654 + " in LRU list: " + app); 2655 mLruProcesses.add(index, app); 2656 return index; 2657 } 2658 2659 final void removeLruProcessLocked(ProcessRecord app) { 2660 int lrui = mLruProcesses.lastIndexOf(app); 2661 if (lrui >= 0) { 2662 if (!app.killed) { 2663 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2664 Process.killProcessQuiet(app.pid); 2665 Process.killProcessGroup(app.info.uid, app.pid); 2666 } 2667 if (lrui <= mLruProcessActivityStart) { 2668 mLruProcessActivityStart--; 2669 } 2670 if (lrui <= mLruProcessServiceStart) { 2671 mLruProcessServiceStart--; 2672 } 2673 mLruProcesses.remove(lrui); 2674 } 2675 } 2676 2677 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2678 ProcessRecord client) { 2679 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2680 || app.treatLikeActivity; 2681 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2682 if (!activityChange && hasActivity) { 2683 // The process has activities, so we are only allowing activity-based adjustments 2684 // to move it. It should be kept in the front of the list with other 2685 // processes that have activities, and we don't want those to change their 2686 // order except due to activity operations. 2687 return; 2688 } 2689 2690 mLruSeq++; 2691 final long now = SystemClock.uptimeMillis(); 2692 app.lastActivityTime = now; 2693 2694 // First a quick reject: if the app is already at the position we will 2695 // put it, then there is nothing to do. 2696 if (hasActivity) { 2697 final int N = mLruProcesses.size(); 2698 if (N > 0 && mLruProcesses.get(N-1) == app) { 2699 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2700 return; 2701 } 2702 } else { 2703 if (mLruProcessServiceStart > 0 2704 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2705 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2706 return; 2707 } 2708 } 2709 2710 int lrui = mLruProcesses.lastIndexOf(app); 2711 2712 if (app.persistent && lrui >= 0) { 2713 // We don't care about the position of persistent processes, as long as 2714 // they are in the list. 2715 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2716 return; 2717 } 2718 2719 /* In progress: compute new position first, so we can avoid doing work 2720 if the process is not actually going to move. Not yet working. 2721 int addIndex; 2722 int nextIndex; 2723 boolean inActivity = false, inService = false; 2724 if (hasActivity) { 2725 // Process has activities, put it at the very tipsy-top. 2726 addIndex = mLruProcesses.size(); 2727 nextIndex = mLruProcessServiceStart; 2728 inActivity = true; 2729 } else if (hasService) { 2730 // Process has services, put it at the top of the service list. 2731 addIndex = mLruProcessActivityStart; 2732 nextIndex = mLruProcessServiceStart; 2733 inActivity = true; 2734 inService = true; 2735 } else { 2736 // Process not otherwise of interest, it goes to the top of the non-service area. 2737 addIndex = mLruProcessServiceStart; 2738 if (client != null) { 2739 int clientIndex = mLruProcesses.lastIndexOf(client); 2740 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2741 + app); 2742 if (clientIndex >= 0 && addIndex > clientIndex) { 2743 addIndex = clientIndex; 2744 } 2745 } 2746 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2747 } 2748 2749 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2750 + mLruProcessActivityStart + "): " + app); 2751 */ 2752 2753 if (lrui >= 0) { 2754 if (lrui < mLruProcessActivityStart) { 2755 mLruProcessActivityStart--; 2756 } 2757 if (lrui < mLruProcessServiceStart) { 2758 mLruProcessServiceStart--; 2759 } 2760 /* 2761 if (addIndex > lrui) { 2762 addIndex--; 2763 } 2764 if (nextIndex > lrui) { 2765 nextIndex--; 2766 } 2767 */ 2768 mLruProcesses.remove(lrui); 2769 } 2770 2771 /* 2772 mLruProcesses.add(addIndex, app); 2773 if (inActivity) { 2774 mLruProcessActivityStart++; 2775 } 2776 if (inService) { 2777 mLruProcessActivityStart++; 2778 } 2779 */ 2780 2781 int nextIndex; 2782 if (hasActivity) { 2783 final int N = mLruProcesses.size(); 2784 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2785 // Process doesn't have activities, but has clients with 2786 // activities... move it up, but one below the top (the top 2787 // should always have a real activity). 2788 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2789 mLruProcesses.add(N-1, app); 2790 // To keep it from spamming the LRU list (by making a bunch of clients), 2791 // we will push down any other entries owned by the app. 2792 final int uid = app.info.uid; 2793 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2794 ProcessRecord subProc = mLruProcesses.get(i); 2795 if (subProc.info.uid == uid) { 2796 // We want to push this one down the list. If the process after 2797 // it is for the same uid, however, don't do so, because we don't 2798 // want them internally to be re-ordered. 2799 if (mLruProcesses.get(i-1).info.uid != uid) { 2800 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2801 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2802 ProcessRecord tmp = mLruProcesses.get(i); 2803 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2804 mLruProcesses.set(i-1, tmp); 2805 i--; 2806 } 2807 } else { 2808 // A gap, we can stop here. 2809 break; 2810 } 2811 } 2812 } else { 2813 // Process has activities, put it at the very tipsy-top. 2814 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2815 mLruProcesses.add(app); 2816 } 2817 nextIndex = mLruProcessServiceStart; 2818 } else if (hasService) { 2819 // Process has services, put it at the top of the service list. 2820 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2821 mLruProcesses.add(mLruProcessActivityStart, app); 2822 nextIndex = mLruProcessServiceStart; 2823 mLruProcessActivityStart++; 2824 } else { 2825 // Process not otherwise of interest, it goes to the top of the non-service area. 2826 int index = mLruProcessServiceStart; 2827 if (client != null) { 2828 // If there is a client, don't allow the process to be moved up higher 2829 // in the list than that client. 2830 int clientIndex = mLruProcesses.lastIndexOf(client); 2831 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2832 + " when updating " + app); 2833 if (clientIndex <= lrui) { 2834 // Don't allow the client index restriction to push it down farther in the 2835 // list than it already is. 2836 clientIndex = lrui; 2837 } 2838 if (clientIndex >= 0 && index > clientIndex) { 2839 index = clientIndex; 2840 } 2841 } 2842 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2843 mLruProcesses.add(index, app); 2844 nextIndex = index-1; 2845 mLruProcessActivityStart++; 2846 mLruProcessServiceStart++; 2847 } 2848 2849 // If the app is currently using a content provider or service, 2850 // bump those processes as well. 2851 for (int j=app.connections.size()-1; j>=0; j--) { 2852 ConnectionRecord cr = app.connections.valueAt(j); 2853 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2854 && cr.binding.service.app != null 2855 && cr.binding.service.app.lruSeq != mLruSeq 2856 && !cr.binding.service.app.persistent) { 2857 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2858 "service connection", cr, app); 2859 } 2860 } 2861 for (int j=app.conProviders.size()-1; j>=0; j--) { 2862 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2863 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2864 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2865 "provider reference", cpr, app); 2866 } 2867 } 2868 } 2869 2870 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2871 if (uid == Process.SYSTEM_UID) { 2872 // The system gets to run in any process. If there are multiple 2873 // processes with the same uid, just pick the first (this 2874 // should never happen). 2875 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2876 if (procs == null) return null; 2877 final int N = procs.size(); 2878 for (int i = 0; i < N; i++) { 2879 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2880 } 2881 } 2882 ProcessRecord proc = mProcessNames.get(processName, uid); 2883 if (false && proc != null && !keepIfLarge 2884 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2885 && proc.lastCachedPss >= 4000) { 2886 // Turn this condition on to cause killing to happen regularly, for testing. 2887 if (proc.baseProcessTracker != null) { 2888 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2889 } 2890 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2891 } else if (proc != null && !keepIfLarge 2892 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2893 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2894 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2895 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2896 if (proc.baseProcessTracker != null) { 2897 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2898 } 2899 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2900 } 2901 } 2902 return proc; 2903 } 2904 2905 void ensurePackageDexOpt(String packageName) { 2906 IPackageManager pm = AppGlobals.getPackageManager(); 2907 try { 2908 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2909 mDidDexOpt = true; 2910 } 2911 } catch (RemoteException e) { 2912 } 2913 } 2914 2915 boolean isNextTransitionForward() { 2916 int transit = mWindowManager.getPendingAppTransition(); 2917 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2918 || transit == AppTransition.TRANSIT_TASK_OPEN 2919 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2920 } 2921 2922 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2923 String processName, String abiOverride, int uid, Runnable crashHandler) { 2924 synchronized(this) { 2925 ApplicationInfo info = new ApplicationInfo(); 2926 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2927 // For isolated processes, the former contains the parent's uid and the latter the 2928 // actual uid of the isolated process. 2929 // In the special case introduced by this method (which is, starting an isolated 2930 // process directly from the SystemServer without an actual parent app process) the 2931 // closest thing to a parent's uid is SYSTEM_UID. 2932 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2933 // the |isolated| logic in the ProcessRecord constructor. 2934 info.uid = Process.SYSTEM_UID; 2935 info.processName = processName; 2936 info.className = entryPoint; 2937 info.packageName = "android"; 2938 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2939 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2940 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2941 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2942 crashHandler); 2943 return proc != null ? proc.pid : 0; 2944 } 2945 } 2946 2947 final ProcessRecord startProcessLocked(String processName, 2948 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2949 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2950 boolean isolated, boolean keepIfLarge) { 2951 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2952 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2953 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2954 null /* crashHandler */); 2955 } 2956 2957 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2958 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2959 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2960 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2961 long startTime = SystemClock.elapsedRealtime(); 2962 ProcessRecord app; 2963 if (!isolated) { 2964 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2965 checkTime(startTime, "startProcess: after getProcessRecord"); 2966 } else { 2967 // If this is an isolated process, it can't re-use an existing process. 2968 app = null; 2969 } 2970 // We don't have to do anything more if: 2971 // (1) There is an existing application record; and 2972 // (2) The caller doesn't think it is dead, OR there is no thread 2973 // object attached to it so we know it couldn't have crashed; and 2974 // (3) There is a pid assigned to it, so it is either starting or 2975 // already running. 2976 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2977 + " app=" + app + " knownToBeDead=" + knownToBeDead 2978 + " thread=" + (app != null ? app.thread : null) 2979 + " pid=" + (app != null ? app.pid : -1)); 2980 if (app != null && app.pid > 0) { 2981 if (!knownToBeDead || app.thread == null) { 2982 // We already have the app running, or are waiting for it to 2983 // come up (we have a pid but not yet its thread), so keep it. 2984 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2985 // If this is a new package in the process, add the package to the list 2986 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2987 checkTime(startTime, "startProcess: done, added package to proc"); 2988 return app; 2989 } 2990 2991 // An application record is attached to a previous process, 2992 // clean it up now. 2993 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2994 checkTime(startTime, "startProcess: bad proc running, killing"); 2995 Process.killProcessGroup(app.info.uid, app.pid); 2996 handleAppDiedLocked(app, true, true); 2997 checkTime(startTime, "startProcess: done killing old proc"); 2998 } 2999 3000 String hostingNameStr = hostingName != null 3001 ? hostingName.flattenToShortString() : null; 3002 3003 if (!isolated) { 3004 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 3005 // If we are in the background, then check to see if this process 3006 // is bad. If so, we will just silently fail. 3007 if (mBadProcesses.get(info.processName, info.uid) != null) { 3008 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3009 + "/" + info.processName); 3010 return null; 3011 } 3012 } else { 3013 // When the user is explicitly starting a process, then clear its 3014 // crash count so that we won't make it bad until they see at 3015 // least one crash dialog again, and make the process good again 3016 // if it had been bad. 3017 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3018 + "/" + info.processName); 3019 mProcessCrashTimes.remove(info.processName, info.uid); 3020 if (mBadProcesses.get(info.processName, info.uid) != null) { 3021 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3022 UserHandle.getUserId(info.uid), info.uid, 3023 info.processName); 3024 mBadProcesses.remove(info.processName, info.uid); 3025 if (app != null) { 3026 app.bad = false; 3027 } 3028 } 3029 } 3030 } 3031 3032 if (app == null) { 3033 checkTime(startTime, "startProcess: creating new process record"); 3034 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3035 app.crashHandler = crashHandler; 3036 if (app == null) { 3037 Slog.w(TAG, "Failed making new process record for " 3038 + processName + "/" + info.uid + " isolated=" + isolated); 3039 return null; 3040 } 3041 mProcessNames.put(processName, app.uid, app); 3042 if (isolated) { 3043 mIsolatedProcesses.put(app.uid, app); 3044 } 3045 checkTime(startTime, "startProcess: done creating new process record"); 3046 } else { 3047 // If this is a new package in the process, add the package to the list 3048 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3049 checkTime(startTime, "startProcess: added package to existing proc"); 3050 } 3051 3052 // If the system is not ready yet, then hold off on starting this 3053 // process until it is. 3054 if (!mProcessesReady 3055 && !isAllowedWhileBooting(info) 3056 && !allowWhileBooting) { 3057 if (!mProcessesOnHold.contains(app)) { 3058 mProcessesOnHold.add(app); 3059 } 3060 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3061 checkTime(startTime, "startProcess: returning with proc on hold"); 3062 return app; 3063 } 3064 3065 checkTime(startTime, "startProcess: stepping in to startProcess"); 3066 startProcessLocked( 3067 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3068 checkTime(startTime, "startProcess: done starting proc!"); 3069 return (app.pid != 0) ? app : null; 3070 } 3071 3072 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3073 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3074 } 3075 3076 private final void startProcessLocked(ProcessRecord app, 3077 String hostingType, String hostingNameStr) { 3078 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3079 null /* entryPoint */, null /* entryPointArgs */); 3080 } 3081 3082 private final void startProcessLocked(ProcessRecord app, String hostingType, 3083 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3084 long startTime = SystemClock.elapsedRealtime(); 3085 if (app.pid > 0 && app.pid != MY_PID) { 3086 checkTime(startTime, "startProcess: removing from pids map"); 3087 synchronized (mPidsSelfLocked) { 3088 mPidsSelfLocked.remove(app.pid); 3089 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3090 } 3091 checkTime(startTime, "startProcess: done removing from pids map"); 3092 app.setPid(0); 3093 } 3094 3095 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3096 "startProcessLocked removing on hold: " + app); 3097 mProcessesOnHold.remove(app); 3098 3099 checkTime(startTime, "startProcess: starting to update cpu stats"); 3100 updateCpuStats(); 3101 checkTime(startTime, "startProcess: done updating cpu stats"); 3102 3103 try { 3104 int uid = app.uid; 3105 3106 int[] gids = null; 3107 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3108 if (!app.isolated) { 3109 int[] permGids = null; 3110 try { 3111 checkTime(startTime, "startProcess: getting gids from package manager"); 3112 final PackageManager pm = mContext.getPackageManager(); 3113 permGids = pm.getPackageGids(app.info.packageName); 3114 3115 if (Environment.isExternalStorageEmulated()) { 3116 checkTime(startTime, "startProcess: checking external storage perm"); 3117 if (pm.checkPermission( 3118 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3119 app.info.packageName) == PERMISSION_GRANTED) { 3120 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3121 } else { 3122 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3123 } 3124 } 3125 } catch (PackageManager.NameNotFoundException e) { 3126 Slog.w(TAG, "Unable to retrieve gids", e); 3127 } 3128 3129 /* 3130 * Add shared application and profile GIDs so applications can share some 3131 * resources like shared libraries and access user-wide resources 3132 */ 3133 if (permGids == null) { 3134 gids = new int[2]; 3135 } else { 3136 gids = new int[permGids.length + 2]; 3137 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3138 } 3139 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3140 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3141 } 3142 checkTime(startTime, "startProcess: building args"); 3143 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3144 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3145 && mTopComponent != null 3146 && app.processName.equals(mTopComponent.getPackageName())) { 3147 uid = 0; 3148 } 3149 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3150 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3151 uid = 0; 3152 } 3153 } 3154 int debugFlags = 0; 3155 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3156 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3157 // Also turn on CheckJNI for debuggable apps. It's quite 3158 // awkward to turn on otherwise. 3159 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3160 } 3161 // Run the app in safe mode if its manifest requests so or the 3162 // system is booted in safe mode. 3163 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3164 mSafeMode == true) { 3165 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3166 } 3167 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3168 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3169 } 3170 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3171 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3172 } 3173 if ("1".equals(SystemProperties.get("debug.assert"))) { 3174 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3175 } 3176 3177 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3178 if (requiredAbi == null) { 3179 requiredAbi = Build.SUPPORTED_ABIS[0]; 3180 } 3181 3182 String instructionSet = null; 3183 if (app.info.primaryCpuAbi != null) { 3184 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3185 } 3186 3187 // Start the process. It will either succeed and return a result containing 3188 // the PID of the new process, or else throw a RuntimeException. 3189 boolean isActivityProcess = (entryPoint == null); 3190 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3191 checkTime(startTime, "startProcess: asking zygote to start proc"); 3192 Process.ProcessStartResult startResult = Process.start(entryPoint, 3193 app.processName, uid, uid, gids, debugFlags, mountExternal, 3194 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3195 app.info.dataDir, entryPointArgs); 3196 checkTime(startTime, "startProcess: returned from zygote!"); 3197 3198 if (app.isolated) { 3199 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3200 } 3201 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3202 checkTime(startTime, "startProcess: done updating battery stats"); 3203 3204 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3205 UserHandle.getUserId(uid), startResult.pid, uid, 3206 app.processName, hostingType, 3207 hostingNameStr != null ? hostingNameStr : ""); 3208 3209 if (app.persistent) { 3210 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3211 } 3212 3213 checkTime(startTime, "startProcess: building log message"); 3214 StringBuilder buf = mStringBuilder; 3215 buf.setLength(0); 3216 buf.append("Start proc "); 3217 buf.append(app.processName); 3218 if (!isActivityProcess) { 3219 buf.append(" ["); 3220 buf.append(entryPoint); 3221 buf.append("]"); 3222 } 3223 buf.append(" for "); 3224 buf.append(hostingType); 3225 if (hostingNameStr != null) { 3226 buf.append(" "); 3227 buf.append(hostingNameStr); 3228 } 3229 buf.append(": pid="); 3230 buf.append(startResult.pid); 3231 buf.append(" uid="); 3232 buf.append(uid); 3233 buf.append(" gids={"); 3234 if (gids != null) { 3235 for (int gi=0; gi<gids.length; gi++) { 3236 if (gi != 0) buf.append(", "); 3237 buf.append(gids[gi]); 3238 3239 } 3240 } 3241 buf.append("}"); 3242 if (requiredAbi != null) { 3243 buf.append(" abi="); 3244 buf.append(requiredAbi); 3245 } 3246 Slog.i(TAG, buf.toString()); 3247 app.setPid(startResult.pid); 3248 app.usingWrapper = startResult.usingWrapper; 3249 app.removed = false; 3250 app.killed = false; 3251 app.killedByAm = false; 3252 checkTime(startTime, "startProcess: starting to update pids map"); 3253 synchronized (mPidsSelfLocked) { 3254 this.mPidsSelfLocked.put(startResult.pid, app); 3255 if (isActivityProcess) { 3256 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3257 msg.obj = app; 3258 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3259 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3260 } 3261 } 3262 checkTime(startTime, "startProcess: done updating pids map"); 3263 } catch (RuntimeException e) { 3264 // XXX do better error recovery. 3265 app.setPid(0); 3266 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3267 if (app.isolated) { 3268 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3269 } 3270 Slog.e(TAG, "Failure starting process " + app.processName, e); 3271 } 3272 } 3273 3274 void updateUsageStats(ActivityRecord component, boolean resumed) { 3275 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3276 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3277 if (resumed) { 3278 if (mUsageStatsService != null) { 3279 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3280 UsageEvents.Event.MOVE_TO_FOREGROUND); 3281 } 3282 synchronized (stats) { 3283 stats.noteActivityResumedLocked(component.app.uid); 3284 } 3285 } else { 3286 if (mUsageStatsService != null) { 3287 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3288 UsageEvents.Event.MOVE_TO_BACKGROUND); 3289 } 3290 synchronized (stats) { 3291 stats.noteActivityPausedLocked(component.app.uid); 3292 } 3293 } 3294 } 3295 3296 Intent getHomeIntent() { 3297 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3298 intent.setComponent(mTopComponent); 3299 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3300 intent.addCategory(Intent.CATEGORY_HOME); 3301 } 3302 return intent; 3303 } 3304 3305 boolean startHomeActivityLocked(int userId) { 3306 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3307 && mTopAction == null) { 3308 // We are running in factory test mode, but unable to find 3309 // the factory test app, so just sit around displaying the 3310 // error message and don't try to start anything. 3311 return false; 3312 } 3313 Intent intent = getHomeIntent(); 3314 ActivityInfo aInfo = 3315 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3316 if (aInfo != null) { 3317 intent.setComponent(new ComponentName( 3318 aInfo.applicationInfo.packageName, aInfo.name)); 3319 // Don't do this if the home app is currently being 3320 // instrumented. 3321 aInfo = new ActivityInfo(aInfo); 3322 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3323 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3324 aInfo.applicationInfo.uid, true); 3325 if (app == null || app.instrumentationClass == null) { 3326 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3327 mStackSupervisor.startHomeActivity(intent, aInfo); 3328 } 3329 } 3330 3331 return true; 3332 } 3333 3334 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3335 ActivityInfo ai = null; 3336 ComponentName comp = intent.getComponent(); 3337 try { 3338 if (comp != null) { 3339 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3340 } else { 3341 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3342 intent, 3343 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3344 flags, userId); 3345 3346 if (info != null) { 3347 ai = info.activityInfo; 3348 } 3349 } 3350 } catch (RemoteException e) { 3351 // ignore 3352 } 3353 3354 return ai; 3355 } 3356 3357 /** 3358 * Starts the "new version setup screen" if appropriate. 3359 */ 3360 void startSetupActivityLocked() { 3361 // Only do this once per boot. 3362 if (mCheckedForSetup) { 3363 return; 3364 } 3365 3366 // We will show this screen if the current one is a different 3367 // version than the last one shown, and we are not running in 3368 // low-level factory test mode. 3369 final ContentResolver resolver = mContext.getContentResolver(); 3370 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3371 Settings.Global.getInt(resolver, 3372 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3373 mCheckedForSetup = true; 3374 3375 // See if we should be showing the platform update setup UI. 3376 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3377 List<ResolveInfo> ris = mContext.getPackageManager() 3378 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3379 3380 // We don't allow third party apps to replace this. 3381 ResolveInfo ri = null; 3382 for (int i=0; ris != null && i<ris.size(); i++) { 3383 if ((ris.get(i).activityInfo.applicationInfo.flags 3384 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3385 ri = ris.get(i); 3386 break; 3387 } 3388 } 3389 3390 if (ri != null) { 3391 String vers = ri.activityInfo.metaData != null 3392 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3393 : null; 3394 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3395 vers = ri.activityInfo.applicationInfo.metaData.getString( 3396 Intent.METADATA_SETUP_VERSION); 3397 } 3398 String lastVers = Settings.Secure.getString( 3399 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3400 if (vers != null && !vers.equals(lastVers)) { 3401 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3402 intent.setComponent(new ComponentName( 3403 ri.activityInfo.packageName, ri.activityInfo.name)); 3404 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3405 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3406 null); 3407 } 3408 } 3409 } 3410 } 3411 3412 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3413 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3414 } 3415 3416 void enforceNotIsolatedCaller(String caller) { 3417 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3418 throw new SecurityException("Isolated process not allowed to call " + caller); 3419 } 3420 } 3421 3422 void enforceShellRestriction(String restriction, int userHandle) { 3423 if (Binder.getCallingUid() == Process.SHELL_UID) { 3424 if (userHandle < 0 3425 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3426 throw new SecurityException("Shell does not have permission to access user " 3427 + userHandle); 3428 } 3429 } 3430 } 3431 3432 @Override 3433 public int getFrontActivityScreenCompatMode() { 3434 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3435 synchronized (this) { 3436 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3437 } 3438 } 3439 3440 @Override 3441 public void setFrontActivityScreenCompatMode(int mode) { 3442 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3443 "setFrontActivityScreenCompatMode"); 3444 synchronized (this) { 3445 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3446 } 3447 } 3448 3449 @Override 3450 public int getPackageScreenCompatMode(String packageName) { 3451 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3452 synchronized (this) { 3453 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3454 } 3455 } 3456 3457 @Override 3458 public void setPackageScreenCompatMode(String packageName, int mode) { 3459 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3460 "setPackageScreenCompatMode"); 3461 synchronized (this) { 3462 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3463 } 3464 } 3465 3466 @Override 3467 public boolean getPackageAskScreenCompat(String packageName) { 3468 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3469 synchronized (this) { 3470 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3471 } 3472 } 3473 3474 @Override 3475 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3476 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3477 "setPackageAskScreenCompat"); 3478 synchronized (this) { 3479 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3480 } 3481 } 3482 3483 private void dispatchProcessesChanged() { 3484 int N; 3485 synchronized (this) { 3486 N = mPendingProcessChanges.size(); 3487 if (mActiveProcessChanges.length < N) { 3488 mActiveProcessChanges = new ProcessChangeItem[N]; 3489 } 3490 mPendingProcessChanges.toArray(mActiveProcessChanges); 3491 mAvailProcessChanges.addAll(mPendingProcessChanges); 3492 mPendingProcessChanges.clear(); 3493 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3494 } 3495 3496 int i = mProcessObservers.beginBroadcast(); 3497 while (i > 0) { 3498 i--; 3499 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3500 if (observer != null) { 3501 try { 3502 for (int j=0; j<N; j++) { 3503 ProcessChangeItem item = mActiveProcessChanges[j]; 3504 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3505 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3506 + item.pid + " uid=" + item.uid + ": " 3507 + item.foregroundActivities); 3508 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3509 item.foregroundActivities); 3510 } 3511 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3512 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3513 + item.pid + " uid=" + item.uid + ": " + item.processState); 3514 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3515 } 3516 } 3517 } catch (RemoteException e) { 3518 } 3519 } 3520 } 3521 mProcessObservers.finishBroadcast(); 3522 } 3523 3524 private void dispatchProcessDied(int pid, int uid) { 3525 int i = mProcessObservers.beginBroadcast(); 3526 while (i > 0) { 3527 i--; 3528 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3529 if (observer != null) { 3530 try { 3531 observer.onProcessDied(pid, uid); 3532 } catch (RemoteException e) { 3533 } 3534 } 3535 } 3536 mProcessObservers.finishBroadcast(); 3537 } 3538 3539 @Override 3540 public final int startActivity(IApplicationThread caller, String callingPackage, 3541 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3542 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3543 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3544 resultWho, requestCode, startFlags, profilerInfo, options, 3545 UserHandle.getCallingUserId()); 3546 } 3547 3548 @Override 3549 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3550 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3551 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3552 enforceNotIsolatedCaller("startActivity"); 3553 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3554 false, ALLOW_FULL_ONLY, "startActivity", null); 3555 // TODO: Switch to user app stacks here. 3556 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3557 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3558 profilerInfo, null, null, options, userId, null, null); 3559 } 3560 3561 @Override 3562 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3563 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3564 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3565 3566 // This is very dangerous -- it allows you to perform a start activity (including 3567 // permission grants) as any app that may launch one of your own activities. So 3568 // we will only allow this to be done from activities that are part of the core framework, 3569 // and then only when they are running as the system. 3570 final ActivityRecord sourceRecord; 3571 final int targetUid; 3572 final String targetPackage; 3573 synchronized (this) { 3574 if (resultTo == null) { 3575 throw new SecurityException("Must be called from an activity"); 3576 } 3577 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3578 if (sourceRecord == null) { 3579 throw new SecurityException("Called with bad activity token: " + resultTo); 3580 } 3581 if (!sourceRecord.info.packageName.equals("android")) { 3582 throw new SecurityException( 3583 "Must be called from an activity that is declared in the android package"); 3584 } 3585 if (sourceRecord.app == null) { 3586 throw new SecurityException("Called without a process attached to activity"); 3587 } 3588 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3589 // This is still okay, as long as this activity is running under the 3590 // uid of the original calling activity. 3591 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3592 throw new SecurityException( 3593 "Calling activity in uid " + sourceRecord.app.uid 3594 + " must be system uid or original calling uid " 3595 + sourceRecord.launchedFromUid); 3596 } 3597 } 3598 targetUid = sourceRecord.launchedFromUid; 3599 targetPackage = sourceRecord.launchedFromPackage; 3600 } 3601 3602 // TODO: Switch to user app stacks here. 3603 try { 3604 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3605 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3606 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3607 return ret; 3608 } catch (SecurityException e) { 3609 // XXX need to figure out how to propagate to original app. 3610 // A SecurityException here is generally actually a fault of the original 3611 // calling activity (such as a fairly granting permissions), so propagate it 3612 // back to them. 3613 /* 3614 StringBuilder msg = new StringBuilder(); 3615 msg.append("While launching"); 3616 msg.append(intent.toString()); 3617 msg.append(": "); 3618 msg.append(e.getMessage()); 3619 */ 3620 throw e; 3621 } 3622 } 3623 3624 @Override 3625 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3626 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3627 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3628 enforceNotIsolatedCaller("startActivityAndWait"); 3629 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3630 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3631 WaitResult res = new WaitResult(); 3632 // TODO: Switch to user app stacks here. 3633 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3634 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3635 options, userId, null, null); 3636 return res; 3637 } 3638 3639 @Override 3640 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3641 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3642 int startFlags, Configuration config, Bundle options, int userId) { 3643 enforceNotIsolatedCaller("startActivityWithConfig"); 3644 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3645 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3646 // TODO: Switch to user app stacks here. 3647 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3648 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3649 null, null, config, options, userId, null, null); 3650 return ret; 3651 } 3652 3653 @Override 3654 public int startActivityIntentSender(IApplicationThread caller, 3655 IntentSender intent, Intent fillInIntent, String resolvedType, 3656 IBinder resultTo, String resultWho, int requestCode, 3657 int flagsMask, int flagsValues, Bundle options) { 3658 enforceNotIsolatedCaller("startActivityIntentSender"); 3659 // Refuse possible leaked file descriptors 3660 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3661 throw new IllegalArgumentException("File descriptors passed in Intent"); 3662 } 3663 3664 IIntentSender sender = intent.getTarget(); 3665 if (!(sender instanceof PendingIntentRecord)) { 3666 throw new IllegalArgumentException("Bad PendingIntent object"); 3667 } 3668 3669 PendingIntentRecord pir = (PendingIntentRecord)sender; 3670 3671 synchronized (this) { 3672 // If this is coming from the currently resumed activity, it is 3673 // effectively saying that app switches are allowed at this point. 3674 final ActivityStack stack = getFocusedStack(); 3675 if (stack.mResumedActivity != null && 3676 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3677 mAppSwitchesAllowedTime = 0; 3678 } 3679 } 3680 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3681 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3682 return ret; 3683 } 3684 3685 @Override 3686 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3687 Intent intent, String resolvedType, IVoiceInteractionSession session, 3688 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3689 Bundle options, int userId) { 3690 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3691 != PackageManager.PERMISSION_GRANTED) { 3692 String msg = "Permission Denial: startVoiceActivity() from pid=" 3693 + Binder.getCallingPid() 3694 + ", uid=" + Binder.getCallingUid() 3695 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3696 Slog.w(TAG, msg); 3697 throw new SecurityException(msg); 3698 } 3699 if (session == null || interactor == null) { 3700 throw new NullPointerException("null session or interactor"); 3701 } 3702 userId = handleIncomingUser(callingPid, callingUid, userId, 3703 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3704 // TODO: Switch to user app stacks here. 3705 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3706 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3707 null, options, userId, null, null); 3708 } 3709 3710 @Override 3711 public boolean startNextMatchingActivity(IBinder callingActivity, 3712 Intent intent, Bundle options) { 3713 // Refuse possible leaked file descriptors 3714 if (intent != null && intent.hasFileDescriptors() == true) { 3715 throw new IllegalArgumentException("File descriptors passed in Intent"); 3716 } 3717 3718 synchronized (this) { 3719 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3720 if (r == null) { 3721 ActivityOptions.abort(options); 3722 return false; 3723 } 3724 if (r.app == null || r.app.thread == null) { 3725 // The caller is not running... d'oh! 3726 ActivityOptions.abort(options); 3727 return false; 3728 } 3729 intent = new Intent(intent); 3730 // The caller is not allowed to change the data. 3731 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3732 // And we are resetting to find the next component... 3733 intent.setComponent(null); 3734 3735 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3736 3737 ActivityInfo aInfo = null; 3738 try { 3739 List<ResolveInfo> resolves = 3740 AppGlobals.getPackageManager().queryIntentActivities( 3741 intent, r.resolvedType, 3742 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3743 UserHandle.getCallingUserId()); 3744 3745 // Look for the original activity in the list... 3746 final int N = resolves != null ? resolves.size() : 0; 3747 for (int i=0; i<N; i++) { 3748 ResolveInfo rInfo = resolves.get(i); 3749 if (rInfo.activityInfo.packageName.equals(r.packageName) 3750 && rInfo.activityInfo.name.equals(r.info.name)) { 3751 // We found the current one... the next matching is 3752 // after it. 3753 i++; 3754 if (i<N) { 3755 aInfo = resolves.get(i).activityInfo; 3756 } 3757 if (debug) { 3758 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3759 + "/" + r.info.name); 3760 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3761 + "/" + aInfo.name); 3762 } 3763 break; 3764 } 3765 } 3766 } catch (RemoteException e) { 3767 } 3768 3769 if (aInfo == null) { 3770 // Nobody who is next! 3771 ActivityOptions.abort(options); 3772 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3773 return false; 3774 } 3775 3776 intent.setComponent(new ComponentName( 3777 aInfo.applicationInfo.packageName, aInfo.name)); 3778 intent.setFlags(intent.getFlags()&~( 3779 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3780 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3781 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3782 Intent.FLAG_ACTIVITY_NEW_TASK)); 3783 3784 // Okay now we need to start the new activity, replacing the 3785 // currently running activity. This is a little tricky because 3786 // we want to start the new one as if the current one is finished, 3787 // but not finish the current one first so that there is no flicker. 3788 // And thus... 3789 final boolean wasFinishing = r.finishing; 3790 r.finishing = true; 3791 3792 // Propagate reply information over to the new activity. 3793 final ActivityRecord resultTo = r.resultTo; 3794 final String resultWho = r.resultWho; 3795 final int requestCode = r.requestCode; 3796 r.resultTo = null; 3797 if (resultTo != null) { 3798 resultTo.removeResultsLocked(r, resultWho, requestCode); 3799 } 3800 3801 final long origId = Binder.clearCallingIdentity(); 3802 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3803 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3804 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3805 -1, r.launchedFromUid, 0, options, false, null, null, null); 3806 Binder.restoreCallingIdentity(origId); 3807 3808 r.finishing = wasFinishing; 3809 if (res != ActivityManager.START_SUCCESS) { 3810 return false; 3811 } 3812 return true; 3813 } 3814 } 3815 3816 @Override 3817 public final int startActivityFromRecents(int taskId, Bundle options) { 3818 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3819 String msg = "Permission Denial: startActivityFromRecents called without " + 3820 START_TASKS_FROM_RECENTS; 3821 Slog.w(TAG, msg); 3822 throw new SecurityException(msg); 3823 } 3824 return startActivityFromRecentsInner(taskId, options); 3825 } 3826 3827 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3828 final TaskRecord task; 3829 final int callingUid; 3830 final String callingPackage; 3831 final Intent intent; 3832 final int userId; 3833 synchronized (this) { 3834 task = recentTaskForIdLocked(taskId); 3835 if (task == null) { 3836 throw new IllegalArgumentException("Task " + taskId + " not found."); 3837 } 3838 callingUid = task.mCallingUid; 3839 callingPackage = task.mCallingPackage; 3840 intent = task.intent; 3841 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3842 userId = task.userId; 3843 } 3844 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3845 options, userId, null, task); 3846 } 3847 3848 final int startActivityInPackage(int uid, String callingPackage, 3849 Intent intent, String resolvedType, IBinder resultTo, 3850 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3851 IActivityContainer container, TaskRecord inTask) { 3852 3853 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3854 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3855 3856 // TODO: Switch to user app stacks here. 3857 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3858 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3859 null, null, null, options, userId, container, inTask); 3860 return ret; 3861 } 3862 3863 @Override 3864 public final int startActivities(IApplicationThread caller, String callingPackage, 3865 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3866 int userId) { 3867 enforceNotIsolatedCaller("startActivities"); 3868 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3869 false, ALLOW_FULL_ONLY, "startActivity", null); 3870 // TODO: Switch to user app stacks here. 3871 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3872 resolvedTypes, resultTo, options, userId); 3873 return ret; 3874 } 3875 3876 final int startActivitiesInPackage(int uid, String callingPackage, 3877 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3878 Bundle options, int userId) { 3879 3880 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3881 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3882 // TODO: Switch to user app stacks here. 3883 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3884 resultTo, options, userId); 3885 return ret; 3886 } 3887 3888 //explicitly remove thd old information in mRecentTasks when removing existing user. 3889 private void removeRecentTasksForUserLocked(int userId) { 3890 if(userId <= 0) { 3891 Slog.i(TAG, "Can't remove recent task on user " + userId); 3892 return; 3893 } 3894 3895 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3896 TaskRecord tr = mRecentTasks.get(i); 3897 if (tr.userId == userId) { 3898 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3899 + " when finishing user" + userId); 3900 mRecentTasks.remove(i); 3901 tr.removedFromRecents(mTaskPersister); 3902 } 3903 } 3904 3905 // Remove tasks from persistent storage. 3906 mTaskPersister.wakeup(null, true); 3907 } 3908 3909 // Sort by taskId 3910 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3911 @Override 3912 public int compare(TaskRecord lhs, TaskRecord rhs) { 3913 return rhs.taskId - lhs.taskId; 3914 } 3915 }; 3916 3917 // Extract the affiliates of the chain containing mRecentTasks[start]. 3918 private int processNextAffiliateChain(int start) { 3919 final TaskRecord startTask = mRecentTasks.get(start); 3920 final int affiliateId = startTask.mAffiliatedTaskId; 3921 3922 // Quick identification of isolated tasks. I.e. those not launched behind. 3923 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3924 startTask.mNextAffiliate == null) { 3925 // There is still a slim chance that there are other tasks that point to this task 3926 // and that the chain is so messed up that this task no longer points to them but 3927 // the gain of this optimization outweighs the risk. 3928 startTask.inRecents = true; 3929 return start + 1; 3930 } 3931 3932 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3933 mTmpRecents.clear(); 3934 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3935 final TaskRecord task = mRecentTasks.get(i); 3936 if (task.mAffiliatedTaskId == affiliateId) { 3937 mRecentTasks.remove(i); 3938 mTmpRecents.add(task); 3939 } 3940 } 3941 3942 // Sort them all by taskId. That is the order they were create in and that order will 3943 // always be correct. 3944 Collections.sort(mTmpRecents, mTaskRecordComparator); 3945 3946 // Go through and fix up the linked list. 3947 // The first one is the end of the chain and has no next. 3948 final TaskRecord first = mTmpRecents.get(0); 3949 first.inRecents = true; 3950 if (first.mNextAffiliate != null) { 3951 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3952 first.setNextAffiliate(null); 3953 mTaskPersister.wakeup(first, false); 3954 } 3955 // Everything in the middle is doubly linked from next to prev. 3956 final int tmpSize = mTmpRecents.size(); 3957 for (int i = 0; i < tmpSize - 1; ++i) { 3958 final TaskRecord next = mTmpRecents.get(i); 3959 final TaskRecord prev = mTmpRecents.get(i + 1); 3960 if (next.mPrevAffiliate != prev) { 3961 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3962 " setting prev=" + prev); 3963 next.setPrevAffiliate(prev); 3964 mTaskPersister.wakeup(next, false); 3965 } 3966 if (prev.mNextAffiliate != next) { 3967 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3968 " setting next=" + next); 3969 prev.setNextAffiliate(next); 3970 mTaskPersister.wakeup(prev, false); 3971 } 3972 prev.inRecents = true; 3973 } 3974 // The last one is the beginning of the list and has no prev. 3975 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3976 if (last.mPrevAffiliate != null) { 3977 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3978 last.setPrevAffiliate(null); 3979 mTaskPersister.wakeup(last, false); 3980 } 3981 3982 // Insert the group back into mRecentTasks at start. 3983 mRecentTasks.addAll(start, mTmpRecents); 3984 3985 // Let the caller know where we left off. 3986 return start + tmpSize; 3987 } 3988 3989 /** 3990 * Update the recent tasks lists: make sure tasks should still be here (their 3991 * applications / activities still exist), update their availability, fixup ordering 3992 * of affiliations. 3993 */ 3994 void cleanupRecentTasksLocked(int userId) { 3995 if (mRecentTasks == null) { 3996 // Happens when called from the packagemanager broadcast before boot. 3997 return; 3998 } 3999 4000 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 4001 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 4002 final IPackageManager pm = AppGlobals.getPackageManager(); 4003 final ActivityInfo dummyAct = new ActivityInfo(); 4004 final ApplicationInfo dummyApp = new ApplicationInfo(); 4005 4006 int N = mRecentTasks.size(); 4007 4008 int[] users = userId == UserHandle.USER_ALL 4009 ? getUsersLocked() : new int[] { userId }; 4010 for (int user : users) { 4011 for (int i = 0; i < N; i++) { 4012 TaskRecord task = mRecentTasks.get(i); 4013 if (task.userId != user) { 4014 // Only look at tasks for the user ID of interest. 4015 continue; 4016 } 4017 if (task.autoRemoveRecents && task.getTopActivity() == null) { 4018 // This situation is broken, and we should just get rid of it now. 4019 mRecentTasks.remove(i); 4020 task.removedFromRecents(mTaskPersister); 4021 i--; 4022 N--; 4023 Slog.w(TAG, "Removing auto-remove without activity: " + task); 4024 continue; 4025 } 4026 // Check whether this activity is currently available. 4027 if (task.realActivity != null) { 4028 ActivityInfo ai = availActCache.get(task.realActivity); 4029 if (ai == null) { 4030 try { 4031 ai = pm.getActivityInfo(task.realActivity, 4032 PackageManager.GET_UNINSTALLED_PACKAGES 4033 | PackageManager.GET_DISABLED_COMPONENTS, user); 4034 } catch (RemoteException e) { 4035 // Will never happen. 4036 continue; 4037 } 4038 if (ai == null) { 4039 ai = dummyAct; 4040 } 4041 availActCache.put(task.realActivity, ai); 4042 } 4043 if (ai == dummyAct) { 4044 // This could be either because the activity no longer exists, or the 4045 // app is temporarily gone. For the former we want to remove the recents 4046 // entry; for the latter we want to mark it as unavailable. 4047 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4048 if (app == null) { 4049 try { 4050 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4051 PackageManager.GET_UNINSTALLED_PACKAGES 4052 | PackageManager.GET_DISABLED_COMPONENTS, user); 4053 } catch (RemoteException e) { 4054 // Will never happen. 4055 continue; 4056 } 4057 if (app == null) { 4058 app = dummyApp; 4059 } 4060 availAppCache.put(task.realActivity.getPackageName(), app); 4061 } 4062 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4063 // Doesn't exist any more! Good-bye. 4064 mRecentTasks.remove(i); 4065 task.removedFromRecents(mTaskPersister); 4066 i--; 4067 N--; 4068 Slog.w(TAG, "Removing no longer valid recent: " + task); 4069 continue; 4070 } else { 4071 // Otherwise just not available for now. 4072 if (task.isAvailable) { 4073 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4074 + task); 4075 } 4076 task.isAvailable = false; 4077 } 4078 } else { 4079 if (!ai.enabled || !ai.applicationInfo.enabled 4080 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4081 if (task.isAvailable) { 4082 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4083 + task + " (enabled=" + ai.enabled + "/" 4084 + ai.applicationInfo.enabled + " flags=" 4085 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4086 } 4087 task.isAvailable = false; 4088 } else { 4089 if (!task.isAvailable) { 4090 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4091 + task); 4092 } 4093 task.isAvailable = true; 4094 } 4095 } 4096 } 4097 } 4098 } 4099 4100 // Verify the affiliate chain for each task. 4101 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4102 } 4103 4104 mTmpRecents.clear(); 4105 // mRecentTasks is now in sorted, affiliated order. 4106 } 4107 4108 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4109 int N = mRecentTasks.size(); 4110 TaskRecord top = task; 4111 int topIndex = taskIndex; 4112 while (top.mNextAffiliate != null && topIndex > 0) { 4113 top = top.mNextAffiliate; 4114 topIndex--; 4115 } 4116 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4117 + topIndex + " from intial " + taskIndex); 4118 // Find the end of the chain, doing a sanity check along the way. 4119 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4120 int endIndex = topIndex; 4121 TaskRecord prev = top; 4122 while (endIndex < N) { 4123 TaskRecord cur = mRecentTasks.get(endIndex); 4124 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4125 + endIndex + " " + cur); 4126 if (cur == top) { 4127 // Verify start of the chain. 4128 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4129 Slog.wtf(TAG, "Bad chain @" + endIndex 4130 + ": first task has next affiliate: " + prev); 4131 sane = false; 4132 break; 4133 } 4134 } else { 4135 // Verify middle of the chain's next points back to the one before. 4136 if (cur.mNextAffiliate != prev 4137 || cur.mNextAffiliateTaskId != prev.taskId) { 4138 Slog.wtf(TAG, "Bad chain @" + endIndex 4139 + ": middle task " + cur + " @" + endIndex 4140 + " has bad next affiliate " 4141 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4142 + ", expected " + prev); 4143 sane = false; 4144 break; 4145 } 4146 } 4147 if (cur.mPrevAffiliateTaskId == -1) { 4148 // Chain ends here. 4149 if (cur.mPrevAffiliate != null) { 4150 Slog.wtf(TAG, "Bad chain @" + endIndex 4151 + ": last task " + cur + " has previous affiliate " 4152 + cur.mPrevAffiliate); 4153 sane = false; 4154 } 4155 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4156 break; 4157 } else { 4158 // Verify middle of the chain's prev points to a valid item. 4159 if (cur.mPrevAffiliate == null) { 4160 Slog.wtf(TAG, "Bad chain @" + endIndex 4161 + ": task " + cur + " has previous affiliate " 4162 + cur.mPrevAffiliate + " but should be id " 4163 + cur.mPrevAffiliate); 4164 sane = false; 4165 break; 4166 } 4167 } 4168 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4169 Slog.wtf(TAG, "Bad chain @" + endIndex 4170 + ": task " + cur + " has affiliated id " 4171 + cur.mAffiliatedTaskId + " but should be " 4172 + task.mAffiliatedTaskId); 4173 sane = false; 4174 break; 4175 } 4176 prev = cur; 4177 endIndex++; 4178 if (endIndex >= N) { 4179 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4180 + ": last task " + prev); 4181 sane = false; 4182 break; 4183 } 4184 } 4185 if (sane) { 4186 if (endIndex < taskIndex) { 4187 Slog.wtf(TAG, "Bad chain @" + endIndex 4188 + ": did not extend to task " + task + " @" + taskIndex); 4189 sane = false; 4190 } 4191 } 4192 if (sane) { 4193 // All looks good, we can just move all of the affiliated tasks 4194 // to the top. 4195 for (int i=topIndex; i<=endIndex; i++) { 4196 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4197 + " from " + i + " to " + (i-topIndex)); 4198 TaskRecord cur = mRecentTasks.remove(i); 4199 mRecentTasks.add(i-topIndex, cur); 4200 } 4201 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4202 + " to " + endIndex); 4203 return true; 4204 } 4205 4206 // Whoops, couldn't do it. 4207 return false; 4208 } 4209 4210 final void addRecentTaskLocked(TaskRecord task) { 4211 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4212 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4213 4214 int N = mRecentTasks.size(); 4215 // Quick case: check if the top-most recent task is the same. 4216 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4218 return; 4219 } 4220 // Another quick case: check if this is part of a set of affiliated 4221 // tasks that are at the top. 4222 if (isAffiliated && N > 0 && task.inRecents 4223 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4224 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4225 + " at top when adding " + task); 4226 return; 4227 } 4228 // Another quick case: never add voice sessions. 4229 if (task.voiceSession != null) { 4230 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4231 return; 4232 } 4233 4234 boolean needAffiliationFix = false; 4235 4236 // Slightly less quick case: the task is already in recents, so all we need 4237 // to do is move it. 4238 if (task.inRecents) { 4239 int taskIndex = mRecentTasks.indexOf(task); 4240 if (taskIndex >= 0) { 4241 if (!isAffiliated) { 4242 // Simple case: this is not an affiliated task, so we just move it to the front. 4243 mRecentTasks.remove(taskIndex); 4244 mRecentTasks.add(0, task); 4245 notifyTaskPersisterLocked(task, false); 4246 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4247 + " from " + taskIndex); 4248 return; 4249 } else { 4250 // More complicated: need to keep all affiliated tasks together. 4251 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4252 // All went well. 4253 return; 4254 } 4255 4256 // Uh oh... something bad in the affiliation chain, try to rebuild 4257 // everything and then go through our general path of adding a new task. 4258 needAffiliationFix = true; 4259 } 4260 } else { 4261 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4262 needAffiliationFix = true; 4263 } 4264 } 4265 4266 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4267 trimRecentsForTask(task, true); 4268 4269 N = mRecentTasks.size(); 4270 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4271 final TaskRecord tr = mRecentTasks.remove(N - 1); 4272 tr.removedFromRecents(mTaskPersister); 4273 N--; 4274 } 4275 task.inRecents = true; 4276 if (!isAffiliated || needAffiliationFix) { 4277 // If this is a simple non-affiliated task, or we had some failure trying to 4278 // handle it as part of an affilated task, then just place it at the top. 4279 mRecentTasks.add(0, task); 4280 } else if (isAffiliated) { 4281 // If this is a new affiliated task, then move all of the affiliated tasks 4282 // to the front and insert this new one. 4283 TaskRecord other = task.mNextAffiliate; 4284 if (other == null) { 4285 other = task.mPrevAffiliate; 4286 } 4287 if (other != null) { 4288 int otherIndex = mRecentTasks.indexOf(other); 4289 if (otherIndex >= 0) { 4290 // Insert new task at appropriate location. 4291 int taskIndex; 4292 if (other == task.mNextAffiliate) { 4293 // We found the index of our next affiliation, which is who is 4294 // before us in the list, so add after that point. 4295 taskIndex = otherIndex+1; 4296 } else { 4297 // We found the index of our previous affiliation, which is who is 4298 // after us in the list, so add at their position. 4299 taskIndex = otherIndex; 4300 } 4301 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4302 + taskIndex + ": " + task); 4303 mRecentTasks.add(taskIndex, task); 4304 4305 // Now move everything to the front. 4306 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4307 // All went well. 4308 return; 4309 } 4310 4311 // Uh oh... something bad in the affiliation chain, try to rebuild 4312 // everything and then go through our general path of adding a new task. 4313 needAffiliationFix = true; 4314 } else { 4315 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4316 + other); 4317 needAffiliationFix = true; 4318 } 4319 } else { 4320 if (DEBUG_RECENTS) Slog.d(TAG, 4321 "addRecent: adding affiliated task without next/prev:" + task); 4322 needAffiliationFix = true; 4323 } 4324 } 4325 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4326 4327 if (needAffiliationFix) { 4328 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4329 cleanupRecentTasksLocked(task.userId); 4330 } 4331 } 4332 4333 /** 4334 * If needed, remove oldest existing entries in recents that are for the same kind 4335 * of task as the given one. 4336 */ 4337 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4338 int N = mRecentTasks.size(); 4339 final Intent intent = task.intent; 4340 final boolean document = intent != null && intent.isDocument(); 4341 4342 int maxRecents = task.maxRecents - 1; 4343 for (int i=0; i<N; i++) { 4344 final TaskRecord tr = mRecentTasks.get(i); 4345 if (task != tr) { 4346 if (task.userId != tr.userId) { 4347 continue; 4348 } 4349 if (i > MAX_RECENT_BITMAPS) { 4350 tr.freeLastThumbnail(); 4351 } 4352 final Intent trIntent = tr.intent; 4353 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4354 (intent == null || !intent.filterEquals(trIntent))) { 4355 continue; 4356 } 4357 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4358 if (document && trIsDocument) { 4359 // These are the same document activity (not necessarily the same doc). 4360 if (maxRecents > 0) { 4361 --maxRecents; 4362 continue; 4363 } 4364 // Hit the maximum number of documents for this task. Fall through 4365 // and remove this document from recents. 4366 } else if (document || trIsDocument) { 4367 // Only one of these is a document. Not the droid we're looking for. 4368 continue; 4369 } 4370 } 4371 4372 if (!doTrim) { 4373 // If the caller is not actually asking for a trim, just tell them we reached 4374 // a point where the trim would happen. 4375 return i; 4376 } 4377 4378 // Either task and tr are the same or, their affinities match or their intents match 4379 // and neither of them is a document, or they are documents using the same activity 4380 // and their maxRecents has been reached. 4381 tr.disposeThumbnail(); 4382 mRecentTasks.remove(i); 4383 if (task != tr) { 4384 tr.removedFromRecents(mTaskPersister); 4385 } 4386 i--; 4387 N--; 4388 if (task.intent == null) { 4389 // If the new recent task we are adding is not fully 4390 // specified, then replace it with the existing recent task. 4391 task = tr; 4392 } 4393 notifyTaskPersisterLocked(tr, false); 4394 } 4395 4396 return -1; 4397 } 4398 4399 @Override 4400 public void reportActivityFullyDrawn(IBinder token) { 4401 synchronized (this) { 4402 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4403 if (r == null) { 4404 return; 4405 } 4406 r.reportFullyDrawnLocked(); 4407 } 4408 } 4409 4410 @Override 4411 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4412 synchronized (this) { 4413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4414 if (r == null) { 4415 return; 4416 } 4417 final long origId = Binder.clearCallingIdentity(); 4418 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4419 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4420 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4421 if (config != null) { 4422 r.frozenBeforeDestroy = true; 4423 if (!updateConfigurationLocked(config, r, false, false)) { 4424 mStackSupervisor.resumeTopActivitiesLocked(); 4425 } 4426 } 4427 Binder.restoreCallingIdentity(origId); 4428 } 4429 } 4430 4431 @Override 4432 public int getRequestedOrientation(IBinder token) { 4433 synchronized (this) { 4434 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4435 if (r == null) { 4436 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4437 } 4438 return mWindowManager.getAppOrientation(r.appToken); 4439 } 4440 } 4441 4442 /** 4443 * This is the internal entry point for handling Activity.finish(). 4444 * 4445 * @param token The Binder token referencing the Activity we want to finish. 4446 * @param resultCode Result code, if any, from this Activity. 4447 * @param resultData Result data (Intent), if any, from this Activity. 4448 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4449 * the root Activity in the task. 4450 * 4451 * @return Returns true if the activity successfully finished, or false if it is still running. 4452 */ 4453 @Override 4454 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4455 boolean finishTask) { 4456 // Refuse possible leaked file descriptors 4457 if (resultData != null && resultData.hasFileDescriptors() == true) { 4458 throw new IllegalArgumentException("File descriptors passed in Intent"); 4459 } 4460 4461 synchronized(this) { 4462 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4463 if (r == null) { 4464 return true; 4465 } 4466 // Keep track of the root activity of the task before we finish it 4467 TaskRecord tr = r.task; 4468 ActivityRecord rootR = tr.getRootActivity(); 4469 // Do not allow task to finish in Lock Task mode. 4470 if (tr == mStackSupervisor.mLockTaskModeTask) { 4471 if (rootR == r) { 4472 mStackSupervisor.showLockTaskToast(); 4473 return false; 4474 } 4475 } 4476 if (mController != null) { 4477 // Find the first activity that is not finishing. 4478 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4479 if (next != null) { 4480 // ask watcher if this is allowed 4481 boolean resumeOK = true; 4482 try { 4483 resumeOK = mController.activityResuming(next.packageName); 4484 } catch (RemoteException e) { 4485 mController = null; 4486 Watchdog.getInstance().setActivityController(null); 4487 } 4488 4489 if (!resumeOK) { 4490 return false; 4491 } 4492 } 4493 } 4494 final long origId = Binder.clearCallingIdentity(); 4495 try { 4496 boolean res; 4497 if (finishTask && r == rootR) { 4498 // If requested, remove the task that is associated to this activity only if it 4499 // was the root activity in the task. The result code and data is ignored because 4500 // we don't support returning them across task boundaries. 4501 res = removeTaskByIdLocked(tr.taskId, 0); 4502 } else { 4503 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4504 resultData, "app-request", true); 4505 } 4506 return res; 4507 } finally { 4508 Binder.restoreCallingIdentity(origId); 4509 } 4510 } 4511 } 4512 4513 @Override 4514 public final void finishHeavyWeightApp() { 4515 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4516 != PackageManager.PERMISSION_GRANTED) { 4517 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4518 + Binder.getCallingPid() 4519 + ", uid=" + Binder.getCallingUid() 4520 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4521 Slog.w(TAG, msg); 4522 throw new SecurityException(msg); 4523 } 4524 4525 synchronized(this) { 4526 if (mHeavyWeightProcess == null) { 4527 return; 4528 } 4529 4530 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4531 mHeavyWeightProcess.activities); 4532 for (int i=0; i<activities.size(); i++) { 4533 ActivityRecord r = activities.get(i); 4534 if (!r.finishing) { 4535 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4536 null, "finish-heavy", true); 4537 } 4538 } 4539 4540 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4541 mHeavyWeightProcess.userId, 0)); 4542 mHeavyWeightProcess = null; 4543 } 4544 } 4545 4546 @Override 4547 public void crashApplication(int uid, int initialPid, String packageName, 4548 String message) { 4549 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4550 != PackageManager.PERMISSION_GRANTED) { 4551 String msg = "Permission Denial: crashApplication() from pid=" 4552 + Binder.getCallingPid() 4553 + ", uid=" + Binder.getCallingUid() 4554 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4555 Slog.w(TAG, msg); 4556 throw new SecurityException(msg); 4557 } 4558 4559 synchronized(this) { 4560 ProcessRecord proc = null; 4561 4562 // Figure out which process to kill. We don't trust that initialPid 4563 // still has any relation to current pids, so must scan through the 4564 // list. 4565 synchronized (mPidsSelfLocked) { 4566 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4567 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4568 if (p.uid != uid) { 4569 continue; 4570 } 4571 if (p.pid == initialPid) { 4572 proc = p; 4573 break; 4574 } 4575 if (p.pkgList.containsKey(packageName)) { 4576 proc = p; 4577 } 4578 } 4579 } 4580 4581 if (proc == null) { 4582 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4583 + " initialPid=" + initialPid 4584 + " packageName=" + packageName); 4585 return; 4586 } 4587 4588 if (proc.thread != null) { 4589 if (proc.pid == Process.myPid()) { 4590 Log.w(TAG, "crashApplication: trying to crash self!"); 4591 return; 4592 } 4593 long ident = Binder.clearCallingIdentity(); 4594 try { 4595 proc.thread.scheduleCrash(message); 4596 } catch (RemoteException e) { 4597 } 4598 Binder.restoreCallingIdentity(ident); 4599 } 4600 } 4601 } 4602 4603 @Override 4604 public final void finishSubActivity(IBinder token, String resultWho, 4605 int requestCode) { 4606 synchronized(this) { 4607 final long origId = Binder.clearCallingIdentity(); 4608 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4609 if (r != null) { 4610 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4611 } 4612 Binder.restoreCallingIdentity(origId); 4613 } 4614 } 4615 4616 @Override 4617 public boolean finishActivityAffinity(IBinder token) { 4618 synchronized(this) { 4619 final long origId = Binder.clearCallingIdentity(); 4620 try { 4621 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4622 4623 ActivityRecord rootR = r.task.getRootActivity(); 4624 // Do not allow task to finish in Lock Task mode. 4625 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4626 if (rootR == r) { 4627 mStackSupervisor.showLockTaskToast(); 4628 return false; 4629 } 4630 } 4631 boolean res = false; 4632 if (r != null) { 4633 res = r.task.stack.finishActivityAffinityLocked(r); 4634 } 4635 return res; 4636 } finally { 4637 Binder.restoreCallingIdentity(origId); 4638 } 4639 } 4640 } 4641 4642 @Override 4643 public void finishVoiceTask(IVoiceInteractionSession session) { 4644 synchronized(this) { 4645 final long origId = Binder.clearCallingIdentity(); 4646 try { 4647 mStackSupervisor.finishVoiceTask(session); 4648 } finally { 4649 Binder.restoreCallingIdentity(origId); 4650 } 4651 } 4652 4653 } 4654 4655 @Override 4656 public boolean releaseActivityInstance(IBinder token) { 4657 synchronized(this) { 4658 final long origId = Binder.clearCallingIdentity(); 4659 try { 4660 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4661 if (r.task == null || r.task.stack == null) { 4662 return false; 4663 } 4664 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4665 } finally { 4666 Binder.restoreCallingIdentity(origId); 4667 } 4668 } 4669 } 4670 4671 @Override 4672 public void releaseSomeActivities(IApplicationThread appInt) { 4673 synchronized(this) { 4674 final long origId = Binder.clearCallingIdentity(); 4675 try { 4676 ProcessRecord app = getRecordForAppLocked(appInt); 4677 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4678 } finally { 4679 Binder.restoreCallingIdentity(origId); 4680 } 4681 } 4682 } 4683 4684 @Override 4685 public boolean willActivityBeVisible(IBinder token) { 4686 synchronized(this) { 4687 ActivityStack stack = ActivityRecord.getStackLocked(token); 4688 if (stack != null) { 4689 return stack.willActivityBeVisibleLocked(token); 4690 } 4691 return false; 4692 } 4693 } 4694 4695 @Override 4696 public void overridePendingTransition(IBinder token, String packageName, 4697 int enterAnim, int exitAnim) { 4698 synchronized(this) { 4699 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4700 if (self == null) { 4701 return; 4702 } 4703 4704 final long origId = Binder.clearCallingIdentity(); 4705 4706 if (self.state == ActivityState.RESUMED 4707 || self.state == ActivityState.PAUSING) { 4708 mWindowManager.overridePendingAppTransition(packageName, 4709 enterAnim, exitAnim, null); 4710 } 4711 4712 Binder.restoreCallingIdentity(origId); 4713 } 4714 } 4715 4716 /** 4717 * Main function for removing an existing process from the activity manager 4718 * as a result of that process going away. Clears out all connections 4719 * to the process. 4720 */ 4721 private final void handleAppDiedLocked(ProcessRecord app, 4722 boolean restarting, boolean allowRestart) { 4723 int pid = app.pid; 4724 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4725 if (!kept && !restarting) { 4726 removeLruProcessLocked(app); 4727 if (pid > 0) { 4728 ProcessList.remove(pid); 4729 } 4730 } 4731 4732 if (mProfileProc == app) { 4733 clearProfilerLocked(); 4734 } 4735 4736 // Remove this application's activities from active lists. 4737 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4738 4739 app.activities.clear(); 4740 4741 if (app.instrumentationClass != null) { 4742 Slog.w(TAG, "Crash of app " + app.processName 4743 + " running instrumentation " + app.instrumentationClass); 4744 Bundle info = new Bundle(); 4745 info.putString("shortMsg", "Process crashed."); 4746 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4747 } 4748 4749 if (!restarting) { 4750 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4751 // If there was nothing to resume, and we are not already 4752 // restarting this process, but there is a visible activity that 4753 // is hosted by the process... then make sure all visible 4754 // activities are running, taking care of restarting this 4755 // process. 4756 if (hasVisibleActivities) { 4757 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4758 } 4759 } 4760 } 4761 } 4762 4763 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4764 IBinder threadBinder = thread.asBinder(); 4765 // Find the application record. 4766 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4767 ProcessRecord rec = mLruProcesses.get(i); 4768 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4769 return i; 4770 } 4771 } 4772 return -1; 4773 } 4774 4775 final ProcessRecord getRecordForAppLocked( 4776 IApplicationThread thread) { 4777 if (thread == null) { 4778 return null; 4779 } 4780 4781 int appIndex = getLRURecordIndexForAppLocked(thread); 4782 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4783 } 4784 4785 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4786 // If there are no longer any background processes running, 4787 // and the app that died was not running instrumentation, 4788 // then tell everyone we are now low on memory. 4789 boolean haveBg = false; 4790 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4791 ProcessRecord rec = mLruProcesses.get(i); 4792 if (rec.thread != null 4793 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4794 haveBg = true; 4795 break; 4796 } 4797 } 4798 4799 if (!haveBg) { 4800 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4801 if (doReport) { 4802 long now = SystemClock.uptimeMillis(); 4803 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4804 doReport = false; 4805 } else { 4806 mLastMemUsageReportTime = now; 4807 } 4808 } 4809 final ArrayList<ProcessMemInfo> memInfos 4810 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4811 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4812 long now = SystemClock.uptimeMillis(); 4813 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4814 ProcessRecord rec = mLruProcesses.get(i); 4815 if (rec == dyingProc || rec.thread == null) { 4816 continue; 4817 } 4818 if (doReport) { 4819 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4820 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4821 } 4822 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4823 // The low memory report is overriding any current 4824 // state for a GC request. Make sure to do 4825 // heavy/important/visible/foreground processes first. 4826 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4827 rec.lastRequestedGc = 0; 4828 } else { 4829 rec.lastRequestedGc = rec.lastLowMemory; 4830 } 4831 rec.reportLowMemory = true; 4832 rec.lastLowMemory = now; 4833 mProcessesToGc.remove(rec); 4834 addProcessToGcListLocked(rec); 4835 } 4836 } 4837 if (doReport) { 4838 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4839 mHandler.sendMessage(msg); 4840 } 4841 scheduleAppGcsLocked(); 4842 } 4843 } 4844 4845 final void appDiedLocked(ProcessRecord app) { 4846 appDiedLocked(app, app.pid, app.thread); 4847 } 4848 4849 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4850 // First check if this ProcessRecord is actually active for the pid. 4851 synchronized (mPidsSelfLocked) { 4852 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4853 if (curProc != app) { 4854 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4855 return; 4856 } 4857 } 4858 4859 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4860 synchronized (stats) { 4861 stats.noteProcessDiedLocked(app.info.uid, pid); 4862 } 4863 4864 Process.killProcessQuiet(pid); 4865 Process.killProcessGroup(app.info.uid, pid); 4866 app.killed = true; 4867 4868 // Clean up already done if the process has been re-started. 4869 if (app.pid == pid && app.thread != null && 4870 app.thread.asBinder() == thread.asBinder()) { 4871 boolean doLowMem = app.instrumentationClass == null; 4872 boolean doOomAdj = doLowMem; 4873 if (!app.killedByAm) { 4874 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4875 + ") has died"); 4876 mAllowLowerMemLevel = true; 4877 } else { 4878 // Note that we always want to do oom adj to update our state with the 4879 // new number of procs. 4880 mAllowLowerMemLevel = false; 4881 doLowMem = false; 4882 } 4883 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4884 if (DEBUG_CLEANUP) Slog.v( 4885 TAG, "Dying app: " + app + ", pid: " + pid 4886 + ", thread: " + thread.asBinder()); 4887 handleAppDiedLocked(app, false, true); 4888 4889 if (doOomAdj) { 4890 updateOomAdjLocked(); 4891 } 4892 if (doLowMem) { 4893 doLowMemReportIfNeededLocked(app); 4894 } 4895 } else if (app.pid != pid) { 4896 // A new process has already been started. 4897 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4898 + ") has died and restarted (pid " + app.pid + ")."); 4899 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4900 } else if (DEBUG_PROCESSES) { 4901 Slog.d(TAG, "Received spurious death notification for thread " 4902 + thread.asBinder()); 4903 } 4904 } 4905 4906 /** 4907 * If a stack trace dump file is configured, dump process stack traces. 4908 * @param clearTraces causes the dump file to be erased prior to the new 4909 * traces being written, if true; when false, the new traces will be 4910 * appended to any existing file content. 4911 * @param firstPids of dalvik VM processes to dump stack traces for first 4912 * @param lastPids of dalvik VM processes to dump stack traces for last 4913 * @param nativeProcs optional list of native process names to dump stack crawls 4914 * @return file containing stack traces, or null if no dump file is configured 4915 */ 4916 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4917 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4918 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4919 if (tracesPath == null || tracesPath.length() == 0) { 4920 return null; 4921 } 4922 4923 File tracesFile = new File(tracesPath); 4924 try { 4925 File tracesDir = tracesFile.getParentFile(); 4926 if (!tracesDir.exists()) { 4927 tracesDir.mkdirs(); 4928 if (!SELinux.restorecon(tracesDir)) { 4929 return null; 4930 } 4931 } 4932 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4933 4934 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4935 tracesFile.createNewFile(); 4936 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4937 } catch (IOException e) { 4938 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4939 return null; 4940 } 4941 4942 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4943 return tracesFile; 4944 } 4945 4946 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4947 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4948 // Use a FileObserver to detect when traces finish writing. 4949 // The order of traces is considered important to maintain for legibility. 4950 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4951 @Override 4952 public synchronized void onEvent(int event, String path) { notify(); } 4953 }; 4954 4955 try { 4956 observer.startWatching(); 4957 4958 // First collect all of the stacks of the most important pids. 4959 if (firstPids != null) { 4960 try { 4961 int num = firstPids.size(); 4962 for (int i = 0; i < num; i++) { 4963 synchronized (observer) { 4964 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4965 observer.wait(200); // Wait for write-close, give up after 200msec 4966 } 4967 } 4968 } catch (InterruptedException e) { 4969 Slog.wtf(TAG, e); 4970 } 4971 } 4972 4973 // Next collect the stacks of the native pids 4974 if (nativeProcs != null) { 4975 int[] pids = Process.getPidsForCommands(nativeProcs); 4976 if (pids != null) { 4977 for (int pid : pids) { 4978 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4979 } 4980 } 4981 } 4982 4983 // Lastly, measure CPU usage. 4984 if (processCpuTracker != null) { 4985 processCpuTracker.init(); 4986 System.gc(); 4987 processCpuTracker.update(); 4988 try { 4989 synchronized (processCpuTracker) { 4990 processCpuTracker.wait(500); // measure over 1/2 second. 4991 } 4992 } catch (InterruptedException e) { 4993 } 4994 processCpuTracker.update(); 4995 4996 // We'll take the stack crawls of just the top apps using CPU. 4997 final int N = processCpuTracker.countWorkingStats(); 4998 int numProcs = 0; 4999 for (int i=0; i<N && numProcs<5; i++) { 5000 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5001 if (lastPids.indexOfKey(stats.pid) >= 0) { 5002 numProcs++; 5003 try { 5004 synchronized (observer) { 5005 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5006 observer.wait(200); // Wait for write-close, give up after 200msec 5007 } 5008 } catch (InterruptedException e) { 5009 Slog.wtf(TAG, e); 5010 } 5011 5012 } 5013 } 5014 } 5015 } finally { 5016 observer.stopWatching(); 5017 } 5018 } 5019 5020 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5021 if (true || IS_USER_BUILD) { 5022 return; 5023 } 5024 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5025 if (tracesPath == null || tracesPath.length() == 0) { 5026 return; 5027 } 5028 5029 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5030 StrictMode.allowThreadDiskWrites(); 5031 try { 5032 final File tracesFile = new File(tracesPath); 5033 final File tracesDir = tracesFile.getParentFile(); 5034 final File tracesTmp = new File(tracesDir, "__tmp__"); 5035 try { 5036 if (!tracesDir.exists()) { 5037 tracesDir.mkdirs(); 5038 if (!SELinux.restorecon(tracesDir.getPath())) { 5039 return; 5040 } 5041 } 5042 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5043 5044 if (tracesFile.exists()) { 5045 tracesTmp.delete(); 5046 tracesFile.renameTo(tracesTmp); 5047 } 5048 StringBuilder sb = new StringBuilder(); 5049 Time tobj = new Time(); 5050 tobj.set(System.currentTimeMillis()); 5051 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5052 sb.append(": "); 5053 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5054 sb.append(" since "); 5055 sb.append(msg); 5056 FileOutputStream fos = new FileOutputStream(tracesFile); 5057 fos.write(sb.toString().getBytes()); 5058 if (app == null) { 5059 fos.write("\n*** No application process!".getBytes()); 5060 } 5061 fos.close(); 5062 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5063 } catch (IOException e) { 5064 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5065 return; 5066 } 5067 5068 if (app != null) { 5069 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5070 firstPids.add(app.pid); 5071 dumpStackTraces(tracesPath, firstPids, null, null, null); 5072 } 5073 5074 File lastTracesFile = null; 5075 File curTracesFile = null; 5076 for (int i=9; i>=0; i--) { 5077 String name = String.format(Locale.US, "slow%02d.txt", i); 5078 curTracesFile = new File(tracesDir, name); 5079 if (curTracesFile.exists()) { 5080 if (lastTracesFile != null) { 5081 curTracesFile.renameTo(lastTracesFile); 5082 } else { 5083 curTracesFile.delete(); 5084 } 5085 } 5086 lastTracesFile = curTracesFile; 5087 } 5088 tracesFile.renameTo(curTracesFile); 5089 if (tracesTmp.exists()) { 5090 tracesTmp.renameTo(tracesFile); 5091 } 5092 } finally { 5093 StrictMode.setThreadPolicy(oldPolicy); 5094 } 5095 } 5096 5097 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5098 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5099 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5100 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5101 5102 if (mController != null) { 5103 try { 5104 // 0 == continue, -1 = kill process immediately 5105 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5106 if (res < 0 && app.pid != MY_PID) { 5107 app.kill("anr", true); 5108 } 5109 } catch (RemoteException e) { 5110 mController = null; 5111 Watchdog.getInstance().setActivityController(null); 5112 } 5113 } 5114 5115 long anrTime = SystemClock.uptimeMillis(); 5116 if (MONITOR_CPU_USAGE) { 5117 updateCpuStatsNow(); 5118 } 5119 5120 synchronized (this) { 5121 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5122 if (mShuttingDown) { 5123 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5124 return; 5125 } else if (app.notResponding) { 5126 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5127 return; 5128 } else if (app.crashing) { 5129 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5130 return; 5131 } 5132 5133 // In case we come through here for the same app before completing 5134 // this one, mark as anring now so we will bail out. 5135 app.notResponding = true; 5136 5137 // Log the ANR to the event log. 5138 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5139 app.processName, app.info.flags, annotation); 5140 5141 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5142 firstPids.add(app.pid); 5143 5144 int parentPid = app.pid; 5145 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5146 if (parentPid != app.pid) firstPids.add(parentPid); 5147 5148 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5149 5150 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5151 ProcessRecord r = mLruProcesses.get(i); 5152 if (r != null && r.thread != null) { 5153 int pid = r.pid; 5154 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5155 if (r.persistent) { 5156 firstPids.add(pid); 5157 } else { 5158 lastPids.put(pid, Boolean.TRUE); 5159 } 5160 } 5161 } 5162 } 5163 } 5164 5165 // Log the ANR to the main log. 5166 StringBuilder info = new StringBuilder(); 5167 info.setLength(0); 5168 info.append("ANR in ").append(app.processName); 5169 if (activity != null && activity.shortComponentName != null) { 5170 info.append(" (").append(activity.shortComponentName).append(")"); 5171 } 5172 info.append("\n"); 5173 info.append("PID: ").append(app.pid).append("\n"); 5174 if (annotation != null) { 5175 info.append("Reason: ").append(annotation).append("\n"); 5176 } 5177 if (parent != null && parent != activity) { 5178 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5179 } 5180 5181 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5182 5183 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5184 NATIVE_STACKS_OF_INTEREST); 5185 5186 String cpuInfo = null; 5187 if (MONITOR_CPU_USAGE) { 5188 updateCpuStatsNow(); 5189 synchronized (mProcessCpuTracker) { 5190 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5191 } 5192 info.append(processCpuTracker.printCurrentLoad()); 5193 info.append(cpuInfo); 5194 } 5195 5196 info.append(processCpuTracker.printCurrentState(anrTime)); 5197 5198 Slog.e(TAG, info.toString()); 5199 if (tracesFile == null) { 5200 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5201 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5202 } 5203 5204 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5205 cpuInfo, tracesFile, null); 5206 5207 if (mController != null) { 5208 try { 5209 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5210 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5211 if (res != 0) { 5212 if (res < 0 && app.pid != MY_PID) { 5213 app.kill("anr", true); 5214 } else { 5215 synchronized (this) { 5216 mServices.scheduleServiceTimeoutLocked(app); 5217 } 5218 } 5219 return; 5220 } 5221 } catch (RemoteException e) { 5222 mController = null; 5223 Watchdog.getInstance().setActivityController(null); 5224 } 5225 } 5226 5227 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5228 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5229 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5230 5231 synchronized (this) { 5232 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5233 app.kill("bg anr", true); 5234 return; 5235 } 5236 5237 // Set the app's notResponding state, and look up the errorReportReceiver 5238 makeAppNotRespondingLocked(app, 5239 activity != null ? activity.shortComponentName : null, 5240 annotation != null ? "ANR " + annotation : "ANR", 5241 info.toString()); 5242 5243 // Bring up the infamous App Not Responding dialog 5244 Message msg = Message.obtain(); 5245 HashMap<String, Object> map = new HashMap<String, Object>(); 5246 msg.what = SHOW_NOT_RESPONDING_MSG; 5247 msg.obj = map; 5248 msg.arg1 = aboveSystem ? 1 : 0; 5249 map.put("app", app); 5250 if (activity != null) { 5251 map.put("activity", activity); 5252 } 5253 5254 mHandler.sendMessage(msg); 5255 } 5256 } 5257 5258 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5259 if (!mLaunchWarningShown) { 5260 mLaunchWarningShown = true; 5261 mHandler.post(new Runnable() { 5262 @Override 5263 public void run() { 5264 synchronized (ActivityManagerService.this) { 5265 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5266 d.show(); 5267 mHandler.postDelayed(new Runnable() { 5268 @Override 5269 public void run() { 5270 synchronized (ActivityManagerService.this) { 5271 d.dismiss(); 5272 mLaunchWarningShown = false; 5273 } 5274 } 5275 }, 4000); 5276 } 5277 } 5278 }); 5279 } 5280 } 5281 5282 @Override 5283 public boolean clearApplicationUserData(final String packageName, 5284 final IPackageDataObserver observer, int userId) { 5285 enforceNotIsolatedCaller("clearApplicationUserData"); 5286 int uid = Binder.getCallingUid(); 5287 int pid = Binder.getCallingPid(); 5288 userId = handleIncomingUser(pid, uid, 5289 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5290 long callingId = Binder.clearCallingIdentity(); 5291 try { 5292 IPackageManager pm = AppGlobals.getPackageManager(); 5293 int pkgUid = -1; 5294 synchronized(this) { 5295 try { 5296 pkgUid = pm.getPackageUid(packageName, userId); 5297 } catch (RemoteException e) { 5298 } 5299 if (pkgUid == -1) { 5300 Slog.w(TAG, "Invalid packageName: " + packageName); 5301 if (observer != null) { 5302 try { 5303 observer.onRemoveCompleted(packageName, false); 5304 } catch (RemoteException e) { 5305 Slog.i(TAG, "Observer no longer exists."); 5306 } 5307 } 5308 return false; 5309 } 5310 if (uid == pkgUid || checkComponentPermission( 5311 android.Manifest.permission.CLEAR_APP_USER_DATA, 5312 pid, uid, -1, true) 5313 == PackageManager.PERMISSION_GRANTED) { 5314 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5315 } else { 5316 throw new SecurityException("PID " + pid + " does not have permission " 5317 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5318 + " of package " + packageName); 5319 } 5320 5321 // Remove all tasks match the cleared application package and user 5322 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5323 final TaskRecord tr = mRecentTasks.get(i); 5324 final String taskPackageName = 5325 tr.getBaseIntent().getComponent().getPackageName(); 5326 if (tr.userId != userId) continue; 5327 if (!taskPackageName.equals(packageName)) continue; 5328 removeTaskByIdLocked(tr.taskId, 0); 5329 } 5330 } 5331 5332 try { 5333 // Clear application user data 5334 pm.clearApplicationUserData(packageName, observer, userId); 5335 5336 synchronized(this) { 5337 // Remove all permissions granted from/to this package 5338 removeUriPermissionsForPackageLocked(packageName, userId, true); 5339 } 5340 5341 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5342 Uri.fromParts("package", packageName, null)); 5343 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5344 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5345 null, null, 0, null, null, null, false, false, userId); 5346 } catch (RemoteException e) { 5347 } 5348 } finally { 5349 Binder.restoreCallingIdentity(callingId); 5350 } 5351 return true; 5352 } 5353 5354 @Override 5355 public void killBackgroundProcesses(final String packageName, int userId) { 5356 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5357 != PackageManager.PERMISSION_GRANTED && 5358 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5359 != PackageManager.PERMISSION_GRANTED) { 5360 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5361 + Binder.getCallingPid() 5362 + ", uid=" + Binder.getCallingUid() 5363 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5364 Slog.w(TAG, msg); 5365 throw new SecurityException(msg); 5366 } 5367 5368 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5369 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5370 long callingId = Binder.clearCallingIdentity(); 5371 try { 5372 IPackageManager pm = AppGlobals.getPackageManager(); 5373 synchronized(this) { 5374 int appId = -1; 5375 try { 5376 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5377 } catch (RemoteException e) { 5378 } 5379 if (appId == -1) { 5380 Slog.w(TAG, "Invalid packageName: " + packageName); 5381 return; 5382 } 5383 killPackageProcessesLocked(packageName, appId, userId, 5384 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5385 } 5386 } finally { 5387 Binder.restoreCallingIdentity(callingId); 5388 } 5389 } 5390 5391 @Override 5392 public void killAllBackgroundProcesses() { 5393 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5394 != PackageManager.PERMISSION_GRANTED) { 5395 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5396 + Binder.getCallingPid() 5397 + ", uid=" + Binder.getCallingUid() 5398 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5399 Slog.w(TAG, msg); 5400 throw new SecurityException(msg); 5401 } 5402 5403 long callingId = Binder.clearCallingIdentity(); 5404 try { 5405 synchronized(this) { 5406 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5407 final int NP = mProcessNames.getMap().size(); 5408 for (int ip=0; ip<NP; ip++) { 5409 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5410 final int NA = apps.size(); 5411 for (int ia=0; ia<NA; ia++) { 5412 ProcessRecord app = apps.valueAt(ia); 5413 if (app.persistent) { 5414 // we don't kill persistent processes 5415 continue; 5416 } 5417 if (app.removed) { 5418 procs.add(app); 5419 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5420 app.removed = true; 5421 procs.add(app); 5422 } 5423 } 5424 } 5425 5426 int N = procs.size(); 5427 for (int i=0; i<N; i++) { 5428 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5429 } 5430 mAllowLowerMemLevel = true; 5431 updateOomAdjLocked(); 5432 doLowMemReportIfNeededLocked(null); 5433 } 5434 } finally { 5435 Binder.restoreCallingIdentity(callingId); 5436 } 5437 } 5438 5439 @Override 5440 public void forceStopPackage(final String packageName, int userId) { 5441 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5442 != PackageManager.PERMISSION_GRANTED) { 5443 String msg = "Permission Denial: forceStopPackage() from pid=" 5444 + Binder.getCallingPid() 5445 + ", uid=" + Binder.getCallingUid() 5446 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5447 Slog.w(TAG, msg); 5448 throw new SecurityException(msg); 5449 } 5450 final int callingPid = Binder.getCallingPid(); 5451 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5452 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5453 long callingId = Binder.clearCallingIdentity(); 5454 try { 5455 IPackageManager pm = AppGlobals.getPackageManager(); 5456 synchronized(this) { 5457 int[] users = userId == UserHandle.USER_ALL 5458 ? getUsersLocked() : new int[] { userId }; 5459 for (int user : users) { 5460 int pkgUid = -1; 5461 try { 5462 pkgUid = pm.getPackageUid(packageName, user); 5463 } catch (RemoteException e) { 5464 } 5465 if (pkgUid == -1) { 5466 Slog.w(TAG, "Invalid packageName: " + packageName); 5467 continue; 5468 } 5469 try { 5470 pm.setPackageStoppedState(packageName, true, user); 5471 } catch (RemoteException e) { 5472 } catch (IllegalArgumentException e) { 5473 Slog.w(TAG, "Failed trying to unstop package " 5474 + packageName + ": " + e); 5475 } 5476 if (isUserRunningLocked(user, false)) { 5477 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5478 } 5479 } 5480 } 5481 } finally { 5482 Binder.restoreCallingIdentity(callingId); 5483 } 5484 } 5485 5486 @Override 5487 public void addPackageDependency(String packageName) { 5488 synchronized (this) { 5489 int callingPid = Binder.getCallingPid(); 5490 if (callingPid == Process.myPid()) { 5491 // Yeah, um, no. 5492 Slog.w(TAG, "Can't addPackageDependency on system process"); 5493 return; 5494 } 5495 ProcessRecord proc; 5496 synchronized (mPidsSelfLocked) { 5497 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5498 } 5499 if (proc != null) { 5500 if (proc.pkgDeps == null) { 5501 proc.pkgDeps = new ArraySet<String>(1); 5502 } 5503 proc.pkgDeps.add(packageName); 5504 } 5505 } 5506 } 5507 5508 /* 5509 * The pkg name and app id have to be specified. 5510 */ 5511 @Override 5512 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5513 if (pkg == null) { 5514 return; 5515 } 5516 // Make sure the uid is valid. 5517 if (appid < 0) { 5518 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5519 return; 5520 } 5521 int callerUid = Binder.getCallingUid(); 5522 // Only the system server can kill an application 5523 if (callerUid == Process.SYSTEM_UID) { 5524 // Post an aysnc message to kill the application 5525 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5526 msg.arg1 = appid; 5527 msg.arg2 = 0; 5528 Bundle bundle = new Bundle(); 5529 bundle.putString("pkg", pkg); 5530 bundle.putString("reason", reason); 5531 msg.obj = bundle; 5532 mHandler.sendMessage(msg); 5533 } else { 5534 throw new SecurityException(callerUid + " cannot kill pkg: " + 5535 pkg); 5536 } 5537 } 5538 5539 @Override 5540 public void closeSystemDialogs(String reason) { 5541 enforceNotIsolatedCaller("closeSystemDialogs"); 5542 5543 final int pid = Binder.getCallingPid(); 5544 final int uid = Binder.getCallingUid(); 5545 final long origId = Binder.clearCallingIdentity(); 5546 try { 5547 synchronized (this) { 5548 // Only allow this from foreground processes, so that background 5549 // applications can't abuse it to prevent system UI from being shown. 5550 if (uid >= Process.FIRST_APPLICATION_UID) { 5551 ProcessRecord proc; 5552 synchronized (mPidsSelfLocked) { 5553 proc = mPidsSelfLocked.get(pid); 5554 } 5555 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5556 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5557 + " from background process " + proc); 5558 return; 5559 } 5560 } 5561 closeSystemDialogsLocked(reason); 5562 } 5563 } finally { 5564 Binder.restoreCallingIdentity(origId); 5565 } 5566 } 5567 5568 void closeSystemDialogsLocked(String reason) { 5569 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5570 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5571 | Intent.FLAG_RECEIVER_FOREGROUND); 5572 if (reason != null) { 5573 intent.putExtra("reason", reason); 5574 } 5575 mWindowManager.closeSystemDialogs(reason); 5576 5577 mStackSupervisor.closeSystemDialogsLocked(); 5578 5579 broadcastIntentLocked(null, null, intent, null, 5580 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5581 Process.SYSTEM_UID, UserHandle.USER_ALL); 5582 } 5583 5584 @Override 5585 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5586 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5587 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5588 for (int i=pids.length-1; i>=0; i--) { 5589 ProcessRecord proc; 5590 int oomAdj; 5591 synchronized (this) { 5592 synchronized (mPidsSelfLocked) { 5593 proc = mPidsSelfLocked.get(pids[i]); 5594 oomAdj = proc != null ? proc.setAdj : 0; 5595 } 5596 } 5597 infos[i] = new Debug.MemoryInfo(); 5598 Debug.getMemoryInfo(pids[i], infos[i]); 5599 if (proc != null) { 5600 synchronized (this) { 5601 if (proc.thread != null && proc.setAdj == oomAdj) { 5602 // Record this for posterity if the process has been stable. 5603 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5604 infos[i].getTotalUss(), false, proc.pkgList); 5605 } 5606 } 5607 } 5608 } 5609 return infos; 5610 } 5611 5612 @Override 5613 public long[] getProcessPss(int[] pids) { 5614 enforceNotIsolatedCaller("getProcessPss"); 5615 long[] pss = new long[pids.length]; 5616 for (int i=pids.length-1; i>=0; i--) { 5617 ProcessRecord proc; 5618 int oomAdj; 5619 synchronized (this) { 5620 synchronized (mPidsSelfLocked) { 5621 proc = mPidsSelfLocked.get(pids[i]); 5622 oomAdj = proc != null ? proc.setAdj : 0; 5623 } 5624 } 5625 long[] tmpUss = new long[1]; 5626 pss[i] = Debug.getPss(pids[i], tmpUss); 5627 if (proc != null) { 5628 synchronized (this) { 5629 if (proc.thread != null && proc.setAdj == oomAdj) { 5630 // Record this for posterity if the process has been stable. 5631 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5632 } 5633 } 5634 } 5635 } 5636 return pss; 5637 } 5638 5639 @Override 5640 public void killApplicationProcess(String processName, int uid) { 5641 if (processName == null) { 5642 return; 5643 } 5644 5645 int callerUid = Binder.getCallingUid(); 5646 // Only the system server can kill an application 5647 if (callerUid == Process.SYSTEM_UID) { 5648 synchronized (this) { 5649 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5650 if (app != null && app.thread != null) { 5651 try { 5652 app.thread.scheduleSuicide(); 5653 } catch (RemoteException e) { 5654 // If the other end already died, then our work here is done. 5655 } 5656 } else { 5657 Slog.w(TAG, "Process/uid not found attempting kill of " 5658 + processName + " / " + uid); 5659 } 5660 } 5661 } else { 5662 throw new SecurityException(callerUid + " cannot kill app process: " + 5663 processName); 5664 } 5665 } 5666 5667 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5668 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5669 false, true, false, false, UserHandle.getUserId(uid), reason); 5670 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5671 Uri.fromParts("package", packageName, null)); 5672 if (!mProcessesReady) { 5673 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5674 | Intent.FLAG_RECEIVER_FOREGROUND); 5675 } 5676 intent.putExtra(Intent.EXTRA_UID, uid); 5677 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5678 broadcastIntentLocked(null, null, intent, 5679 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5680 false, false, 5681 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5682 } 5683 5684 private void forceStopUserLocked(int userId, String reason) { 5685 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5686 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5687 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5688 | Intent.FLAG_RECEIVER_FOREGROUND); 5689 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5690 broadcastIntentLocked(null, null, intent, 5691 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5692 false, false, 5693 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5694 } 5695 5696 private final boolean killPackageProcessesLocked(String packageName, int appId, 5697 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5698 boolean doit, boolean evenPersistent, String reason) { 5699 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5700 5701 // Remove all processes this package may have touched: all with the 5702 // same UID (except for the system or root user), and all whose name 5703 // matches the package name. 5704 final int NP = mProcessNames.getMap().size(); 5705 for (int ip=0; ip<NP; ip++) { 5706 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5707 final int NA = apps.size(); 5708 for (int ia=0; ia<NA; ia++) { 5709 ProcessRecord app = apps.valueAt(ia); 5710 if (app.persistent && !evenPersistent) { 5711 // we don't kill persistent processes 5712 continue; 5713 } 5714 if (app.removed) { 5715 if (doit) { 5716 procs.add(app); 5717 } 5718 continue; 5719 } 5720 5721 // Skip process if it doesn't meet our oom adj requirement. 5722 if (app.setAdj < minOomAdj) { 5723 continue; 5724 } 5725 5726 // If no package is specified, we call all processes under the 5727 // give user id. 5728 if (packageName == null) { 5729 if (app.userId != userId) { 5730 continue; 5731 } 5732 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5733 continue; 5734 } 5735 // Package has been specified, we want to hit all processes 5736 // that match it. We need to qualify this by the processes 5737 // that are running under the specified app and user ID. 5738 } else { 5739 final boolean isDep = app.pkgDeps != null 5740 && app.pkgDeps.contains(packageName); 5741 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5742 continue; 5743 } 5744 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5745 continue; 5746 } 5747 if (!app.pkgList.containsKey(packageName) && !isDep) { 5748 continue; 5749 } 5750 } 5751 5752 // Process has passed all conditions, kill it! 5753 if (!doit) { 5754 return true; 5755 } 5756 app.removed = true; 5757 procs.add(app); 5758 } 5759 } 5760 5761 int N = procs.size(); 5762 for (int i=0; i<N; i++) { 5763 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5764 } 5765 updateOomAdjLocked(); 5766 return N > 0; 5767 } 5768 5769 private final boolean forceStopPackageLocked(String name, int appId, 5770 boolean callerWillRestart, boolean purgeCache, boolean doit, 5771 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5772 int i; 5773 int N; 5774 5775 if (userId == UserHandle.USER_ALL && name == null) { 5776 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5777 } 5778 5779 if (appId < 0 && name != null) { 5780 try { 5781 appId = UserHandle.getAppId( 5782 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5783 } catch (RemoteException e) { 5784 } 5785 } 5786 5787 if (doit) { 5788 if (name != null) { 5789 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5790 + " user=" + userId + ": " + reason); 5791 } else { 5792 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5793 } 5794 5795 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5796 for (int ip=pmap.size()-1; ip>=0; ip--) { 5797 SparseArray<Long> ba = pmap.valueAt(ip); 5798 for (i=ba.size()-1; i>=0; i--) { 5799 boolean remove = false; 5800 final int entUid = ba.keyAt(i); 5801 if (name != null) { 5802 if (userId == UserHandle.USER_ALL) { 5803 if (UserHandle.getAppId(entUid) == appId) { 5804 remove = true; 5805 } 5806 } else { 5807 if (entUid == UserHandle.getUid(userId, appId)) { 5808 remove = true; 5809 } 5810 } 5811 } else if (UserHandle.getUserId(entUid) == userId) { 5812 remove = true; 5813 } 5814 if (remove) { 5815 ba.removeAt(i); 5816 } 5817 } 5818 if (ba.size() == 0) { 5819 pmap.removeAt(ip); 5820 } 5821 } 5822 } 5823 5824 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5825 -100, callerWillRestart, true, doit, evenPersistent, 5826 name == null ? ("stop user " + userId) : ("stop " + name)); 5827 5828 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5829 if (!doit) { 5830 return true; 5831 } 5832 didSomething = true; 5833 } 5834 5835 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5836 if (!doit) { 5837 return true; 5838 } 5839 didSomething = true; 5840 } 5841 5842 if (name == null) { 5843 // Remove all sticky broadcasts from this user. 5844 mStickyBroadcasts.remove(userId); 5845 } 5846 5847 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5848 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5849 userId, providers)) { 5850 if (!doit) { 5851 return true; 5852 } 5853 didSomething = true; 5854 } 5855 N = providers.size(); 5856 for (i=0; i<N; i++) { 5857 removeDyingProviderLocked(null, providers.get(i), true); 5858 } 5859 5860 // Remove transient permissions granted from/to this package/user 5861 removeUriPermissionsForPackageLocked(name, userId, false); 5862 5863 if (name == null || uninstalling) { 5864 // Remove pending intents. For now we only do this when force 5865 // stopping users, because we have some problems when doing this 5866 // for packages -- app widgets are not currently cleaned up for 5867 // such packages, so they can be left with bad pending intents. 5868 if (mIntentSenderRecords.size() > 0) { 5869 Iterator<WeakReference<PendingIntentRecord>> it 5870 = mIntentSenderRecords.values().iterator(); 5871 while (it.hasNext()) { 5872 WeakReference<PendingIntentRecord> wpir = it.next(); 5873 if (wpir == null) { 5874 it.remove(); 5875 continue; 5876 } 5877 PendingIntentRecord pir = wpir.get(); 5878 if (pir == null) { 5879 it.remove(); 5880 continue; 5881 } 5882 if (name == null) { 5883 // Stopping user, remove all objects for the user. 5884 if (pir.key.userId != userId) { 5885 // Not the same user, skip it. 5886 continue; 5887 } 5888 } else { 5889 if (UserHandle.getAppId(pir.uid) != appId) { 5890 // Different app id, skip it. 5891 continue; 5892 } 5893 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5894 // Different user, skip it. 5895 continue; 5896 } 5897 if (!pir.key.packageName.equals(name)) { 5898 // Different package, skip it. 5899 continue; 5900 } 5901 } 5902 if (!doit) { 5903 return true; 5904 } 5905 didSomething = true; 5906 it.remove(); 5907 pir.canceled = true; 5908 if (pir.key.activity != null) { 5909 pir.key.activity.pendingResults.remove(pir.ref); 5910 } 5911 } 5912 } 5913 } 5914 5915 if (doit) { 5916 if (purgeCache && name != null) { 5917 AttributeCache ac = AttributeCache.instance(); 5918 if (ac != null) { 5919 ac.removePackage(name); 5920 } 5921 } 5922 if (mBooted) { 5923 mStackSupervisor.resumeTopActivitiesLocked(); 5924 mStackSupervisor.scheduleIdleLocked(); 5925 } 5926 } 5927 5928 return didSomething; 5929 } 5930 5931 private final boolean removeProcessLocked(ProcessRecord app, 5932 boolean callerWillRestart, boolean allowRestart, String reason) { 5933 final String name = app.processName; 5934 final int uid = app.uid; 5935 if (DEBUG_PROCESSES) Slog.d( 5936 TAG, "Force removing proc " + app.toShortString() + " (" + name 5937 + "/" + uid + ")"); 5938 5939 mProcessNames.remove(name, uid); 5940 mIsolatedProcesses.remove(app.uid); 5941 if (mHeavyWeightProcess == app) { 5942 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5943 mHeavyWeightProcess.userId, 0)); 5944 mHeavyWeightProcess = null; 5945 } 5946 boolean needRestart = false; 5947 if (app.pid > 0 && app.pid != MY_PID) { 5948 int pid = app.pid; 5949 synchronized (mPidsSelfLocked) { 5950 mPidsSelfLocked.remove(pid); 5951 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5952 } 5953 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5954 if (app.isolated) { 5955 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5956 } 5957 app.kill(reason, true); 5958 handleAppDiedLocked(app, true, allowRestart); 5959 removeLruProcessLocked(app); 5960 5961 if (app.persistent && !app.isolated) { 5962 if (!callerWillRestart) { 5963 addAppLocked(app.info, false, null /* ABI override */); 5964 } else { 5965 needRestart = true; 5966 } 5967 } 5968 } else { 5969 mRemovedProcesses.add(app); 5970 } 5971 5972 return needRestart; 5973 } 5974 5975 private final void processStartTimedOutLocked(ProcessRecord app) { 5976 final int pid = app.pid; 5977 boolean gone = false; 5978 synchronized (mPidsSelfLocked) { 5979 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5980 if (knownApp != null && knownApp.thread == null) { 5981 mPidsSelfLocked.remove(pid); 5982 gone = true; 5983 } 5984 } 5985 5986 if (gone) { 5987 Slog.w(TAG, "Process " + app + " failed to attach"); 5988 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5989 pid, app.uid, app.processName); 5990 mProcessNames.remove(app.processName, app.uid); 5991 mIsolatedProcesses.remove(app.uid); 5992 if (mHeavyWeightProcess == app) { 5993 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5994 mHeavyWeightProcess.userId, 0)); 5995 mHeavyWeightProcess = null; 5996 } 5997 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5998 if (app.isolated) { 5999 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6000 } 6001 // Take care of any launching providers waiting for this process. 6002 checkAppInLaunchingProvidersLocked(app, true); 6003 // Take care of any services that are waiting for the process. 6004 mServices.processStartTimedOutLocked(app); 6005 app.kill("start timeout", true); 6006 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6007 Slog.w(TAG, "Unattached app died before backup, skipping"); 6008 try { 6009 IBackupManager bm = IBackupManager.Stub.asInterface( 6010 ServiceManager.getService(Context.BACKUP_SERVICE)); 6011 bm.agentDisconnected(app.info.packageName); 6012 } catch (RemoteException e) { 6013 // Can't happen; the backup manager is local 6014 } 6015 } 6016 if (isPendingBroadcastProcessLocked(pid)) { 6017 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6018 skipPendingBroadcastLocked(pid); 6019 } 6020 } else { 6021 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6022 } 6023 } 6024 6025 private final boolean attachApplicationLocked(IApplicationThread thread, 6026 int pid) { 6027 6028 // Find the application record that is being attached... either via 6029 // the pid if we are running in multiple processes, or just pull the 6030 // next app record if we are emulating process with anonymous threads. 6031 ProcessRecord app; 6032 if (pid != MY_PID && pid >= 0) { 6033 synchronized (mPidsSelfLocked) { 6034 app = mPidsSelfLocked.get(pid); 6035 } 6036 } else { 6037 app = null; 6038 } 6039 6040 if (app == null) { 6041 Slog.w(TAG, "No pending application record for pid " + pid 6042 + " (IApplicationThread " + thread + "); dropping process"); 6043 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6044 if (pid > 0 && pid != MY_PID) { 6045 Process.killProcessQuiet(pid); 6046 //TODO: Process.killProcessGroup(app.info.uid, pid); 6047 } else { 6048 try { 6049 thread.scheduleExit(); 6050 } catch (Exception e) { 6051 // Ignore exceptions. 6052 } 6053 } 6054 return false; 6055 } 6056 6057 // If this application record is still attached to a previous 6058 // process, clean it up now. 6059 if (app.thread != null) { 6060 handleAppDiedLocked(app, true, true); 6061 } 6062 6063 // Tell the process all about itself. 6064 6065 if (localLOGV) Slog.v( 6066 TAG, "Binding process pid " + pid + " to record " + app); 6067 6068 final String processName = app.processName; 6069 try { 6070 AppDeathRecipient adr = new AppDeathRecipient( 6071 app, pid, thread); 6072 thread.asBinder().linkToDeath(adr, 0); 6073 app.deathRecipient = adr; 6074 } catch (RemoteException e) { 6075 app.resetPackageList(mProcessStats); 6076 startProcessLocked(app, "link fail", processName); 6077 return false; 6078 } 6079 6080 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6081 6082 app.makeActive(thread, mProcessStats); 6083 app.curAdj = app.setAdj = -100; 6084 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6085 app.forcingToForeground = null; 6086 updateProcessForegroundLocked(app, false, false); 6087 app.hasShownUi = false; 6088 app.debugging = false; 6089 app.cached = false; 6090 6091 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6092 6093 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6094 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6095 6096 if (!normalMode) { 6097 Slog.i(TAG, "Launching preboot mode app: " + app); 6098 } 6099 6100 if (localLOGV) Slog.v( 6101 TAG, "New app record " + app 6102 + " thread=" + thread.asBinder() + " pid=" + pid); 6103 try { 6104 int testMode = IApplicationThread.DEBUG_OFF; 6105 if (mDebugApp != null && mDebugApp.equals(processName)) { 6106 testMode = mWaitForDebugger 6107 ? IApplicationThread.DEBUG_WAIT 6108 : IApplicationThread.DEBUG_ON; 6109 app.debugging = true; 6110 if (mDebugTransient) { 6111 mDebugApp = mOrigDebugApp; 6112 mWaitForDebugger = mOrigWaitForDebugger; 6113 } 6114 } 6115 String profileFile = app.instrumentationProfileFile; 6116 ParcelFileDescriptor profileFd = null; 6117 int samplingInterval = 0; 6118 boolean profileAutoStop = false; 6119 if (mProfileApp != null && mProfileApp.equals(processName)) { 6120 mProfileProc = app; 6121 profileFile = mProfileFile; 6122 profileFd = mProfileFd; 6123 samplingInterval = mSamplingInterval; 6124 profileAutoStop = mAutoStopProfiler; 6125 } 6126 boolean enableOpenGlTrace = false; 6127 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6128 enableOpenGlTrace = true; 6129 mOpenGlTraceApp = null; 6130 } 6131 6132 // If the app is being launched for restore or full backup, set it up specially 6133 boolean isRestrictedBackupMode = false; 6134 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6135 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6136 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6137 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6138 } 6139 6140 ensurePackageDexOpt(app.instrumentationInfo != null 6141 ? app.instrumentationInfo.packageName 6142 : app.info.packageName); 6143 if (app.instrumentationClass != null) { 6144 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6145 } 6146 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6147 + processName + " with config " + mConfiguration); 6148 ApplicationInfo appInfo = app.instrumentationInfo != null 6149 ? app.instrumentationInfo : app.info; 6150 app.compat = compatibilityInfoForPackageLocked(appInfo); 6151 if (profileFd != null) { 6152 profileFd = profileFd.dup(); 6153 } 6154 ProfilerInfo profilerInfo = profileFile == null ? null 6155 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6156 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6157 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6158 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6159 isRestrictedBackupMode || !normalMode, app.persistent, 6160 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6161 mCoreSettingsObserver.getCoreSettingsLocked()); 6162 updateLruProcessLocked(app, false, null); 6163 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6164 } catch (Exception e) { 6165 // todo: Yikes! What should we do? For now we will try to 6166 // start another process, but that could easily get us in 6167 // an infinite loop of restarting processes... 6168 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6169 6170 app.resetPackageList(mProcessStats); 6171 app.unlinkDeathRecipient(); 6172 startProcessLocked(app, "bind fail", processName); 6173 return false; 6174 } 6175 6176 // Remove this record from the list of starting applications. 6177 mPersistentStartingProcesses.remove(app); 6178 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6179 "Attach application locked removing on hold: " + app); 6180 mProcessesOnHold.remove(app); 6181 6182 boolean badApp = false; 6183 boolean didSomething = false; 6184 6185 // See if the top visible activity is waiting to run in this process... 6186 if (normalMode) { 6187 try { 6188 if (mStackSupervisor.attachApplicationLocked(app)) { 6189 didSomething = true; 6190 } 6191 } catch (Exception e) { 6192 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6193 badApp = true; 6194 } 6195 } 6196 6197 // Find any services that should be running in this process... 6198 if (!badApp) { 6199 try { 6200 didSomething |= mServices.attachApplicationLocked(app, processName); 6201 } catch (Exception e) { 6202 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6203 badApp = true; 6204 } 6205 } 6206 6207 // Check if a next-broadcast receiver is in this process... 6208 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6209 try { 6210 didSomething |= sendPendingBroadcastsLocked(app); 6211 } catch (Exception e) { 6212 // If the app died trying to launch the receiver we declare it 'bad' 6213 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6214 badApp = true; 6215 } 6216 } 6217 6218 // Check whether the next backup agent is in this process... 6219 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6220 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6221 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6222 try { 6223 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6224 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6225 mBackupTarget.backupMode); 6226 } catch (Exception e) { 6227 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6228 badApp = true; 6229 } 6230 } 6231 6232 if (badApp) { 6233 app.kill("error during init", true); 6234 handleAppDiedLocked(app, false, true); 6235 return false; 6236 } 6237 6238 if (!didSomething) { 6239 updateOomAdjLocked(); 6240 } 6241 6242 return true; 6243 } 6244 6245 @Override 6246 public final void attachApplication(IApplicationThread thread) { 6247 synchronized (this) { 6248 int callingPid = Binder.getCallingPid(); 6249 final long origId = Binder.clearCallingIdentity(); 6250 attachApplicationLocked(thread, callingPid); 6251 Binder.restoreCallingIdentity(origId); 6252 } 6253 } 6254 6255 @Override 6256 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6257 final long origId = Binder.clearCallingIdentity(); 6258 synchronized (this) { 6259 ActivityStack stack = ActivityRecord.getStackLocked(token); 6260 if (stack != null) { 6261 ActivityRecord r = 6262 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6263 if (stopProfiling) { 6264 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6265 try { 6266 mProfileFd.close(); 6267 } catch (IOException e) { 6268 } 6269 clearProfilerLocked(); 6270 } 6271 } 6272 } 6273 } 6274 Binder.restoreCallingIdentity(origId); 6275 } 6276 6277 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6278 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6279 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6280 } 6281 6282 void enableScreenAfterBoot() { 6283 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6284 SystemClock.uptimeMillis()); 6285 mWindowManager.enableScreenAfterBoot(); 6286 6287 synchronized (this) { 6288 updateEventDispatchingLocked(); 6289 } 6290 } 6291 6292 @Override 6293 public void showBootMessage(final CharSequence msg, final boolean always) { 6294 enforceNotIsolatedCaller("showBootMessage"); 6295 mWindowManager.showBootMessage(msg, always); 6296 } 6297 6298 @Override 6299 public void keyguardWaitingForActivityDrawn() { 6300 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6301 final long token = Binder.clearCallingIdentity(); 6302 try { 6303 synchronized (this) { 6304 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6305 mWindowManager.keyguardWaitingForActivityDrawn(); 6306 if (mLockScreenShown) { 6307 mLockScreenShown = false; 6308 comeOutOfSleepIfNeededLocked(); 6309 } 6310 } 6311 } finally { 6312 Binder.restoreCallingIdentity(token); 6313 } 6314 } 6315 6316 final void finishBooting() { 6317 synchronized (this) { 6318 if (!mBootAnimationComplete) { 6319 mCallFinishBooting = true; 6320 return; 6321 } 6322 mCallFinishBooting = false; 6323 } 6324 6325 // Register receivers to handle package update events 6326 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6327 6328 // Let system services know. 6329 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6330 6331 synchronized (this) { 6332 // Ensure that any processes we had put on hold are now started 6333 // up. 6334 final int NP = mProcessesOnHold.size(); 6335 if (NP > 0) { 6336 ArrayList<ProcessRecord> procs = 6337 new ArrayList<ProcessRecord>(mProcessesOnHold); 6338 for (int ip=0; ip<NP; ip++) { 6339 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6340 + procs.get(ip)); 6341 startProcessLocked(procs.get(ip), "on-hold", null); 6342 } 6343 } 6344 6345 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6346 // Start looking for apps that are abusing wake locks. 6347 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6348 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6349 // Tell anyone interested that we are done booting! 6350 SystemProperties.set("sys.boot_completed", "1"); 6351 6352 // And trigger dev.bootcomplete if we are not showing encryption progress 6353 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6354 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6355 SystemProperties.set("dev.bootcomplete", "1"); 6356 } 6357 for (int i=0; i<mStartedUsers.size(); i++) { 6358 UserStartedState uss = mStartedUsers.valueAt(i); 6359 if (uss.mState == UserStartedState.STATE_BOOTING) { 6360 uss.mState = UserStartedState.STATE_RUNNING; 6361 final int userId = mStartedUsers.keyAt(i); 6362 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6363 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6364 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6365 broadcastIntentLocked(null, null, intent, null, 6366 new IIntentReceiver.Stub() { 6367 @Override 6368 public void performReceive(Intent intent, int resultCode, 6369 String data, Bundle extras, boolean ordered, 6370 boolean sticky, int sendingUser) { 6371 synchronized (ActivityManagerService.this) { 6372 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6373 true, false); 6374 } 6375 } 6376 }, 6377 0, null, null, 6378 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6379 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6380 userId); 6381 } 6382 } 6383 scheduleStartProfilesLocked(); 6384 } 6385 } 6386 } 6387 6388 @Override 6389 public void bootAnimationComplete() { 6390 final boolean callFinishBooting; 6391 synchronized (this) { 6392 callFinishBooting = mCallFinishBooting; 6393 mBootAnimationComplete = true; 6394 } 6395 if (callFinishBooting) { 6396 finishBooting(); 6397 } 6398 } 6399 6400 final void ensureBootCompleted() { 6401 boolean booting; 6402 boolean enableScreen; 6403 synchronized (this) { 6404 booting = mBooting; 6405 mBooting = false; 6406 enableScreen = !mBooted; 6407 mBooted = true; 6408 } 6409 6410 if (booting) { 6411 finishBooting(); 6412 } 6413 6414 if (enableScreen) { 6415 enableScreenAfterBoot(); 6416 } 6417 } 6418 6419 @Override 6420 public final void activityResumed(IBinder token) { 6421 final long origId = Binder.clearCallingIdentity(); 6422 synchronized(this) { 6423 ActivityStack stack = ActivityRecord.getStackLocked(token); 6424 if (stack != null) { 6425 ActivityRecord.activityResumedLocked(token); 6426 } 6427 } 6428 Binder.restoreCallingIdentity(origId); 6429 } 6430 6431 @Override 6432 public final void activityPaused(IBinder token) { 6433 final long origId = Binder.clearCallingIdentity(); 6434 synchronized(this) { 6435 ActivityStack stack = ActivityRecord.getStackLocked(token); 6436 if (stack != null) { 6437 stack.activityPausedLocked(token, false); 6438 } 6439 } 6440 Binder.restoreCallingIdentity(origId); 6441 } 6442 6443 @Override 6444 public final void activityStopped(IBinder token, Bundle icicle, 6445 PersistableBundle persistentState, CharSequence description) { 6446 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6447 6448 // Refuse possible leaked file descriptors 6449 if (icicle != null && icicle.hasFileDescriptors()) { 6450 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6451 } 6452 6453 final long origId = Binder.clearCallingIdentity(); 6454 6455 synchronized (this) { 6456 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6457 if (r != null) { 6458 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6459 } 6460 } 6461 6462 trimApplications(); 6463 6464 Binder.restoreCallingIdentity(origId); 6465 } 6466 6467 @Override 6468 public final void activityDestroyed(IBinder token) { 6469 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6470 synchronized (this) { 6471 ActivityStack stack = ActivityRecord.getStackLocked(token); 6472 if (stack != null) { 6473 stack.activityDestroyedLocked(token); 6474 } 6475 } 6476 } 6477 6478 @Override 6479 public final void backgroundResourcesReleased(IBinder token) { 6480 final long origId = Binder.clearCallingIdentity(); 6481 try { 6482 synchronized (this) { 6483 ActivityStack stack = ActivityRecord.getStackLocked(token); 6484 if (stack != null) { 6485 stack.backgroundResourcesReleased(token); 6486 } 6487 } 6488 } finally { 6489 Binder.restoreCallingIdentity(origId); 6490 } 6491 } 6492 6493 @Override 6494 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6495 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6496 } 6497 6498 @Override 6499 public final void notifyEnterAnimationComplete(IBinder token) { 6500 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6501 } 6502 6503 @Override 6504 public String getCallingPackage(IBinder token) { 6505 synchronized (this) { 6506 ActivityRecord r = getCallingRecordLocked(token); 6507 return r != null ? r.info.packageName : null; 6508 } 6509 } 6510 6511 @Override 6512 public ComponentName getCallingActivity(IBinder token) { 6513 synchronized (this) { 6514 ActivityRecord r = getCallingRecordLocked(token); 6515 return r != null ? r.intent.getComponent() : null; 6516 } 6517 } 6518 6519 private ActivityRecord getCallingRecordLocked(IBinder token) { 6520 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6521 if (r == null) { 6522 return null; 6523 } 6524 return r.resultTo; 6525 } 6526 6527 @Override 6528 public ComponentName getActivityClassForToken(IBinder token) { 6529 synchronized(this) { 6530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6531 if (r == null) { 6532 return null; 6533 } 6534 return r.intent.getComponent(); 6535 } 6536 } 6537 6538 @Override 6539 public String getPackageForToken(IBinder token) { 6540 synchronized(this) { 6541 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6542 if (r == null) { 6543 return null; 6544 } 6545 return r.packageName; 6546 } 6547 } 6548 6549 @Override 6550 public IIntentSender getIntentSender(int type, 6551 String packageName, IBinder token, String resultWho, 6552 int requestCode, Intent[] intents, String[] resolvedTypes, 6553 int flags, Bundle options, int userId) { 6554 enforceNotIsolatedCaller("getIntentSender"); 6555 // Refuse possible leaked file descriptors 6556 if (intents != null) { 6557 if (intents.length < 1) { 6558 throw new IllegalArgumentException("Intents array length must be >= 1"); 6559 } 6560 for (int i=0; i<intents.length; i++) { 6561 Intent intent = intents[i]; 6562 if (intent != null) { 6563 if (intent.hasFileDescriptors()) { 6564 throw new IllegalArgumentException("File descriptors passed in Intent"); 6565 } 6566 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6567 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6568 throw new IllegalArgumentException( 6569 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6570 } 6571 intents[i] = new Intent(intent); 6572 } 6573 } 6574 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6575 throw new IllegalArgumentException( 6576 "Intent array length does not match resolvedTypes length"); 6577 } 6578 } 6579 if (options != null) { 6580 if (options.hasFileDescriptors()) { 6581 throw new IllegalArgumentException("File descriptors passed in options"); 6582 } 6583 } 6584 6585 synchronized(this) { 6586 int callingUid = Binder.getCallingUid(); 6587 int origUserId = userId; 6588 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6589 type == ActivityManager.INTENT_SENDER_BROADCAST, 6590 ALLOW_NON_FULL, "getIntentSender", null); 6591 if (origUserId == UserHandle.USER_CURRENT) { 6592 // We don't want to evaluate this until the pending intent is 6593 // actually executed. However, we do want to always do the 6594 // security checking for it above. 6595 userId = UserHandle.USER_CURRENT; 6596 } 6597 try { 6598 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6599 int uid = AppGlobals.getPackageManager() 6600 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6601 if (!UserHandle.isSameApp(callingUid, uid)) { 6602 String msg = "Permission Denial: getIntentSender() from pid=" 6603 + Binder.getCallingPid() 6604 + ", uid=" + Binder.getCallingUid() 6605 + ", (need uid=" + uid + ")" 6606 + " is not allowed to send as package " + packageName; 6607 Slog.w(TAG, msg); 6608 throw new SecurityException(msg); 6609 } 6610 } 6611 6612 return getIntentSenderLocked(type, packageName, callingUid, userId, 6613 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6614 6615 } catch (RemoteException e) { 6616 throw new SecurityException(e); 6617 } 6618 } 6619 } 6620 6621 IIntentSender getIntentSenderLocked(int type, String packageName, 6622 int callingUid, int userId, IBinder token, String resultWho, 6623 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6624 Bundle options) { 6625 if (DEBUG_MU) 6626 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6627 ActivityRecord activity = null; 6628 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6629 activity = ActivityRecord.isInStackLocked(token); 6630 if (activity == null) { 6631 return null; 6632 } 6633 if (activity.finishing) { 6634 return null; 6635 } 6636 } 6637 6638 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6639 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6640 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6641 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6642 |PendingIntent.FLAG_UPDATE_CURRENT); 6643 6644 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6645 type, packageName, activity, resultWho, 6646 requestCode, intents, resolvedTypes, flags, options, userId); 6647 WeakReference<PendingIntentRecord> ref; 6648 ref = mIntentSenderRecords.get(key); 6649 PendingIntentRecord rec = ref != null ? ref.get() : null; 6650 if (rec != null) { 6651 if (!cancelCurrent) { 6652 if (updateCurrent) { 6653 if (rec.key.requestIntent != null) { 6654 rec.key.requestIntent.replaceExtras(intents != null ? 6655 intents[intents.length - 1] : null); 6656 } 6657 if (intents != null) { 6658 intents[intents.length-1] = rec.key.requestIntent; 6659 rec.key.allIntents = intents; 6660 rec.key.allResolvedTypes = resolvedTypes; 6661 } else { 6662 rec.key.allIntents = null; 6663 rec.key.allResolvedTypes = null; 6664 } 6665 } 6666 return rec; 6667 } 6668 rec.canceled = true; 6669 mIntentSenderRecords.remove(key); 6670 } 6671 if (noCreate) { 6672 return rec; 6673 } 6674 rec = new PendingIntentRecord(this, key, callingUid); 6675 mIntentSenderRecords.put(key, rec.ref); 6676 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6677 if (activity.pendingResults == null) { 6678 activity.pendingResults 6679 = new HashSet<WeakReference<PendingIntentRecord>>(); 6680 } 6681 activity.pendingResults.add(rec.ref); 6682 } 6683 return rec; 6684 } 6685 6686 @Override 6687 public void cancelIntentSender(IIntentSender sender) { 6688 if (!(sender instanceof PendingIntentRecord)) { 6689 return; 6690 } 6691 synchronized(this) { 6692 PendingIntentRecord rec = (PendingIntentRecord)sender; 6693 try { 6694 int uid = AppGlobals.getPackageManager() 6695 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6696 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6697 String msg = "Permission Denial: cancelIntentSender() from pid=" 6698 + Binder.getCallingPid() 6699 + ", uid=" + Binder.getCallingUid() 6700 + " is not allowed to cancel packges " 6701 + rec.key.packageName; 6702 Slog.w(TAG, msg); 6703 throw new SecurityException(msg); 6704 } 6705 } catch (RemoteException e) { 6706 throw new SecurityException(e); 6707 } 6708 cancelIntentSenderLocked(rec, true); 6709 } 6710 } 6711 6712 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6713 rec.canceled = true; 6714 mIntentSenderRecords.remove(rec.key); 6715 if (cleanActivity && rec.key.activity != null) { 6716 rec.key.activity.pendingResults.remove(rec.ref); 6717 } 6718 } 6719 6720 @Override 6721 public String getPackageForIntentSender(IIntentSender pendingResult) { 6722 if (!(pendingResult instanceof PendingIntentRecord)) { 6723 return null; 6724 } 6725 try { 6726 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6727 return res.key.packageName; 6728 } catch (ClassCastException e) { 6729 } 6730 return null; 6731 } 6732 6733 @Override 6734 public int getUidForIntentSender(IIntentSender sender) { 6735 if (sender instanceof PendingIntentRecord) { 6736 try { 6737 PendingIntentRecord res = (PendingIntentRecord)sender; 6738 return res.uid; 6739 } catch (ClassCastException e) { 6740 } 6741 } 6742 return -1; 6743 } 6744 6745 @Override 6746 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6747 if (!(pendingResult instanceof PendingIntentRecord)) { 6748 return false; 6749 } 6750 try { 6751 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6752 if (res.key.allIntents == null) { 6753 return false; 6754 } 6755 for (int i=0; i<res.key.allIntents.length; i++) { 6756 Intent intent = res.key.allIntents[i]; 6757 if (intent.getPackage() != null && intent.getComponent() != null) { 6758 return false; 6759 } 6760 } 6761 return true; 6762 } catch (ClassCastException e) { 6763 } 6764 return false; 6765 } 6766 6767 @Override 6768 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6769 if (!(pendingResult instanceof PendingIntentRecord)) { 6770 return false; 6771 } 6772 try { 6773 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6774 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6775 return true; 6776 } 6777 return false; 6778 } catch (ClassCastException e) { 6779 } 6780 return false; 6781 } 6782 6783 @Override 6784 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6785 if (!(pendingResult instanceof PendingIntentRecord)) { 6786 return null; 6787 } 6788 try { 6789 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6790 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6791 } catch (ClassCastException e) { 6792 } 6793 return null; 6794 } 6795 6796 @Override 6797 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6798 if (!(pendingResult instanceof PendingIntentRecord)) { 6799 return null; 6800 } 6801 try { 6802 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6803 Intent intent = res.key.requestIntent; 6804 if (intent != null) { 6805 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6806 || res.lastTagPrefix.equals(prefix))) { 6807 return res.lastTag; 6808 } 6809 res.lastTagPrefix = prefix; 6810 StringBuilder sb = new StringBuilder(128); 6811 if (prefix != null) { 6812 sb.append(prefix); 6813 } 6814 if (intent.getAction() != null) { 6815 sb.append(intent.getAction()); 6816 } else if (intent.getComponent() != null) { 6817 intent.getComponent().appendShortString(sb); 6818 } else { 6819 sb.append("?"); 6820 } 6821 return res.lastTag = sb.toString(); 6822 } 6823 } catch (ClassCastException e) { 6824 } 6825 return null; 6826 } 6827 6828 @Override 6829 public void setProcessLimit(int max) { 6830 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6831 "setProcessLimit()"); 6832 synchronized (this) { 6833 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6834 mProcessLimitOverride = max; 6835 } 6836 trimApplications(); 6837 } 6838 6839 @Override 6840 public int getProcessLimit() { 6841 synchronized (this) { 6842 return mProcessLimitOverride; 6843 } 6844 } 6845 6846 void foregroundTokenDied(ForegroundToken token) { 6847 synchronized (ActivityManagerService.this) { 6848 synchronized (mPidsSelfLocked) { 6849 ForegroundToken cur 6850 = mForegroundProcesses.get(token.pid); 6851 if (cur != token) { 6852 return; 6853 } 6854 mForegroundProcesses.remove(token.pid); 6855 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6856 if (pr == null) { 6857 return; 6858 } 6859 pr.forcingToForeground = null; 6860 updateProcessForegroundLocked(pr, false, false); 6861 } 6862 updateOomAdjLocked(); 6863 } 6864 } 6865 6866 @Override 6867 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6868 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6869 "setProcessForeground()"); 6870 synchronized(this) { 6871 boolean changed = false; 6872 6873 synchronized (mPidsSelfLocked) { 6874 ProcessRecord pr = mPidsSelfLocked.get(pid); 6875 if (pr == null && isForeground) { 6876 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6877 return; 6878 } 6879 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6880 if (oldToken != null) { 6881 oldToken.token.unlinkToDeath(oldToken, 0); 6882 mForegroundProcesses.remove(pid); 6883 if (pr != null) { 6884 pr.forcingToForeground = null; 6885 } 6886 changed = true; 6887 } 6888 if (isForeground && token != null) { 6889 ForegroundToken newToken = new ForegroundToken() { 6890 @Override 6891 public void binderDied() { 6892 foregroundTokenDied(this); 6893 } 6894 }; 6895 newToken.pid = pid; 6896 newToken.token = token; 6897 try { 6898 token.linkToDeath(newToken, 0); 6899 mForegroundProcesses.put(pid, newToken); 6900 pr.forcingToForeground = token; 6901 changed = true; 6902 } catch (RemoteException e) { 6903 // If the process died while doing this, we will later 6904 // do the cleanup with the process death link. 6905 } 6906 } 6907 } 6908 6909 if (changed) { 6910 updateOomAdjLocked(); 6911 } 6912 } 6913 } 6914 6915 // ========================================================= 6916 // PERMISSIONS 6917 // ========================================================= 6918 6919 static class PermissionController extends IPermissionController.Stub { 6920 ActivityManagerService mActivityManagerService; 6921 PermissionController(ActivityManagerService activityManagerService) { 6922 mActivityManagerService = activityManagerService; 6923 } 6924 6925 @Override 6926 public boolean checkPermission(String permission, int pid, int uid) { 6927 return mActivityManagerService.checkPermission(permission, pid, 6928 uid) == PackageManager.PERMISSION_GRANTED; 6929 } 6930 } 6931 6932 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6933 @Override 6934 public int checkComponentPermission(String permission, int pid, int uid, 6935 int owningUid, boolean exported) { 6936 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6937 owningUid, exported); 6938 } 6939 6940 @Override 6941 public Object getAMSLock() { 6942 return ActivityManagerService.this; 6943 } 6944 } 6945 6946 /** 6947 * This can be called with or without the global lock held. 6948 */ 6949 int checkComponentPermission(String permission, int pid, int uid, 6950 int owningUid, boolean exported) { 6951 // We might be performing an operation on behalf of an indirect binder 6952 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6953 // client identity accordingly before proceeding. 6954 Identity tlsIdentity = sCallerIdentity.get(); 6955 if (tlsIdentity != null) { 6956 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6957 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6958 uid = tlsIdentity.uid; 6959 pid = tlsIdentity.pid; 6960 } 6961 6962 if (pid == MY_PID) { 6963 return PackageManager.PERMISSION_GRANTED; 6964 } 6965 6966 return ActivityManager.checkComponentPermission(permission, uid, 6967 owningUid, exported); 6968 } 6969 6970 /** 6971 * As the only public entry point for permissions checking, this method 6972 * can enforce the semantic that requesting a check on a null global 6973 * permission is automatically denied. (Internally a null permission 6974 * string is used when calling {@link #checkComponentPermission} in cases 6975 * when only uid-based security is needed.) 6976 * 6977 * This can be called with or without the global lock held. 6978 */ 6979 @Override 6980 public int checkPermission(String permission, int pid, int uid) { 6981 if (permission == null) { 6982 return PackageManager.PERMISSION_DENIED; 6983 } 6984 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6985 } 6986 6987 /** 6988 * Binder IPC calls go through the public entry point. 6989 * This can be called with or without the global lock held. 6990 */ 6991 int checkCallingPermission(String permission) { 6992 return checkPermission(permission, 6993 Binder.getCallingPid(), 6994 UserHandle.getAppId(Binder.getCallingUid())); 6995 } 6996 6997 /** 6998 * This can be called with or without the global lock held. 6999 */ 7000 void enforceCallingPermission(String permission, String func) { 7001 if (checkCallingPermission(permission) 7002 == PackageManager.PERMISSION_GRANTED) { 7003 return; 7004 } 7005 7006 String msg = "Permission Denial: " + func + " from pid=" 7007 + Binder.getCallingPid() 7008 + ", uid=" + Binder.getCallingUid() 7009 + " requires " + permission; 7010 Slog.w(TAG, msg); 7011 throw new SecurityException(msg); 7012 } 7013 7014 /** 7015 * Determine if UID is holding permissions required to access {@link Uri} in 7016 * the given {@link ProviderInfo}. Final permission checking is always done 7017 * in {@link ContentProvider}. 7018 */ 7019 private final boolean checkHoldingPermissionsLocked( 7020 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 7021 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7022 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 7023 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 7024 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 7025 != PERMISSION_GRANTED) { 7026 return false; 7027 } 7028 } 7029 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 7030 } 7031 7032 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7033 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7034 if (pi.applicationInfo.uid == uid) { 7035 return true; 7036 } else if (!pi.exported) { 7037 return false; 7038 } 7039 7040 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7041 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7042 try { 7043 // check if target holds top-level <provider> permissions 7044 if (!readMet && pi.readPermission != null && considerUidPermissions 7045 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7046 readMet = true; 7047 } 7048 if (!writeMet && pi.writePermission != null && considerUidPermissions 7049 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7050 writeMet = true; 7051 } 7052 7053 // track if unprotected read/write is allowed; any denied 7054 // <path-permission> below removes this ability 7055 boolean allowDefaultRead = pi.readPermission == null; 7056 boolean allowDefaultWrite = pi.writePermission == null; 7057 7058 // check if target holds any <path-permission> that match uri 7059 final PathPermission[] pps = pi.pathPermissions; 7060 if (pps != null) { 7061 final String path = grantUri.uri.getPath(); 7062 int i = pps.length; 7063 while (i > 0 && (!readMet || !writeMet)) { 7064 i--; 7065 PathPermission pp = pps[i]; 7066 if (pp.match(path)) { 7067 if (!readMet) { 7068 final String pprperm = pp.getReadPermission(); 7069 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7070 + pprperm + " for " + pp.getPath() 7071 + ": match=" + pp.match(path) 7072 + " check=" + pm.checkUidPermission(pprperm, uid)); 7073 if (pprperm != null) { 7074 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7075 == PERMISSION_GRANTED) { 7076 readMet = true; 7077 } else { 7078 allowDefaultRead = false; 7079 } 7080 } 7081 } 7082 if (!writeMet) { 7083 final String ppwperm = pp.getWritePermission(); 7084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7085 + ppwperm + " for " + pp.getPath() 7086 + ": match=" + pp.match(path) 7087 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7088 if (ppwperm != null) { 7089 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7090 == PERMISSION_GRANTED) { 7091 writeMet = true; 7092 } else { 7093 allowDefaultWrite = false; 7094 } 7095 } 7096 } 7097 } 7098 } 7099 } 7100 7101 // grant unprotected <provider> read/write, if not blocked by 7102 // <path-permission> above 7103 if (allowDefaultRead) readMet = true; 7104 if (allowDefaultWrite) writeMet = true; 7105 7106 } catch (RemoteException e) { 7107 return false; 7108 } 7109 7110 return readMet && writeMet; 7111 } 7112 7113 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7114 ProviderInfo pi = null; 7115 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7116 if (cpr != null) { 7117 pi = cpr.info; 7118 } else { 7119 try { 7120 pi = AppGlobals.getPackageManager().resolveContentProvider( 7121 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7122 } catch (RemoteException ex) { 7123 } 7124 } 7125 return pi; 7126 } 7127 7128 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7129 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7130 if (targetUris != null) { 7131 return targetUris.get(grantUri); 7132 } 7133 return null; 7134 } 7135 7136 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7137 String targetPkg, int targetUid, GrantUri grantUri) { 7138 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7139 if (targetUris == null) { 7140 targetUris = Maps.newArrayMap(); 7141 mGrantedUriPermissions.put(targetUid, targetUris); 7142 } 7143 7144 UriPermission perm = targetUris.get(grantUri); 7145 if (perm == null) { 7146 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7147 targetUris.put(grantUri, perm); 7148 } 7149 7150 return perm; 7151 } 7152 7153 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7154 final int modeFlags) { 7155 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7156 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7157 : UriPermission.STRENGTH_OWNED; 7158 7159 // Root gets to do everything. 7160 if (uid == 0) { 7161 return true; 7162 } 7163 7164 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7165 if (perms == null) return false; 7166 7167 // First look for exact match 7168 final UriPermission exactPerm = perms.get(grantUri); 7169 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7170 return true; 7171 } 7172 7173 // No exact match, look for prefixes 7174 final int N = perms.size(); 7175 for (int i = 0; i < N; i++) { 7176 final UriPermission perm = perms.valueAt(i); 7177 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7178 && perm.getStrength(modeFlags) >= minStrength) { 7179 return true; 7180 } 7181 } 7182 7183 return false; 7184 } 7185 7186 /** 7187 * @param uri This uri must NOT contain an embedded userId. 7188 * @param userId The userId in which the uri is to be resolved. 7189 */ 7190 @Override 7191 public int checkUriPermission(Uri uri, int pid, int uid, 7192 final int modeFlags, int userId) { 7193 enforceNotIsolatedCaller("checkUriPermission"); 7194 7195 // Another redirected-binder-call permissions check as in 7196 // {@link checkComponentPermission}. 7197 Identity tlsIdentity = sCallerIdentity.get(); 7198 if (tlsIdentity != null) { 7199 uid = tlsIdentity.uid; 7200 pid = tlsIdentity.pid; 7201 } 7202 7203 // Our own process gets to do everything. 7204 if (pid == MY_PID) { 7205 return PackageManager.PERMISSION_GRANTED; 7206 } 7207 synchronized (this) { 7208 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7209 ? PackageManager.PERMISSION_GRANTED 7210 : PackageManager.PERMISSION_DENIED; 7211 } 7212 } 7213 7214 /** 7215 * Check if the targetPkg can be granted permission to access uri by 7216 * the callingUid using the given modeFlags. Throws a security exception 7217 * if callingUid is not allowed to do this. Returns the uid of the target 7218 * if the URI permission grant should be performed; returns -1 if it is not 7219 * needed (for example targetPkg already has permission to access the URI). 7220 * If you already know the uid of the target, you can supply it in 7221 * lastTargetUid else set that to -1. 7222 */ 7223 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7224 final int modeFlags, int lastTargetUid) { 7225 if (!Intent.isAccessUriMode(modeFlags)) { 7226 return -1; 7227 } 7228 7229 if (targetPkg != null) { 7230 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7231 "Checking grant " + targetPkg + " permission to " + grantUri); 7232 } 7233 7234 final IPackageManager pm = AppGlobals.getPackageManager(); 7235 7236 // If this is not a content: uri, we can't do anything with it. 7237 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7238 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7239 "Can't grant URI permission for non-content URI: " + grantUri); 7240 return -1; 7241 } 7242 7243 final String authority = grantUri.uri.getAuthority(); 7244 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7245 if (pi == null) { 7246 Slog.w(TAG, "No content provider found for permission check: " + 7247 grantUri.uri.toSafeString()); 7248 return -1; 7249 } 7250 7251 int targetUid = lastTargetUid; 7252 if (targetUid < 0 && targetPkg != null) { 7253 try { 7254 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7255 if (targetUid < 0) { 7256 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7257 "Can't grant URI permission no uid for: " + targetPkg); 7258 return -1; 7259 } 7260 } catch (RemoteException ex) { 7261 return -1; 7262 } 7263 } 7264 7265 if (targetUid >= 0) { 7266 // First... does the target actually need this permission? 7267 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7268 // No need to grant the target this permission. 7269 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7270 "Target " + targetPkg + " already has full permission to " + grantUri); 7271 return -1; 7272 } 7273 } else { 7274 // First... there is no target package, so can anyone access it? 7275 boolean allowed = pi.exported; 7276 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7277 if (pi.readPermission != null) { 7278 allowed = false; 7279 } 7280 } 7281 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7282 if (pi.writePermission != null) { 7283 allowed = false; 7284 } 7285 } 7286 if (allowed) { 7287 return -1; 7288 } 7289 } 7290 7291 /* There is a special cross user grant if: 7292 * - The target is on another user. 7293 * - Apps on the current user can access the uri without any uid permissions. 7294 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7295 * grant uri permissions. 7296 */ 7297 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7298 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7299 modeFlags, false /*without considering the uid permissions*/); 7300 7301 // Second... is the provider allowing granting of URI permissions? 7302 if (!specialCrossUserGrant) { 7303 if (!pi.grantUriPermissions) { 7304 throw new SecurityException("Provider " + pi.packageName 7305 + "/" + pi.name 7306 + " does not allow granting of Uri permissions (uri " 7307 + grantUri + ")"); 7308 } 7309 if (pi.uriPermissionPatterns != null) { 7310 final int N = pi.uriPermissionPatterns.length; 7311 boolean allowed = false; 7312 for (int i=0; i<N; i++) { 7313 if (pi.uriPermissionPatterns[i] != null 7314 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7315 allowed = true; 7316 break; 7317 } 7318 } 7319 if (!allowed) { 7320 throw new SecurityException("Provider " + pi.packageName 7321 + "/" + pi.name 7322 + " does not allow granting of permission to path of Uri " 7323 + grantUri); 7324 } 7325 } 7326 } 7327 7328 // Third... does the caller itself have permission to access 7329 // this uri? 7330 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7331 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7332 // Require they hold a strong enough Uri permission 7333 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7334 throw new SecurityException("Uid " + callingUid 7335 + " does not have permission to uri " + grantUri); 7336 } 7337 } 7338 } 7339 return targetUid; 7340 } 7341 7342 /** 7343 * @param uri This uri must NOT contain an embedded userId. 7344 * @param userId The userId in which the uri is to be resolved. 7345 */ 7346 @Override 7347 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7348 final int modeFlags, int userId) { 7349 enforceNotIsolatedCaller("checkGrantUriPermission"); 7350 synchronized(this) { 7351 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7352 new GrantUri(userId, uri, false), modeFlags, -1); 7353 } 7354 } 7355 7356 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7357 final int modeFlags, UriPermissionOwner owner) { 7358 if (!Intent.isAccessUriMode(modeFlags)) { 7359 return; 7360 } 7361 7362 // So here we are: the caller has the assumed permission 7363 // to the uri, and the target doesn't. Let's now give this to 7364 // the target. 7365 7366 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7367 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7368 7369 final String authority = grantUri.uri.getAuthority(); 7370 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7371 if (pi == null) { 7372 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7373 return; 7374 } 7375 7376 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7377 grantUri.prefix = true; 7378 } 7379 final UriPermission perm = findOrCreateUriPermissionLocked( 7380 pi.packageName, targetPkg, targetUid, grantUri); 7381 perm.grantModes(modeFlags, owner); 7382 } 7383 7384 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7385 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7386 if (targetPkg == null) { 7387 throw new NullPointerException("targetPkg"); 7388 } 7389 int targetUid; 7390 final IPackageManager pm = AppGlobals.getPackageManager(); 7391 try { 7392 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7393 } catch (RemoteException ex) { 7394 return; 7395 } 7396 7397 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7398 targetUid); 7399 if (targetUid < 0) { 7400 return; 7401 } 7402 7403 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7404 owner); 7405 } 7406 7407 static class NeededUriGrants extends ArrayList<GrantUri> { 7408 final String targetPkg; 7409 final int targetUid; 7410 final int flags; 7411 7412 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7413 this.targetPkg = targetPkg; 7414 this.targetUid = targetUid; 7415 this.flags = flags; 7416 } 7417 } 7418 7419 /** 7420 * Like checkGrantUriPermissionLocked, but takes an Intent. 7421 */ 7422 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7423 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7424 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7425 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7426 + " clip=" + (intent != null ? intent.getClipData() : null) 7427 + " from " + intent + "; flags=0x" 7428 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7429 7430 if (targetPkg == null) { 7431 throw new NullPointerException("targetPkg"); 7432 } 7433 7434 if (intent == null) { 7435 return null; 7436 } 7437 Uri data = intent.getData(); 7438 ClipData clip = intent.getClipData(); 7439 if (data == null && clip == null) { 7440 return null; 7441 } 7442 // Default userId for uris in the intent (if they don't specify it themselves) 7443 int contentUserHint = intent.getContentUserHint(); 7444 if (contentUserHint == UserHandle.USER_CURRENT) { 7445 contentUserHint = UserHandle.getUserId(callingUid); 7446 } 7447 final IPackageManager pm = AppGlobals.getPackageManager(); 7448 int targetUid; 7449 if (needed != null) { 7450 targetUid = needed.targetUid; 7451 } else { 7452 try { 7453 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7454 } catch (RemoteException ex) { 7455 return null; 7456 } 7457 if (targetUid < 0) { 7458 if (DEBUG_URI_PERMISSION) { 7459 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7460 + " on user " + targetUserId); 7461 } 7462 return null; 7463 } 7464 } 7465 if (data != null) { 7466 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7467 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7468 targetUid); 7469 if (targetUid > 0) { 7470 if (needed == null) { 7471 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7472 } 7473 needed.add(grantUri); 7474 } 7475 } 7476 if (clip != null) { 7477 for (int i=0; i<clip.getItemCount(); i++) { 7478 Uri uri = clip.getItemAt(i).getUri(); 7479 if (uri != null) { 7480 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7481 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7482 targetUid); 7483 if (targetUid > 0) { 7484 if (needed == null) { 7485 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7486 } 7487 needed.add(grantUri); 7488 } 7489 } else { 7490 Intent clipIntent = clip.getItemAt(i).getIntent(); 7491 if (clipIntent != null) { 7492 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7493 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7494 if (newNeeded != null) { 7495 needed = newNeeded; 7496 } 7497 } 7498 } 7499 } 7500 } 7501 7502 return needed; 7503 } 7504 7505 /** 7506 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7507 */ 7508 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7509 UriPermissionOwner owner) { 7510 if (needed != null) { 7511 for (int i=0; i<needed.size(); i++) { 7512 GrantUri grantUri = needed.get(i); 7513 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7514 grantUri, needed.flags, owner); 7515 } 7516 } 7517 } 7518 7519 void grantUriPermissionFromIntentLocked(int callingUid, 7520 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7521 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7522 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7523 if (needed == null) { 7524 return; 7525 } 7526 7527 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7528 } 7529 7530 /** 7531 * @param uri This uri must NOT contain an embedded userId. 7532 * @param userId The userId in which the uri is to be resolved. 7533 */ 7534 @Override 7535 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7536 final int modeFlags, int userId) { 7537 enforceNotIsolatedCaller("grantUriPermission"); 7538 GrantUri grantUri = new GrantUri(userId, uri, false); 7539 synchronized(this) { 7540 final ProcessRecord r = getRecordForAppLocked(caller); 7541 if (r == null) { 7542 throw new SecurityException("Unable to find app for caller " 7543 + caller 7544 + " when granting permission to uri " + grantUri); 7545 } 7546 if (targetPkg == null) { 7547 throw new IllegalArgumentException("null target"); 7548 } 7549 if (grantUri == null) { 7550 throw new IllegalArgumentException("null uri"); 7551 } 7552 7553 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7554 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7555 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7556 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7557 7558 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7559 UserHandle.getUserId(r.uid)); 7560 } 7561 } 7562 7563 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7564 if (perm.modeFlags == 0) { 7565 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7566 perm.targetUid); 7567 if (perms != null) { 7568 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7569 "Removing " + perm.targetUid + " permission to " + perm.uri); 7570 7571 perms.remove(perm.uri); 7572 if (perms.isEmpty()) { 7573 mGrantedUriPermissions.remove(perm.targetUid); 7574 } 7575 } 7576 } 7577 } 7578 7579 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7580 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7581 7582 final IPackageManager pm = AppGlobals.getPackageManager(); 7583 final String authority = grantUri.uri.getAuthority(); 7584 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7585 if (pi == null) { 7586 Slog.w(TAG, "No content provider found for permission revoke: " 7587 + grantUri.toSafeString()); 7588 return; 7589 } 7590 7591 // Does the caller have this permission on the URI? 7592 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7593 // If they don't have direct access to the URI, then revoke any 7594 // ownerless URI permissions that have been granted to them. 7595 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7596 if (perms != null) { 7597 boolean persistChanged = false; 7598 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7599 final UriPermission perm = it.next(); 7600 if (perm.uri.sourceUserId == grantUri.sourceUserId 7601 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7602 if (DEBUG_URI_PERMISSION) 7603 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7604 " permission to " + perm.uri); 7605 persistChanged |= perm.revokeModes( 7606 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7607 if (perm.modeFlags == 0) { 7608 it.remove(); 7609 } 7610 } 7611 } 7612 if (perms.isEmpty()) { 7613 mGrantedUriPermissions.remove(callingUid); 7614 } 7615 if (persistChanged) { 7616 schedulePersistUriGrants(); 7617 } 7618 } 7619 return; 7620 } 7621 7622 boolean persistChanged = false; 7623 7624 // Go through all of the permissions and remove any that match. 7625 int N = mGrantedUriPermissions.size(); 7626 for (int i = 0; i < N; i++) { 7627 final int targetUid = mGrantedUriPermissions.keyAt(i); 7628 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7629 7630 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7631 final UriPermission perm = it.next(); 7632 if (perm.uri.sourceUserId == grantUri.sourceUserId 7633 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7634 if (DEBUG_URI_PERMISSION) 7635 Slog.v(TAG, 7636 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7637 persistChanged |= perm.revokeModes( 7638 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7639 if (perm.modeFlags == 0) { 7640 it.remove(); 7641 } 7642 } 7643 } 7644 7645 if (perms.isEmpty()) { 7646 mGrantedUriPermissions.remove(targetUid); 7647 N--; 7648 i--; 7649 } 7650 } 7651 7652 if (persistChanged) { 7653 schedulePersistUriGrants(); 7654 } 7655 } 7656 7657 /** 7658 * @param uri This uri must NOT contain an embedded userId. 7659 * @param userId The userId in which the uri is to be resolved. 7660 */ 7661 @Override 7662 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7663 int userId) { 7664 enforceNotIsolatedCaller("revokeUriPermission"); 7665 synchronized(this) { 7666 final ProcessRecord r = getRecordForAppLocked(caller); 7667 if (r == null) { 7668 throw new SecurityException("Unable to find app for caller " 7669 + caller 7670 + " when revoking permission to uri " + uri); 7671 } 7672 if (uri == null) { 7673 Slog.w(TAG, "revokeUriPermission: null uri"); 7674 return; 7675 } 7676 7677 if (!Intent.isAccessUriMode(modeFlags)) { 7678 return; 7679 } 7680 7681 final IPackageManager pm = AppGlobals.getPackageManager(); 7682 final String authority = uri.getAuthority(); 7683 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7684 if (pi == null) { 7685 Slog.w(TAG, "No content provider found for permission revoke: " 7686 + uri.toSafeString()); 7687 return; 7688 } 7689 7690 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7691 } 7692 } 7693 7694 /** 7695 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7696 * given package. 7697 * 7698 * @param packageName Package name to match, or {@code null} to apply to all 7699 * packages. 7700 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7701 * to all users. 7702 * @param persistable If persistable grants should be removed. 7703 */ 7704 private void removeUriPermissionsForPackageLocked( 7705 String packageName, int userHandle, boolean persistable) { 7706 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7707 throw new IllegalArgumentException("Must narrow by either package or user"); 7708 } 7709 7710 boolean persistChanged = false; 7711 7712 int N = mGrantedUriPermissions.size(); 7713 for (int i = 0; i < N; i++) { 7714 final int targetUid = mGrantedUriPermissions.keyAt(i); 7715 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7716 7717 // Only inspect grants matching user 7718 if (userHandle == UserHandle.USER_ALL 7719 || userHandle == UserHandle.getUserId(targetUid)) { 7720 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7721 final UriPermission perm = it.next(); 7722 7723 // Only inspect grants matching package 7724 if (packageName == null || perm.sourcePkg.equals(packageName) 7725 || perm.targetPkg.equals(packageName)) { 7726 persistChanged |= perm.revokeModes(persistable 7727 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7728 7729 // Only remove when no modes remain; any persisted grants 7730 // will keep this alive. 7731 if (perm.modeFlags == 0) { 7732 it.remove(); 7733 } 7734 } 7735 } 7736 7737 if (perms.isEmpty()) { 7738 mGrantedUriPermissions.remove(targetUid); 7739 N--; 7740 i--; 7741 } 7742 } 7743 } 7744 7745 if (persistChanged) { 7746 schedulePersistUriGrants(); 7747 } 7748 } 7749 7750 @Override 7751 public IBinder newUriPermissionOwner(String name) { 7752 enforceNotIsolatedCaller("newUriPermissionOwner"); 7753 synchronized(this) { 7754 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7755 return owner.getExternalTokenLocked(); 7756 } 7757 } 7758 7759 /** 7760 * @param uri This uri must NOT contain an embedded userId. 7761 * @param sourceUserId The userId in which the uri is to be resolved. 7762 * @param targetUserId The userId of the app that receives the grant. 7763 */ 7764 @Override 7765 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7766 final int modeFlags, int sourceUserId, int targetUserId) { 7767 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7768 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7769 synchronized(this) { 7770 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7771 if (owner == null) { 7772 throw new IllegalArgumentException("Unknown owner: " + token); 7773 } 7774 if (fromUid != Binder.getCallingUid()) { 7775 if (Binder.getCallingUid() != Process.myUid()) { 7776 // Only system code can grant URI permissions on behalf 7777 // of other users. 7778 throw new SecurityException("nice try"); 7779 } 7780 } 7781 if (targetPkg == null) { 7782 throw new IllegalArgumentException("null target"); 7783 } 7784 if (uri == null) { 7785 throw new IllegalArgumentException("null uri"); 7786 } 7787 7788 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7789 modeFlags, owner, targetUserId); 7790 } 7791 } 7792 7793 /** 7794 * @param uri This uri must NOT contain an embedded userId. 7795 * @param userId The userId in which the uri is to be resolved. 7796 */ 7797 @Override 7798 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7799 synchronized(this) { 7800 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7801 if (owner == null) { 7802 throw new IllegalArgumentException("Unknown owner: " + token); 7803 } 7804 7805 if (uri == null) { 7806 owner.removeUriPermissionsLocked(mode); 7807 } else { 7808 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7809 } 7810 } 7811 } 7812 7813 private void schedulePersistUriGrants() { 7814 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7815 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7816 10 * DateUtils.SECOND_IN_MILLIS); 7817 } 7818 } 7819 7820 private void writeGrantedUriPermissions() { 7821 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7822 7823 // Snapshot permissions so we can persist without lock 7824 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7825 synchronized (this) { 7826 final int size = mGrantedUriPermissions.size(); 7827 for (int i = 0; i < size; i++) { 7828 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7829 for (UriPermission perm : perms.values()) { 7830 if (perm.persistedModeFlags != 0) { 7831 persist.add(perm.snapshot()); 7832 } 7833 } 7834 } 7835 } 7836 7837 FileOutputStream fos = null; 7838 try { 7839 fos = mGrantFile.startWrite(); 7840 7841 XmlSerializer out = new FastXmlSerializer(); 7842 out.setOutput(fos, "utf-8"); 7843 out.startDocument(null, true); 7844 out.startTag(null, TAG_URI_GRANTS); 7845 for (UriPermission.Snapshot perm : persist) { 7846 out.startTag(null, TAG_URI_GRANT); 7847 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7848 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7849 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7850 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7851 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7852 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7853 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7854 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7855 out.endTag(null, TAG_URI_GRANT); 7856 } 7857 out.endTag(null, TAG_URI_GRANTS); 7858 out.endDocument(); 7859 7860 mGrantFile.finishWrite(fos); 7861 } catch (IOException e) { 7862 if (fos != null) { 7863 mGrantFile.failWrite(fos); 7864 } 7865 } 7866 } 7867 7868 private void readGrantedUriPermissionsLocked() { 7869 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7870 7871 final long now = System.currentTimeMillis(); 7872 7873 FileInputStream fis = null; 7874 try { 7875 fis = mGrantFile.openRead(); 7876 final XmlPullParser in = Xml.newPullParser(); 7877 in.setInput(fis, null); 7878 7879 int type; 7880 while ((type = in.next()) != END_DOCUMENT) { 7881 final String tag = in.getName(); 7882 if (type == START_TAG) { 7883 if (TAG_URI_GRANT.equals(tag)) { 7884 final int sourceUserId; 7885 final int targetUserId; 7886 final int userHandle = readIntAttribute(in, 7887 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7888 if (userHandle != UserHandle.USER_NULL) { 7889 // For backwards compatibility. 7890 sourceUserId = userHandle; 7891 targetUserId = userHandle; 7892 } else { 7893 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7894 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7895 } 7896 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7897 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7898 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7899 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7900 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7901 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7902 7903 // Sanity check that provider still belongs to source package 7904 final ProviderInfo pi = getProviderInfoLocked( 7905 uri.getAuthority(), sourceUserId); 7906 if (pi != null && sourcePkg.equals(pi.packageName)) { 7907 int targetUid = -1; 7908 try { 7909 targetUid = AppGlobals.getPackageManager() 7910 .getPackageUid(targetPkg, targetUserId); 7911 } catch (RemoteException e) { 7912 } 7913 if (targetUid != -1) { 7914 final UriPermission perm = findOrCreateUriPermissionLocked( 7915 sourcePkg, targetPkg, targetUid, 7916 new GrantUri(sourceUserId, uri, prefix)); 7917 perm.initPersistedModes(modeFlags, createdTime); 7918 } 7919 } else { 7920 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7921 + " but instead found " + pi); 7922 } 7923 } 7924 } 7925 } 7926 } catch (FileNotFoundException e) { 7927 // Missing grants is okay 7928 } catch (IOException e) { 7929 Slog.wtf(TAG, "Failed reading Uri grants", e); 7930 } catch (XmlPullParserException e) { 7931 Slog.wtf(TAG, "Failed reading Uri grants", e); 7932 } finally { 7933 IoUtils.closeQuietly(fis); 7934 } 7935 } 7936 7937 /** 7938 * @param uri This uri must NOT contain an embedded userId. 7939 * @param userId The userId in which the uri is to be resolved. 7940 */ 7941 @Override 7942 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7943 enforceNotIsolatedCaller("takePersistableUriPermission"); 7944 7945 Preconditions.checkFlagsArgument(modeFlags, 7946 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7947 7948 synchronized (this) { 7949 final int callingUid = Binder.getCallingUid(); 7950 boolean persistChanged = false; 7951 GrantUri grantUri = new GrantUri(userId, uri, false); 7952 7953 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7954 new GrantUri(userId, uri, false)); 7955 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7956 new GrantUri(userId, uri, true)); 7957 7958 final boolean exactValid = (exactPerm != null) 7959 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7960 final boolean prefixValid = (prefixPerm != null) 7961 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7962 7963 if (!(exactValid || prefixValid)) { 7964 throw new SecurityException("No persistable permission grants found for UID " 7965 + callingUid + " and Uri " + grantUri.toSafeString()); 7966 } 7967 7968 if (exactValid) { 7969 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7970 } 7971 if (prefixValid) { 7972 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7973 } 7974 7975 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7976 7977 if (persistChanged) { 7978 schedulePersistUriGrants(); 7979 } 7980 } 7981 } 7982 7983 /** 7984 * @param uri This uri must NOT contain an embedded userId. 7985 * @param userId The userId in which the uri is to be resolved. 7986 */ 7987 @Override 7988 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7989 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7990 7991 Preconditions.checkFlagsArgument(modeFlags, 7992 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7993 7994 synchronized (this) { 7995 final int callingUid = Binder.getCallingUid(); 7996 boolean persistChanged = false; 7997 7998 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7999 new GrantUri(userId, uri, false)); 8000 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 8001 new GrantUri(userId, uri, true)); 8002 if (exactPerm == null && prefixPerm == null) { 8003 throw new SecurityException("No permission grants found for UID " + callingUid 8004 + " and Uri " + uri.toSafeString()); 8005 } 8006 8007 if (exactPerm != null) { 8008 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 8009 removeUriPermissionIfNeededLocked(exactPerm); 8010 } 8011 if (prefixPerm != null) { 8012 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 8013 removeUriPermissionIfNeededLocked(prefixPerm); 8014 } 8015 8016 if (persistChanged) { 8017 schedulePersistUriGrants(); 8018 } 8019 } 8020 } 8021 8022 /** 8023 * Prune any older {@link UriPermission} for the given UID until outstanding 8024 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 8025 * 8026 * @return if any mutations occured that require persisting. 8027 */ 8028 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 8029 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8030 if (perms == null) return false; 8031 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8032 8033 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8034 for (UriPermission perm : perms.values()) { 8035 if (perm.persistedModeFlags != 0) { 8036 persisted.add(perm); 8037 } 8038 } 8039 8040 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8041 if (trimCount <= 0) return false; 8042 8043 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8044 for (int i = 0; i < trimCount; i++) { 8045 final UriPermission perm = persisted.get(i); 8046 8047 if (DEBUG_URI_PERMISSION) { 8048 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8049 } 8050 8051 perm.releasePersistableModes(~0); 8052 removeUriPermissionIfNeededLocked(perm); 8053 } 8054 8055 return true; 8056 } 8057 8058 @Override 8059 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8060 String packageName, boolean incoming) { 8061 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8062 Preconditions.checkNotNull(packageName, "packageName"); 8063 8064 final int callingUid = Binder.getCallingUid(); 8065 final IPackageManager pm = AppGlobals.getPackageManager(); 8066 try { 8067 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8068 if (packageUid != callingUid) { 8069 throw new SecurityException( 8070 "Package " + packageName + " does not belong to calling UID " + callingUid); 8071 } 8072 } catch (RemoteException e) { 8073 throw new SecurityException("Failed to verify package name ownership"); 8074 } 8075 8076 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8077 synchronized (this) { 8078 if (incoming) { 8079 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8080 callingUid); 8081 if (perms == null) { 8082 Slog.w(TAG, "No permission grants found for " + packageName); 8083 } else { 8084 for (UriPermission perm : perms.values()) { 8085 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8086 result.add(perm.buildPersistedPublicApiObject()); 8087 } 8088 } 8089 } 8090 } else { 8091 final int size = mGrantedUriPermissions.size(); 8092 for (int i = 0; i < size; i++) { 8093 final ArrayMap<GrantUri, UriPermission> perms = 8094 mGrantedUriPermissions.valueAt(i); 8095 for (UriPermission perm : perms.values()) { 8096 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8097 result.add(perm.buildPersistedPublicApiObject()); 8098 } 8099 } 8100 } 8101 } 8102 } 8103 return new ParceledListSlice<android.content.UriPermission>(result); 8104 } 8105 8106 @Override 8107 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8108 synchronized (this) { 8109 ProcessRecord app = 8110 who != null ? getRecordForAppLocked(who) : null; 8111 if (app == null) return; 8112 8113 Message msg = Message.obtain(); 8114 msg.what = WAIT_FOR_DEBUGGER_MSG; 8115 msg.obj = app; 8116 msg.arg1 = waiting ? 1 : 0; 8117 mHandler.sendMessage(msg); 8118 } 8119 } 8120 8121 @Override 8122 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8123 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8124 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8125 outInfo.availMem = Process.getFreeMemory(); 8126 outInfo.totalMem = Process.getTotalMemory(); 8127 outInfo.threshold = homeAppMem; 8128 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8129 outInfo.hiddenAppThreshold = cachedAppMem; 8130 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8131 ProcessList.SERVICE_ADJ); 8132 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8133 ProcessList.VISIBLE_APP_ADJ); 8134 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8135 ProcessList.FOREGROUND_APP_ADJ); 8136 } 8137 8138 // ========================================================= 8139 // TASK MANAGEMENT 8140 // ========================================================= 8141 8142 @Override 8143 public List<IAppTask> getAppTasks(String callingPackage) { 8144 int callingUid = Binder.getCallingUid(); 8145 long ident = Binder.clearCallingIdentity(); 8146 8147 synchronized(this) { 8148 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8149 try { 8150 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8151 8152 final int N = mRecentTasks.size(); 8153 for (int i = 0; i < N; i++) { 8154 TaskRecord tr = mRecentTasks.get(i); 8155 // Skip tasks that do not match the caller. We don't need to verify 8156 // callingPackage, because we are also limiting to callingUid and know 8157 // that will limit to the correct security sandbox. 8158 if (tr.effectiveUid != callingUid) { 8159 continue; 8160 } 8161 Intent intent = tr.getBaseIntent(); 8162 if (intent == null || 8163 !callingPackage.equals(intent.getComponent().getPackageName())) { 8164 continue; 8165 } 8166 ActivityManager.RecentTaskInfo taskInfo = 8167 createRecentTaskInfoFromTaskRecord(tr); 8168 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8169 list.add(taskImpl); 8170 } 8171 } finally { 8172 Binder.restoreCallingIdentity(ident); 8173 } 8174 return list; 8175 } 8176 } 8177 8178 @Override 8179 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8180 final int callingUid = Binder.getCallingUid(); 8181 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8182 8183 synchronized(this) { 8184 if (localLOGV) Slog.v( 8185 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8186 8187 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8188 callingUid); 8189 8190 // TODO: Improve with MRU list from all ActivityStacks. 8191 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8192 } 8193 8194 return list; 8195 } 8196 8197 TaskRecord getMostRecentTask() { 8198 return mRecentTasks.get(0); 8199 } 8200 8201 /** 8202 * Creates a new RecentTaskInfo from a TaskRecord. 8203 */ 8204 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8205 // Update the task description to reflect any changes in the task stack 8206 tr.updateTaskDescription(); 8207 8208 // Compose the recent task info 8209 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8210 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8211 rti.persistentId = tr.taskId; 8212 rti.baseIntent = new Intent(tr.getBaseIntent()); 8213 rti.origActivity = tr.origActivity; 8214 rti.description = tr.lastDescription; 8215 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8216 rti.userId = tr.userId; 8217 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8218 rti.firstActiveTime = tr.firstActiveTime; 8219 rti.lastActiveTime = tr.lastActiveTime; 8220 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8221 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8222 return rti; 8223 } 8224 8225 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8226 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8227 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8228 if (!allowed) { 8229 if (checkPermission(android.Manifest.permission.GET_TASKS, 8230 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8231 // Temporary compatibility: some existing apps on the system image may 8232 // still be requesting the old permission and not switched to the new 8233 // one; if so, we'll still allow them full access. This means we need 8234 // to see if they are holding the old permission and are a system app. 8235 try { 8236 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8237 allowed = true; 8238 Slog.w(TAG, caller + ": caller " + callingUid 8239 + " is using old GET_TASKS but privileged; allowing"); 8240 } 8241 } catch (RemoteException e) { 8242 } 8243 } 8244 } 8245 if (!allowed) { 8246 Slog.w(TAG, caller + ": caller " + callingUid 8247 + " does not hold GET_TASKS; limiting output"); 8248 } 8249 return allowed; 8250 } 8251 8252 @Override 8253 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8254 final int callingUid = Binder.getCallingUid(); 8255 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8256 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8257 8258 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8259 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8260 synchronized (this) { 8261 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8262 callingUid); 8263 final boolean detailed = checkCallingPermission( 8264 android.Manifest.permission.GET_DETAILED_TASKS) 8265 == PackageManager.PERMISSION_GRANTED; 8266 8267 final int N = mRecentTasks.size(); 8268 ArrayList<ActivityManager.RecentTaskInfo> res 8269 = new ArrayList<ActivityManager.RecentTaskInfo>( 8270 maxNum < N ? maxNum : N); 8271 8272 final Set<Integer> includedUsers; 8273 if (includeProfiles) { 8274 includedUsers = getProfileIdsLocked(userId); 8275 } else { 8276 includedUsers = new HashSet<Integer>(); 8277 } 8278 includedUsers.add(Integer.valueOf(userId)); 8279 8280 for (int i=0; i<N && maxNum > 0; i++) { 8281 TaskRecord tr = mRecentTasks.get(i); 8282 // Only add calling user or related users recent tasks 8283 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8284 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8285 continue; 8286 } 8287 8288 // Return the entry if desired by the caller. We always return 8289 // the first entry, because callers always expect this to be the 8290 // foreground app. We may filter others if the caller has 8291 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8292 // we should exclude the entry. 8293 8294 if (i == 0 8295 || withExcluded 8296 || (tr.intent == null) 8297 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8298 == 0)) { 8299 if (!allowed) { 8300 // If the caller doesn't have the GET_TASKS permission, then only 8301 // allow them to see a small subset of tasks -- their own and home. 8302 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8303 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8304 continue; 8305 } 8306 } 8307 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8308 if (tr.stack != null && tr.stack.isHomeStack()) { 8309 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8310 continue; 8311 } 8312 } 8313 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8314 // Don't include auto remove tasks that are finished or finishing. 8315 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8316 + tr); 8317 continue; 8318 } 8319 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8320 && !tr.isAvailable) { 8321 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8322 continue; 8323 } 8324 8325 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8326 if (!detailed) { 8327 rti.baseIntent.replaceExtras((Bundle)null); 8328 } 8329 8330 res.add(rti); 8331 maxNum--; 8332 } 8333 } 8334 return res; 8335 } 8336 } 8337 8338 private TaskRecord recentTaskForIdLocked(int id) { 8339 final int N = mRecentTasks.size(); 8340 for (int i=0; i<N; i++) { 8341 TaskRecord tr = mRecentTasks.get(i); 8342 if (tr.taskId == id) { 8343 return tr; 8344 } 8345 } 8346 return null; 8347 } 8348 8349 @Override 8350 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8351 synchronized (this) { 8352 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8353 "getTaskThumbnail()"); 8354 TaskRecord tr = recentTaskForIdLocked(id); 8355 if (tr != null) { 8356 return tr.getTaskThumbnailLocked(); 8357 } 8358 } 8359 return null; 8360 } 8361 8362 @Override 8363 public int addAppTask(IBinder activityToken, Intent intent, 8364 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8365 final int callingUid = Binder.getCallingUid(); 8366 final long callingIdent = Binder.clearCallingIdentity(); 8367 8368 try { 8369 synchronized (this) { 8370 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8371 if (r == null) { 8372 throw new IllegalArgumentException("Activity does not exist; token=" 8373 + activityToken); 8374 } 8375 ComponentName comp = intent.getComponent(); 8376 if (comp == null) { 8377 throw new IllegalArgumentException("Intent " + intent 8378 + " must specify explicit component"); 8379 } 8380 if (thumbnail.getWidth() != mThumbnailWidth 8381 || thumbnail.getHeight() != mThumbnailHeight) { 8382 throw new IllegalArgumentException("Bad thumbnail size: got " 8383 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8384 + mThumbnailWidth + "x" + mThumbnailHeight); 8385 } 8386 if (intent.getSelector() != null) { 8387 intent.setSelector(null); 8388 } 8389 if (intent.getSourceBounds() != null) { 8390 intent.setSourceBounds(null); 8391 } 8392 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8393 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8394 // The caller has added this as an auto-remove task... that makes no 8395 // sense, so turn off auto-remove. 8396 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8397 } 8398 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8399 // Must be a new task. 8400 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8401 } 8402 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8403 mLastAddedTaskActivity = null; 8404 } 8405 ActivityInfo ainfo = mLastAddedTaskActivity; 8406 if (ainfo == null) { 8407 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8408 comp, 0, UserHandle.getUserId(callingUid)); 8409 if (ainfo.applicationInfo.uid != callingUid) { 8410 throw new SecurityException( 8411 "Can't add task for another application: target uid=" 8412 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8413 } 8414 } 8415 8416 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8417 intent, description); 8418 8419 int trimIdx = trimRecentsForTask(task, false); 8420 if (trimIdx >= 0) { 8421 // If this would have caused a trim, then we'll abort because that 8422 // means it would be added at the end of the list but then just removed. 8423 return -1; 8424 } 8425 8426 final int N = mRecentTasks.size(); 8427 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8428 final TaskRecord tr = mRecentTasks.remove(N - 1); 8429 tr.removedFromRecents(mTaskPersister); 8430 } 8431 8432 task.inRecents = true; 8433 mRecentTasks.add(task); 8434 r.task.stack.addTask(task, false, false); 8435 8436 task.setLastThumbnail(thumbnail); 8437 task.freeLastThumbnail(); 8438 8439 return task.taskId; 8440 } 8441 } finally { 8442 Binder.restoreCallingIdentity(callingIdent); 8443 } 8444 } 8445 8446 @Override 8447 public Point getAppTaskThumbnailSize() { 8448 synchronized (this) { 8449 return new Point(mThumbnailWidth, mThumbnailHeight); 8450 } 8451 } 8452 8453 @Override 8454 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8455 synchronized (this) { 8456 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8457 if (r != null) { 8458 r.setTaskDescription(td); 8459 r.task.updateTaskDescription(); 8460 } 8461 } 8462 } 8463 8464 @Override 8465 public Bitmap getTaskDescriptionIcon(String filename) { 8466 if (!FileUtils.isValidExtFilename(filename) 8467 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8468 throw new IllegalArgumentException("Bad filename: " + filename); 8469 } 8470 return mTaskPersister.getTaskDescriptionIcon(filename); 8471 } 8472 8473 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8474 mRecentTasks.remove(tr); 8475 tr.removedFromRecents(mTaskPersister); 8476 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8477 Intent baseIntent = new Intent( 8478 tr.intent != null ? tr.intent : tr.affinityIntent); 8479 ComponentName component = baseIntent.getComponent(); 8480 if (component == null) { 8481 Slog.w(TAG, "Now component for base intent of task: " + tr); 8482 return; 8483 } 8484 8485 // Find any running services associated with this app. 8486 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8487 8488 if (killProcesses) { 8489 // Find any running processes associated with this app. 8490 final String pkg = component.getPackageName(); 8491 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8492 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8493 for (int i=0; i<pmap.size(); i++) { 8494 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8495 for (int j=0; j<uids.size(); j++) { 8496 ProcessRecord proc = uids.valueAt(j); 8497 if (proc.userId != tr.userId) { 8498 continue; 8499 } 8500 if (!proc.pkgList.containsKey(pkg)) { 8501 continue; 8502 } 8503 procs.add(proc); 8504 } 8505 } 8506 8507 // Kill the running processes. 8508 for (int i=0; i<procs.size(); i++) { 8509 ProcessRecord pr = procs.get(i); 8510 if (pr == mHomeProcess) { 8511 // Don't kill the home process along with tasks from the same package. 8512 continue; 8513 } 8514 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8515 pr.kill("remove task", true); 8516 } else { 8517 pr.waitingToKill = "remove task"; 8518 } 8519 } 8520 } 8521 } 8522 8523 /** 8524 * Removes the task with the specified task id. 8525 * 8526 * @param taskId Identifier of the task to be removed. 8527 * @param flags Additional operational flags. May be 0 or 8528 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8529 * @return Returns true if the given task was found and removed. 8530 */ 8531 private boolean removeTaskByIdLocked(int taskId, int flags) { 8532 TaskRecord tr = recentTaskForIdLocked(taskId); 8533 if (tr != null) { 8534 tr.removeTaskActivitiesLocked(); 8535 cleanUpRemovedTaskLocked(tr, flags); 8536 if (tr.isPersistable) { 8537 notifyTaskPersisterLocked(null, true); 8538 } 8539 return true; 8540 } 8541 return false; 8542 } 8543 8544 @Override 8545 public boolean removeTask(int taskId, int flags) { 8546 synchronized (this) { 8547 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8548 "removeTask()"); 8549 long ident = Binder.clearCallingIdentity(); 8550 try { 8551 return removeTaskByIdLocked(taskId, flags); 8552 } finally { 8553 Binder.restoreCallingIdentity(ident); 8554 } 8555 } 8556 } 8557 8558 /** 8559 * TODO: Add mController hook 8560 */ 8561 @Override 8562 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8563 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8564 "moveTaskToFront()"); 8565 8566 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8567 synchronized(this) { 8568 moveTaskToFrontLocked(taskId, flags, options); 8569 } 8570 } 8571 8572 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8573 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8574 Binder.getCallingUid(), -1, -1, "Task to front")) { 8575 ActivityOptions.abort(options); 8576 return; 8577 } 8578 final long origId = Binder.clearCallingIdentity(); 8579 try { 8580 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8581 if (task == null) { 8582 return; 8583 } 8584 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8585 mStackSupervisor.showLockTaskToast(); 8586 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8587 return; 8588 } 8589 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8590 if (prev != null && prev.isRecentsActivity()) { 8591 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8592 } 8593 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8594 } finally { 8595 Binder.restoreCallingIdentity(origId); 8596 } 8597 ActivityOptions.abort(options); 8598 } 8599 8600 @Override 8601 public void moveTaskToBack(int taskId) { 8602 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8603 "moveTaskToBack()"); 8604 8605 synchronized(this) { 8606 TaskRecord tr = recentTaskForIdLocked(taskId); 8607 if (tr != null) { 8608 if (tr == mStackSupervisor.mLockTaskModeTask) { 8609 mStackSupervisor.showLockTaskToast(); 8610 return; 8611 } 8612 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8613 ActivityStack stack = tr.stack; 8614 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8615 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8616 Binder.getCallingUid(), -1, -1, "Task to back")) { 8617 return; 8618 } 8619 } 8620 final long origId = Binder.clearCallingIdentity(); 8621 try { 8622 stack.moveTaskToBackLocked(taskId, null); 8623 } finally { 8624 Binder.restoreCallingIdentity(origId); 8625 } 8626 } 8627 } 8628 } 8629 8630 /** 8631 * Moves an activity, and all of the other activities within the same task, to the bottom 8632 * of the history stack. The activity's order within the task is unchanged. 8633 * 8634 * @param token A reference to the activity we wish to move 8635 * @param nonRoot If false then this only works if the activity is the root 8636 * of a task; if true it will work for any activity in a task. 8637 * @return Returns true if the move completed, false if not. 8638 */ 8639 @Override 8640 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8641 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8642 synchronized(this) { 8643 final long origId = Binder.clearCallingIdentity(); 8644 try { 8645 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8646 if (taskId >= 0) { 8647 if ((mStackSupervisor.mLockTaskModeTask != null) 8648 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8649 mStackSupervisor.showLockTaskToast(); 8650 return false; 8651 } 8652 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8653 } 8654 } finally { 8655 Binder.restoreCallingIdentity(origId); 8656 } 8657 } 8658 return false; 8659 } 8660 8661 @Override 8662 public void moveTaskBackwards(int task) { 8663 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8664 "moveTaskBackwards()"); 8665 8666 synchronized(this) { 8667 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8668 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8669 return; 8670 } 8671 final long origId = Binder.clearCallingIdentity(); 8672 moveTaskBackwardsLocked(task); 8673 Binder.restoreCallingIdentity(origId); 8674 } 8675 } 8676 8677 private final void moveTaskBackwardsLocked(int task) { 8678 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8679 } 8680 8681 @Override 8682 public IBinder getHomeActivityToken() throws RemoteException { 8683 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8684 "getHomeActivityToken()"); 8685 synchronized (this) { 8686 return mStackSupervisor.getHomeActivityToken(); 8687 } 8688 } 8689 8690 @Override 8691 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8692 IActivityContainerCallback callback) throws RemoteException { 8693 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8694 "createActivityContainer()"); 8695 synchronized (this) { 8696 if (parentActivityToken == null) { 8697 throw new IllegalArgumentException("parent token must not be null"); 8698 } 8699 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8700 if (r == null) { 8701 return null; 8702 } 8703 if (callback == null) { 8704 throw new IllegalArgumentException("callback must not be null"); 8705 } 8706 return mStackSupervisor.createActivityContainer(r, callback); 8707 } 8708 } 8709 8710 @Override 8711 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8712 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8713 "deleteActivityContainer()"); 8714 synchronized (this) { 8715 mStackSupervisor.deleteActivityContainer(container); 8716 } 8717 } 8718 8719 @Override 8720 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8721 throws RemoteException { 8722 synchronized (this) { 8723 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8724 if (stack != null) { 8725 return stack.mActivityContainer; 8726 } 8727 return null; 8728 } 8729 } 8730 8731 @Override 8732 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8733 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8734 "moveTaskToStack()"); 8735 if (stackId == HOME_STACK_ID) { 8736 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8737 new RuntimeException("here").fillInStackTrace()); 8738 } 8739 synchronized (this) { 8740 long ident = Binder.clearCallingIdentity(); 8741 try { 8742 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8743 + stackId + " toTop=" + toTop); 8744 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8745 } finally { 8746 Binder.restoreCallingIdentity(ident); 8747 } 8748 } 8749 } 8750 8751 @Override 8752 public void resizeStack(int stackBoxId, Rect bounds) { 8753 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8754 "resizeStackBox()"); 8755 long ident = Binder.clearCallingIdentity(); 8756 try { 8757 mWindowManager.resizeStack(stackBoxId, bounds); 8758 } finally { 8759 Binder.restoreCallingIdentity(ident); 8760 } 8761 } 8762 8763 @Override 8764 public List<StackInfo> getAllStackInfos() { 8765 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8766 "getAllStackInfos()"); 8767 long ident = Binder.clearCallingIdentity(); 8768 try { 8769 synchronized (this) { 8770 return mStackSupervisor.getAllStackInfosLocked(); 8771 } 8772 } finally { 8773 Binder.restoreCallingIdentity(ident); 8774 } 8775 } 8776 8777 @Override 8778 public StackInfo getStackInfo(int stackId) { 8779 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8780 "getStackInfo()"); 8781 long ident = Binder.clearCallingIdentity(); 8782 try { 8783 synchronized (this) { 8784 return mStackSupervisor.getStackInfoLocked(stackId); 8785 } 8786 } finally { 8787 Binder.restoreCallingIdentity(ident); 8788 } 8789 } 8790 8791 @Override 8792 public boolean isInHomeStack(int taskId) { 8793 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8794 "getStackInfo()"); 8795 long ident = Binder.clearCallingIdentity(); 8796 try { 8797 synchronized (this) { 8798 TaskRecord tr = recentTaskForIdLocked(taskId); 8799 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8800 } 8801 } finally { 8802 Binder.restoreCallingIdentity(ident); 8803 } 8804 } 8805 8806 @Override 8807 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8808 synchronized(this) { 8809 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8810 } 8811 } 8812 8813 private boolean isLockTaskAuthorized(String pkg) { 8814 final DevicePolicyManager dpm = (DevicePolicyManager) 8815 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8816 try { 8817 int uid = mContext.getPackageManager().getPackageUid(pkg, 8818 Binder.getCallingUserHandle().getIdentifier()); 8819 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8820 } catch (NameNotFoundException e) { 8821 return false; 8822 } 8823 } 8824 8825 void startLockTaskMode(TaskRecord task) { 8826 final String pkg; 8827 synchronized (this) { 8828 pkg = task.intent.getComponent().getPackageName(); 8829 } 8830 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8831 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8832 final TaskRecord taskRecord = task; 8833 mHandler.post(new Runnable() { 8834 @Override 8835 public void run() { 8836 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8837 } 8838 }); 8839 return; 8840 } 8841 long ident = Binder.clearCallingIdentity(); 8842 try { 8843 synchronized (this) { 8844 // Since we lost lock on task, make sure it is still there. 8845 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8846 if (task != null) { 8847 if (!isSystemInitiated 8848 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8849 throw new IllegalArgumentException("Invalid task, not in foreground"); 8850 } 8851 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8852 } 8853 } 8854 } finally { 8855 Binder.restoreCallingIdentity(ident); 8856 } 8857 } 8858 8859 @Override 8860 public void startLockTaskMode(int taskId) { 8861 final TaskRecord task; 8862 long ident = Binder.clearCallingIdentity(); 8863 try { 8864 synchronized (this) { 8865 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8866 } 8867 } finally { 8868 Binder.restoreCallingIdentity(ident); 8869 } 8870 if (task != null) { 8871 startLockTaskMode(task); 8872 } 8873 } 8874 8875 @Override 8876 public void startLockTaskMode(IBinder token) { 8877 final TaskRecord task; 8878 long ident = Binder.clearCallingIdentity(); 8879 try { 8880 synchronized (this) { 8881 final ActivityRecord r = ActivityRecord.forToken(token); 8882 if (r == null) { 8883 return; 8884 } 8885 task = r.task; 8886 } 8887 } finally { 8888 Binder.restoreCallingIdentity(ident); 8889 } 8890 if (task != null) { 8891 startLockTaskMode(task); 8892 } 8893 } 8894 8895 @Override 8896 public void startLockTaskModeOnCurrent() throws RemoteException { 8897 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8898 "startLockTaskModeOnCurrent"); 8899 ActivityRecord r = null; 8900 synchronized (this) { 8901 r = mStackSupervisor.topRunningActivityLocked(); 8902 } 8903 startLockTaskMode(r.task); 8904 } 8905 8906 @Override 8907 public void stopLockTaskMode() { 8908 // Verify that the user matches the package of the intent for the TaskRecord 8909 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8910 // and stopLockTaskMode. 8911 final int callingUid = Binder.getCallingUid(); 8912 if (callingUid != Process.SYSTEM_UID) { 8913 try { 8914 String pkg = 8915 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8916 int uid = mContext.getPackageManager().getPackageUid(pkg, 8917 Binder.getCallingUserHandle().getIdentifier()); 8918 if (uid != callingUid) { 8919 throw new SecurityException("Invalid uid, expected " + uid); 8920 } 8921 } catch (NameNotFoundException e) { 8922 Log.d(TAG, "stopLockTaskMode " + e); 8923 return; 8924 } 8925 } 8926 long ident = Binder.clearCallingIdentity(); 8927 try { 8928 Log.d(TAG, "stopLockTaskMode"); 8929 // Stop lock task 8930 synchronized (this) { 8931 mStackSupervisor.setLockTaskModeLocked(null, false); 8932 } 8933 } finally { 8934 Binder.restoreCallingIdentity(ident); 8935 } 8936 } 8937 8938 @Override 8939 public void stopLockTaskModeOnCurrent() throws RemoteException { 8940 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8941 "stopLockTaskModeOnCurrent"); 8942 long ident = Binder.clearCallingIdentity(); 8943 try { 8944 stopLockTaskMode(); 8945 } finally { 8946 Binder.restoreCallingIdentity(ident); 8947 } 8948 } 8949 8950 @Override 8951 public boolean isInLockTaskMode() { 8952 synchronized (this) { 8953 return mStackSupervisor.isInLockTaskMode(); 8954 } 8955 } 8956 8957 // ========================================================= 8958 // CONTENT PROVIDERS 8959 // ========================================================= 8960 8961 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8962 List<ProviderInfo> providers = null; 8963 try { 8964 providers = AppGlobals.getPackageManager(). 8965 queryContentProviders(app.processName, app.uid, 8966 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8967 } catch (RemoteException ex) { 8968 } 8969 if (DEBUG_MU) 8970 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8971 int userId = app.userId; 8972 if (providers != null) { 8973 int N = providers.size(); 8974 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8975 for (int i=0; i<N; i++) { 8976 ProviderInfo cpi = 8977 (ProviderInfo)providers.get(i); 8978 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8979 cpi.name, cpi.flags); 8980 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8981 // This is a singleton provider, but a user besides the 8982 // default user is asking to initialize a process it runs 8983 // in... well, no, it doesn't actually run in this process, 8984 // it runs in the process of the default user. Get rid of it. 8985 providers.remove(i); 8986 N--; 8987 i--; 8988 continue; 8989 } 8990 8991 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8992 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8993 if (cpr == null) { 8994 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8995 mProviderMap.putProviderByClass(comp, cpr); 8996 } 8997 if (DEBUG_MU) 8998 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8999 app.pubProviders.put(cpi.name, cpr); 9000 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9001 // Don't add this if it is a platform component that is marked 9002 // to run in multiple processes, because this is actually 9003 // part of the framework so doesn't make sense to track as a 9004 // separate apk in the process. 9005 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9006 mProcessStats); 9007 } 9008 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9009 } 9010 } 9011 return providers; 9012 } 9013 9014 /** 9015 * Check if {@link ProcessRecord} has a possible chance at accessing the 9016 * given {@link ProviderInfo}. Final permission checking is always done 9017 * in {@link ContentProvider}. 9018 */ 9019 private final String checkContentProviderPermissionLocked( 9020 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9021 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9022 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9023 boolean checkedGrants = false; 9024 if (checkUser) { 9025 // Looking for cross-user grants before enforcing the typical cross-users permissions 9026 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9027 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9028 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9029 return null; 9030 } 9031 checkedGrants = true; 9032 } 9033 userId = handleIncomingUser(callingPid, callingUid, userId, 9034 false, ALLOW_NON_FULL, 9035 "checkContentProviderPermissionLocked " + cpi.authority, null); 9036 if (userId != tmpTargetUserId) { 9037 // When we actually went to determine the final targer user ID, this ended 9038 // up different than our initial check for the authority. This is because 9039 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9040 // SELF. So we need to re-check the grants again. 9041 checkedGrants = false; 9042 } 9043 } 9044 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9045 cpi.applicationInfo.uid, cpi.exported) 9046 == PackageManager.PERMISSION_GRANTED) { 9047 return null; 9048 } 9049 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9050 cpi.applicationInfo.uid, cpi.exported) 9051 == PackageManager.PERMISSION_GRANTED) { 9052 return null; 9053 } 9054 9055 PathPermission[] pps = cpi.pathPermissions; 9056 if (pps != null) { 9057 int i = pps.length; 9058 while (i > 0) { 9059 i--; 9060 PathPermission pp = pps[i]; 9061 String pprperm = pp.getReadPermission(); 9062 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9063 cpi.applicationInfo.uid, cpi.exported) 9064 == PackageManager.PERMISSION_GRANTED) { 9065 return null; 9066 } 9067 String ppwperm = pp.getWritePermission(); 9068 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9069 cpi.applicationInfo.uid, cpi.exported) 9070 == PackageManager.PERMISSION_GRANTED) { 9071 return null; 9072 } 9073 } 9074 } 9075 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9076 return null; 9077 } 9078 9079 String msg; 9080 if (!cpi.exported) { 9081 msg = "Permission Denial: opening provider " + cpi.name 9082 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9083 + ", uid=" + callingUid + ") that is not exported from uid " 9084 + cpi.applicationInfo.uid; 9085 } else { 9086 msg = "Permission Denial: opening provider " + cpi.name 9087 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9088 + ", uid=" + callingUid + ") requires " 9089 + cpi.readPermission + " or " + cpi.writePermission; 9090 } 9091 Slog.w(TAG, msg); 9092 return msg; 9093 } 9094 9095 /** 9096 * Returns if the ContentProvider has granted a uri to callingUid 9097 */ 9098 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9099 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9100 if (perms != null) { 9101 for (int i=perms.size()-1; i>=0; i--) { 9102 GrantUri grantUri = perms.keyAt(i); 9103 if (grantUri.sourceUserId == userId || !checkUser) { 9104 if (matchesProvider(grantUri.uri, cpi)) { 9105 return true; 9106 } 9107 } 9108 } 9109 } 9110 return false; 9111 } 9112 9113 /** 9114 * Returns true if the uri authority is one of the authorities specified in the provider. 9115 */ 9116 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9117 String uriAuth = uri.getAuthority(); 9118 String cpiAuth = cpi.authority; 9119 if (cpiAuth.indexOf(';') == -1) { 9120 return cpiAuth.equals(uriAuth); 9121 } 9122 String[] cpiAuths = cpiAuth.split(";"); 9123 int length = cpiAuths.length; 9124 for (int i = 0; i < length; i++) { 9125 if (cpiAuths[i].equals(uriAuth)) return true; 9126 } 9127 return false; 9128 } 9129 9130 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9131 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9132 if (r != null) { 9133 for (int i=0; i<r.conProviders.size(); i++) { 9134 ContentProviderConnection conn = r.conProviders.get(i); 9135 if (conn.provider == cpr) { 9136 if (DEBUG_PROVIDER) Slog.v(TAG, 9137 "Adding provider requested by " 9138 + r.processName + " from process " 9139 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9140 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9141 if (stable) { 9142 conn.stableCount++; 9143 conn.numStableIncs++; 9144 } else { 9145 conn.unstableCount++; 9146 conn.numUnstableIncs++; 9147 } 9148 return conn; 9149 } 9150 } 9151 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9152 if (stable) { 9153 conn.stableCount = 1; 9154 conn.numStableIncs = 1; 9155 } else { 9156 conn.unstableCount = 1; 9157 conn.numUnstableIncs = 1; 9158 } 9159 cpr.connections.add(conn); 9160 r.conProviders.add(conn); 9161 return conn; 9162 } 9163 cpr.addExternalProcessHandleLocked(externalProcessToken); 9164 return null; 9165 } 9166 9167 boolean decProviderCountLocked(ContentProviderConnection conn, 9168 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9169 if (conn != null) { 9170 cpr = conn.provider; 9171 if (DEBUG_PROVIDER) Slog.v(TAG, 9172 "Removing provider requested by " 9173 + conn.client.processName + " from process " 9174 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9175 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9176 if (stable) { 9177 conn.stableCount--; 9178 } else { 9179 conn.unstableCount--; 9180 } 9181 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9182 cpr.connections.remove(conn); 9183 conn.client.conProviders.remove(conn); 9184 return true; 9185 } 9186 return false; 9187 } 9188 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9189 return false; 9190 } 9191 9192 private void checkTime(long startTime, String where) { 9193 long now = SystemClock.elapsedRealtime(); 9194 if ((now-startTime) > 1000) { 9195 // If we are taking more than a second, log about it. 9196 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9197 } 9198 } 9199 9200 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9201 String name, IBinder token, boolean stable, int userId) { 9202 ContentProviderRecord cpr; 9203 ContentProviderConnection conn = null; 9204 ProviderInfo cpi = null; 9205 9206 synchronized(this) { 9207 long startTime = SystemClock.elapsedRealtime(); 9208 9209 ProcessRecord r = null; 9210 if (caller != null) { 9211 r = getRecordForAppLocked(caller); 9212 if (r == null) { 9213 throw new SecurityException( 9214 "Unable to find app for caller " + caller 9215 + " (pid=" + Binder.getCallingPid() 9216 + ") when getting content provider " + name); 9217 } 9218 } 9219 9220 boolean checkCrossUser = true; 9221 9222 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9223 9224 // First check if this content provider has been published... 9225 cpr = mProviderMap.getProviderByName(name, userId); 9226 // If that didn't work, check if it exists for user 0 and then 9227 // verify that it's a singleton provider before using it. 9228 if (cpr == null && userId != UserHandle.USER_OWNER) { 9229 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9230 if (cpr != null) { 9231 cpi = cpr.info; 9232 if (isSingleton(cpi.processName, cpi.applicationInfo, 9233 cpi.name, cpi.flags) 9234 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9235 userId = UserHandle.USER_OWNER; 9236 checkCrossUser = false; 9237 } else { 9238 cpr = null; 9239 cpi = null; 9240 } 9241 } 9242 } 9243 9244 boolean providerRunning = cpr != null; 9245 if (providerRunning) { 9246 cpi = cpr.info; 9247 String msg; 9248 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9249 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9250 != null) { 9251 throw new SecurityException(msg); 9252 } 9253 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9254 9255 if (r != null && cpr.canRunHere(r)) { 9256 // This provider has been published or is in the process 9257 // of being published... but it is also allowed to run 9258 // in the caller's process, so don't make a connection 9259 // and just let the caller instantiate its own instance. 9260 ContentProviderHolder holder = cpr.newHolder(null); 9261 // don't give caller the provider object, it needs 9262 // to make its own. 9263 holder.provider = null; 9264 return holder; 9265 } 9266 9267 final long origId = Binder.clearCallingIdentity(); 9268 9269 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9270 9271 // In this case the provider instance already exists, so we can 9272 // return it right away. 9273 conn = incProviderCountLocked(r, cpr, token, stable); 9274 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9275 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9276 // If this is a perceptible app accessing the provider, 9277 // make sure to count it as being accessed and thus 9278 // back up on the LRU list. This is good because 9279 // content providers are often expensive to start. 9280 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9281 updateLruProcessLocked(cpr.proc, false, null); 9282 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9283 } 9284 } 9285 9286 if (cpr.proc != null) { 9287 if (false) { 9288 if (cpr.name.flattenToShortString().equals( 9289 "com.android.providers.calendar/.CalendarProvider2")) { 9290 Slog.v(TAG, "****************** KILLING " 9291 + cpr.name.flattenToShortString()); 9292 Process.killProcess(cpr.proc.pid); 9293 } 9294 } 9295 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9296 boolean success = updateOomAdjLocked(cpr.proc); 9297 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9298 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9299 // NOTE: there is still a race here where a signal could be 9300 // pending on the process even though we managed to update its 9301 // adj level. Not sure what to do about this, but at least 9302 // the race is now smaller. 9303 if (!success) { 9304 // Uh oh... it looks like the provider's process 9305 // has been killed on us. We need to wait for a new 9306 // process to be started, and make sure its death 9307 // doesn't kill our process. 9308 Slog.i(TAG, 9309 "Existing provider " + cpr.name.flattenToShortString() 9310 + " is crashing; detaching " + r); 9311 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9312 checkTime(startTime, "getContentProviderImpl: before appDied"); 9313 appDiedLocked(cpr.proc); 9314 checkTime(startTime, "getContentProviderImpl: after appDied"); 9315 if (!lastRef) { 9316 // This wasn't the last ref our process had on 9317 // the provider... we have now been killed, bail. 9318 return null; 9319 } 9320 providerRunning = false; 9321 conn = null; 9322 } 9323 } 9324 9325 Binder.restoreCallingIdentity(origId); 9326 } 9327 9328 boolean singleton; 9329 if (!providerRunning) { 9330 try { 9331 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9332 cpi = AppGlobals.getPackageManager(). 9333 resolveContentProvider(name, 9334 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9335 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9336 } catch (RemoteException ex) { 9337 } 9338 if (cpi == null) { 9339 return null; 9340 } 9341 // If the provider is a singleton AND 9342 // (it's a call within the same user || the provider is a 9343 // privileged app) 9344 // Then allow connecting to the singleton provider 9345 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9346 cpi.name, cpi.flags) 9347 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9348 if (singleton) { 9349 userId = UserHandle.USER_OWNER; 9350 } 9351 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9352 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9353 9354 String msg; 9355 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9356 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9357 != null) { 9358 throw new SecurityException(msg); 9359 } 9360 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9361 9362 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9363 && !cpi.processName.equals("system")) { 9364 // If this content provider does not run in the system 9365 // process, and the system is not yet ready to run other 9366 // processes, then fail fast instead of hanging. 9367 throw new IllegalArgumentException( 9368 "Attempt to launch content provider before system ready"); 9369 } 9370 9371 // Make sure that the user who owns this provider is started. If not, 9372 // we don't want to allow it to run. 9373 if (mStartedUsers.get(userId) == null) { 9374 Slog.w(TAG, "Unable to launch app " 9375 + cpi.applicationInfo.packageName + "/" 9376 + cpi.applicationInfo.uid + " for provider " 9377 + name + ": user " + userId + " is stopped"); 9378 return null; 9379 } 9380 9381 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9382 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9383 cpr = mProviderMap.getProviderByClass(comp, userId); 9384 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9385 final boolean firstClass = cpr == null; 9386 if (firstClass) { 9387 final long ident = Binder.clearCallingIdentity(); 9388 try { 9389 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9390 ApplicationInfo ai = 9391 AppGlobals.getPackageManager(). 9392 getApplicationInfo( 9393 cpi.applicationInfo.packageName, 9394 STOCK_PM_FLAGS, userId); 9395 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9396 if (ai == null) { 9397 Slog.w(TAG, "No package info for content provider " 9398 + cpi.name); 9399 return null; 9400 } 9401 ai = getAppInfoForUser(ai, userId); 9402 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9403 } catch (RemoteException ex) { 9404 // pm is in same process, this will never happen. 9405 } finally { 9406 Binder.restoreCallingIdentity(ident); 9407 } 9408 } 9409 9410 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9411 9412 if (r != null && cpr.canRunHere(r)) { 9413 // If this is a multiprocess provider, then just return its 9414 // info and allow the caller to instantiate it. Only do 9415 // this if the provider is the same user as the caller's 9416 // process, or can run as root (so can be in any process). 9417 return cpr.newHolder(null); 9418 } 9419 9420 if (DEBUG_PROVIDER) { 9421 RuntimeException e = new RuntimeException("here"); 9422 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9423 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9424 } 9425 9426 // This is single process, and our app is now connecting to it. 9427 // See if we are already in the process of launching this 9428 // provider. 9429 final int N = mLaunchingProviders.size(); 9430 int i; 9431 for (i=0; i<N; i++) { 9432 if (mLaunchingProviders.get(i) == cpr) { 9433 break; 9434 } 9435 } 9436 9437 // If the provider is not already being launched, then get it 9438 // started. 9439 if (i >= N) { 9440 final long origId = Binder.clearCallingIdentity(); 9441 9442 try { 9443 // Content provider is now in use, its package can't be stopped. 9444 try { 9445 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9446 AppGlobals.getPackageManager().setPackageStoppedState( 9447 cpr.appInfo.packageName, false, userId); 9448 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9449 } catch (RemoteException e) { 9450 } catch (IllegalArgumentException e) { 9451 Slog.w(TAG, "Failed trying to unstop package " 9452 + cpr.appInfo.packageName + ": " + e); 9453 } 9454 9455 // Use existing process if already started 9456 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9457 ProcessRecord proc = getProcessRecordLocked( 9458 cpi.processName, cpr.appInfo.uid, false); 9459 if (proc != null && proc.thread != null) { 9460 if (DEBUG_PROVIDER) { 9461 Slog.d(TAG, "Installing in existing process " + proc); 9462 } 9463 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9464 proc.pubProviders.put(cpi.name, cpr); 9465 try { 9466 proc.thread.scheduleInstallProvider(cpi); 9467 } catch (RemoteException e) { 9468 } 9469 } else { 9470 checkTime(startTime, "getContentProviderImpl: before start process"); 9471 proc = startProcessLocked(cpi.processName, 9472 cpr.appInfo, false, 0, "content provider", 9473 new ComponentName(cpi.applicationInfo.packageName, 9474 cpi.name), false, false, false); 9475 checkTime(startTime, "getContentProviderImpl: after start process"); 9476 if (proc == null) { 9477 Slog.w(TAG, "Unable to launch app " 9478 + cpi.applicationInfo.packageName + "/" 9479 + cpi.applicationInfo.uid + " for provider " 9480 + name + ": process is bad"); 9481 return null; 9482 } 9483 } 9484 cpr.launchingApp = proc; 9485 mLaunchingProviders.add(cpr); 9486 } finally { 9487 Binder.restoreCallingIdentity(origId); 9488 } 9489 } 9490 9491 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9492 9493 // Make sure the provider is published (the same provider class 9494 // may be published under multiple names). 9495 if (firstClass) { 9496 mProviderMap.putProviderByClass(comp, cpr); 9497 } 9498 9499 mProviderMap.putProviderByName(name, cpr); 9500 conn = incProviderCountLocked(r, cpr, token, stable); 9501 if (conn != null) { 9502 conn.waiting = true; 9503 } 9504 } 9505 checkTime(startTime, "getContentProviderImpl: done!"); 9506 } 9507 9508 // Wait for the provider to be published... 9509 synchronized (cpr) { 9510 while (cpr.provider == null) { 9511 if (cpr.launchingApp == null) { 9512 Slog.w(TAG, "Unable to launch app " 9513 + cpi.applicationInfo.packageName + "/" 9514 + cpi.applicationInfo.uid + " for provider " 9515 + name + ": launching app became null"); 9516 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9517 UserHandle.getUserId(cpi.applicationInfo.uid), 9518 cpi.applicationInfo.packageName, 9519 cpi.applicationInfo.uid, name); 9520 return null; 9521 } 9522 try { 9523 if (DEBUG_MU) { 9524 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9525 + cpr.launchingApp); 9526 } 9527 if (conn != null) { 9528 conn.waiting = true; 9529 } 9530 cpr.wait(); 9531 } catch (InterruptedException ex) { 9532 } finally { 9533 if (conn != null) { 9534 conn.waiting = false; 9535 } 9536 } 9537 } 9538 } 9539 return cpr != null ? cpr.newHolder(conn) : null; 9540 } 9541 9542 @Override 9543 public final ContentProviderHolder getContentProvider( 9544 IApplicationThread caller, String name, int userId, boolean stable) { 9545 enforceNotIsolatedCaller("getContentProvider"); 9546 if (caller == null) { 9547 String msg = "null IApplicationThread when getting content provider " 9548 + name; 9549 Slog.w(TAG, msg); 9550 throw new SecurityException(msg); 9551 } 9552 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9553 // with cross-user grant. 9554 return getContentProviderImpl(caller, name, null, stable, userId); 9555 } 9556 9557 public ContentProviderHolder getContentProviderExternal( 9558 String name, int userId, IBinder token) { 9559 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9560 "Do not have permission in call getContentProviderExternal()"); 9561 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9562 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9563 return getContentProviderExternalUnchecked(name, token, userId); 9564 } 9565 9566 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9567 IBinder token, int userId) { 9568 return getContentProviderImpl(null, name, token, true, userId); 9569 } 9570 9571 /** 9572 * Drop a content provider from a ProcessRecord's bookkeeping 9573 */ 9574 public void removeContentProvider(IBinder connection, boolean stable) { 9575 enforceNotIsolatedCaller("removeContentProvider"); 9576 long ident = Binder.clearCallingIdentity(); 9577 try { 9578 synchronized (this) { 9579 ContentProviderConnection conn; 9580 try { 9581 conn = (ContentProviderConnection)connection; 9582 } catch (ClassCastException e) { 9583 String msg ="removeContentProvider: " + connection 9584 + " not a ContentProviderConnection"; 9585 Slog.w(TAG, msg); 9586 throw new IllegalArgumentException(msg); 9587 } 9588 if (conn == null) { 9589 throw new NullPointerException("connection is null"); 9590 } 9591 if (decProviderCountLocked(conn, null, null, stable)) { 9592 updateOomAdjLocked(); 9593 } 9594 } 9595 } finally { 9596 Binder.restoreCallingIdentity(ident); 9597 } 9598 } 9599 9600 public void removeContentProviderExternal(String name, IBinder token) { 9601 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9602 "Do not have permission in call removeContentProviderExternal()"); 9603 int userId = UserHandle.getCallingUserId(); 9604 long ident = Binder.clearCallingIdentity(); 9605 try { 9606 removeContentProviderExternalUnchecked(name, token, userId); 9607 } finally { 9608 Binder.restoreCallingIdentity(ident); 9609 } 9610 } 9611 9612 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9613 synchronized (this) { 9614 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9615 if(cpr == null) { 9616 //remove from mProvidersByClass 9617 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9618 return; 9619 } 9620 9621 //update content provider record entry info 9622 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9623 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9624 if (localCpr.hasExternalProcessHandles()) { 9625 if (localCpr.removeExternalProcessHandleLocked(token)) { 9626 updateOomAdjLocked(); 9627 } else { 9628 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9629 + " with no external reference for token: " 9630 + token + "."); 9631 } 9632 } else { 9633 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9634 + " with no external references."); 9635 } 9636 } 9637 } 9638 9639 public final void publishContentProviders(IApplicationThread caller, 9640 List<ContentProviderHolder> providers) { 9641 if (providers == null) { 9642 return; 9643 } 9644 9645 enforceNotIsolatedCaller("publishContentProviders"); 9646 synchronized (this) { 9647 final ProcessRecord r = getRecordForAppLocked(caller); 9648 if (DEBUG_MU) 9649 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9650 if (r == null) { 9651 throw new SecurityException( 9652 "Unable to find app for caller " + caller 9653 + " (pid=" + Binder.getCallingPid() 9654 + ") when publishing content providers"); 9655 } 9656 9657 final long origId = Binder.clearCallingIdentity(); 9658 9659 final int N = providers.size(); 9660 for (int i=0; i<N; i++) { 9661 ContentProviderHolder src = providers.get(i); 9662 if (src == null || src.info == null || src.provider == null) { 9663 continue; 9664 } 9665 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9666 if (DEBUG_MU) 9667 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9668 if (dst != null) { 9669 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9670 mProviderMap.putProviderByClass(comp, dst); 9671 String names[] = dst.info.authority.split(";"); 9672 for (int j = 0; j < names.length; j++) { 9673 mProviderMap.putProviderByName(names[j], dst); 9674 } 9675 9676 int NL = mLaunchingProviders.size(); 9677 int j; 9678 for (j=0; j<NL; j++) { 9679 if (mLaunchingProviders.get(j) == dst) { 9680 mLaunchingProviders.remove(j); 9681 j--; 9682 NL--; 9683 } 9684 } 9685 synchronized (dst) { 9686 dst.provider = src.provider; 9687 dst.proc = r; 9688 dst.notifyAll(); 9689 } 9690 updateOomAdjLocked(r); 9691 } 9692 } 9693 9694 Binder.restoreCallingIdentity(origId); 9695 } 9696 } 9697 9698 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9699 ContentProviderConnection conn; 9700 try { 9701 conn = (ContentProviderConnection)connection; 9702 } catch (ClassCastException e) { 9703 String msg ="refContentProvider: " + connection 9704 + " not a ContentProviderConnection"; 9705 Slog.w(TAG, msg); 9706 throw new IllegalArgumentException(msg); 9707 } 9708 if (conn == null) { 9709 throw new NullPointerException("connection is null"); 9710 } 9711 9712 synchronized (this) { 9713 if (stable > 0) { 9714 conn.numStableIncs += stable; 9715 } 9716 stable = conn.stableCount + stable; 9717 if (stable < 0) { 9718 throw new IllegalStateException("stableCount < 0: " + stable); 9719 } 9720 9721 if (unstable > 0) { 9722 conn.numUnstableIncs += unstable; 9723 } 9724 unstable = conn.unstableCount + unstable; 9725 if (unstable < 0) { 9726 throw new IllegalStateException("unstableCount < 0: " + unstable); 9727 } 9728 9729 if ((stable+unstable) <= 0) { 9730 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9731 + stable + " unstable=" + unstable); 9732 } 9733 conn.stableCount = stable; 9734 conn.unstableCount = unstable; 9735 return !conn.dead; 9736 } 9737 } 9738 9739 public void unstableProviderDied(IBinder connection) { 9740 ContentProviderConnection conn; 9741 try { 9742 conn = (ContentProviderConnection)connection; 9743 } catch (ClassCastException e) { 9744 String msg ="refContentProvider: " + connection 9745 + " not a ContentProviderConnection"; 9746 Slog.w(TAG, msg); 9747 throw new IllegalArgumentException(msg); 9748 } 9749 if (conn == null) { 9750 throw new NullPointerException("connection is null"); 9751 } 9752 9753 // Safely retrieve the content provider associated with the connection. 9754 IContentProvider provider; 9755 synchronized (this) { 9756 provider = conn.provider.provider; 9757 } 9758 9759 if (provider == null) { 9760 // Um, yeah, we're way ahead of you. 9761 return; 9762 } 9763 9764 // Make sure the caller is being honest with us. 9765 if (provider.asBinder().pingBinder()) { 9766 // Er, no, still looks good to us. 9767 synchronized (this) { 9768 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9769 + " says " + conn + " died, but we don't agree"); 9770 return; 9771 } 9772 } 9773 9774 // Well look at that! It's dead! 9775 synchronized (this) { 9776 if (conn.provider.provider != provider) { 9777 // But something changed... good enough. 9778 return; 9779 } 9780 9781 ProcessRecord proc = conn.provider.proc; 9782 if (proc == null || proc.thread == null) { 9783 // Seems like the process is already cleaned up. 9784 return; 9785 } 9786 9787 // As far as we're concerned, this is just like receiving a 9788 // death notification... just a bit prematurely. 9789 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9790 + ") early provider death"); 9791 final long ident = Binder.clearCallingIdentity(); 9792 try { 9793 appDiedLocked(proc); 9794 } finally { 9795 Binder.restoreCallingIdentity(ident); 9796 } 9797 } 9798 } 9799 9800 @Override 9801 public void appNotRespondingViaProvider(IBinder connection) { 9802 enforceCallingPermission( 9803 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9804 9805 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9806 if (conn == null) { 9807 Slog.w(TAG, "ContentProviderConnection is null"); 9808 return; 9809 } 9810 9811 final ProcessRecord host = conn.provider.proc; 9812 if (host == null) { 9813 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9814 return; 9815 } 9816 9817 final long token = Binder.clearCallingIdentity(); 9818 try { 9819 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9820 } finally { 9821 Binder.restoreCallingIdentity(token); 9822 } 9823 } 9824 9825 public final void installSystemProviders() { 9826 List<ProviderInfo> providers; 9827 synchronized (this) { 9828 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9829 providers = generateApplicationProvidersLocked(app); 9830 if (providers != null) { 9831 for (int i=providers.size()-1; i>=0; i--) { 9832 ProviderInfo pi = (ProviderInfo)providers.get(i); 9833 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9834 Slog.w(TAG, "Not installing system proc provider " + pi.name 9835 + ": not system .apk"); 9836 providers.remove(i); 9837 } 9838 } 9839 } 9840 } 9841 if (providers != null) { 9842 mSystemThread.installSystemProviders(providers); 9843 } 9844 9845 mCoreSettingsObserver = new CoreSettingsObserver(this); 9846 9847 //mUsageStatsService.monitorPackages(); 9848 } 9849 9850 /** 9851 * Allows apps to retrieve the MIME type of a URI. 9852 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9853 * users, then it does not need permission to access the ContentProvider. 9854 * Either, it needs cross-user uri grants. 9855 * 9856 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9857 * 9858 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9859 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9860 */ 9861 public String getProviderMimeType(Uri uri, int userId) { 9862 enforceNotIsolatedCaller("getProviderMimeType"); 9863 final String name = uri.getAuthority(); 9864 int callingUid = Binder.getCallingUid(); 9865 int callingPid = Binder.getCallingPid(); 9866 long ident = 0; 9867 boolean clearedIdentity = false; 9868 userId = unsafeConvertIncomingUser(userId); 9869 if (canClearIdentity(callingPid, callingUid, userId)) { 9870 clearedIdentity = true; 9871 ident = Binder.clearCallingIdentity(); 9872 } 9873 ContentProviderHolder holder = null; 9874 try { 9875 holder = getContentProviderExternalUnchecked(name, null, userId); 9876 if (holder != null) { 9877 return holder.provider.getType(uri); 9878 } 9879 } catch (RemoteException e) { 9880 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9881 return null; 9882 } finally { 9883 // We need to clear the identity to call removeContentProviderExternalUnchecked 9884 if (!clearedIdentity) { 9885 ident = Binder.clearCallingIdentity(); 9886 } 9887 try { 9888 if (holder != null) { 9889 removeContentProviderExternalUnchecked(name, null, userId); 9890 } 9891 } finally { 9892 Binder.restoreCallingIdentity(ident); 9893 } 9894 } 9895 9896 return null; 9897 } 9898 9899 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9900 if (UserHandle.getUserId(callingUid) == userId) { 9901 return true; 9902 } 9903 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9904 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9905 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9906 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9907 return true; 9908 } 9909 return false; 9910 } 9911 9912 // ========================================================= 9913 // GLOBAL MANAGEMENT 9914 // ========================================================= 9915 9916 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9917 boolean isolated, int isolatedUid) { 9918 String proc = customProcess != null ? customProcess : info.processName; 9919 BatteryStatsImpl.Uid.Proc ps = null; 9920 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9921 int uid = info.uid; 9922 if (isolated) { 9923 if (isolatedUid == 0) { 9924 int userId = UserHandle.getUserId(uid); 9925 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9926 while (true) { 9927 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9928 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9929 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9930 } 9931 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9932 mNextIsolatedProcessUid++; 9933 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9934 // No process for this uid, use it. 9935 break; 9936 } 9937 stepsLeft--; 9938 if (stepsLeft <= 0) { 9939 return null; 9940 } 9941 } 9942 } else { 9943 // Special case for startIsolatedProcess (internal only), where 9944 // the uid of the isolated process is specified by the caller. 9945 uid = isolatedUid; 9946 } 9947 } 9948 return new ProcessRecord(stats, info, proc, uid); 9949 } 9950 9951 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9952 String abiOverride) { 9953 ProcessRecord app; 9954 if (!isolated) { 9955 app = getProcessRecordLocked(info.processName, info.uid, true); 9956 } else { 9957 app = null; 9958 } 9959 9960 if (app == null) { 9961 app = newProcessRecordLocked(info, null, isolated, 0); 9962 mProcessNames.put(info.processName, app.uid, app); 9963 if (isolated) { 9964 mIsolatedProcesses.put(app.uid, app); 9965 } 9966 updateLruProcessLocked(app, false, null); 9967 updateOomAdjLocked(); 9968 } 9969 9970 // This package really, really can not be stopped. 9971 try { 9972 AppGlobals.getPackageManager().setPackageStoppedState( 9973 info.packageName, false, UserHandle.getUserId(app.uid)); 9974 } catch (RemoteException e) { 9975 } catch (IllegalArgumentException e) { 9976 Slog.w(TAG, "Failed trying to unstop package " 9977 + info.packageName + ": " + e); 9978 } 9979 9980 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9981 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9982 app.persistent = true; 9983 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9984 } 9985 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9986 mPersistentStartingProcesses.add(app); 9987 startProcessLocked(app, "added application", app.processName, abiOverride, 9988 null /* entryPoint */, null /* entryPointArgs */); 9989 } 9990 9991 return app; 9992 } 9993 9994 public void unhandledBack() { 9995 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9996 "unhandledBack()"); 9997 9998 synchronized(this) { 9999 final long origId = Binder.clearCallingIdentity(); 10000 try { 10001 getFocusedStack().unhandledBackLocked(); 10002 } finally { 10003 Binder.restoreCallingIdentity(origId); 10004 } 10005 } 10006 } 10007 10008 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10009 enforceNotIsolatedCaller("openContentUri"); 10010 final int userId = UserHandle.getCallingUserId(); 10011 String name = uri.getAuthority(); 10012 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10013 ParcelFileDescriptor pfd = null; 10014 if (cph != null) { 10015 // We record the binder invoker's uid in thread-local storage before 10016 // going to the content provider to open the file. Later, in the code 10017 // that handles all permissions checks, we look for this uid and use 10018 // that rather than the Activity Manager's own uid. The effect is that 10019 // we do the check against the caller's permissions even though it looks 10020 // to the content provider like the Activity Manager itself is making 10021 // the request. 10022 sCallerIdentity.set(new Identity( 10023 Binder.getCallingPid(), Binder.getCallingUid())); 10024 try { 10025 pfd = cph.provider.openFile(null, uri, "r", null); 10026 } catch (FileNotFoundException e) { 10027 // do nothing; pfd will be returned null 10028 } finally { 10029 // Ensure that whatever happens, we clean up the identity state 10030 sCallerIdentity.remove(); 10031 } 10032 10033 // We've got the fd now, so we're done with the provider. 10034 removeContentProviderExternalUnchecked(name, null, userId); 10035 } else { 10036 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10037 } 10038 return pfd; 10039 } 10040 10041 // Actually is sleeping or shutting down or whatever else in the future 10042 // is an inactive state. 10043 public boolean isSleepingOrShuttingDown() { 10044 return isSleeping() || mShuttingDown; 10045 } 10046 10047 public boolean isSleeping() { 10048 return mSleeping; 10049 } 10050 10051 void goingToSleep() { 10052 synchronized(this) { 10053 mWentToSleep = true; 10054 goToSleepIfNeededLocked(); 10055 } 10056 } 10057 10058 void finishRunningVoiceLocked() { 10059 if (mRunningVoice) { 10060 mRunningVoice = false; 10061 goToSleepIfNeededLocked(); 10062 } 10063 } 10064 10065 void goToSleepIfNeededLocked() { 10066 if (mWentToSleep && !mRunningVoice) { 10067 if (!mSleeping) { 10068 mSleeping = true; 10069 mStackSupervisor.goingToSleepLocked(); 10070 10071 // Initialize the wake times of all processes. 10072 checkExcessivePowerUsageLocked(false); 10073 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10074 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10075 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10076 } 10077 } 10078 } 10079 10080 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10081 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10082 // Never persist the home stack. 10083 return; 10084 } 10085 mTaskPersister.wakeup(task, flush); 10086 } 10087 10088 @Override 10089 public boolean shutdown(int timeout) { 10090 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10091 != PackageManager.PERMISSION_GRANTED) { 10092 throw new SecurityException("Requires permission " 10093 + android.Manifest.permission.SHUTDOWN); 10094 } 10095 10096 boolean timedout = false; 10097 10098 synchronized(this) { 10099 mShuttingDown = true; 10100 updateEventDispatchingLocked(); 10101 timedout = mStackSupervisor.shutdownLocked(timeout); 10102 } 10103 10104 mAppOpsService.shutdown(); 10105 if (mUsageStatsService != null) { 10106 mUsageStatsService.prepareShutdown(); 10107 } 10108 mBatteryStatsService.shutdown(); 10109 synchronized (this) { 10110 mProcessStats.shutdownLocked(); 10111 } 10112 notifyTaskPersisterLocked(null, true); 10113 10114 return timedout; 10115 } 10116 10117 public final void activitySlept(IBinder token) { 10118 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10119 10120 final long origId = Binder.clearCallingIdentity(); 10121 10122 synchronized (this) { 10123 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10124 if (r != null) { 10125 mStackSupervisor.activitySleptLocked(r); 10126 } 10127 } 10128 10129 Binder.restoreCallingIdentity(origId); 10130 } 10131 10132 void logLockScreen(String msg) { 10133 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10134 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10135 mWentToSleep + " mSleeping=" + mSleeping); 10136 } 10137 10138 private void comeOutOfSleepIfNeededLocked() { 10139 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10140 if (mSleeping) { 10141 mSleeping = false; 10142 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10143 } 10144 } 10145 } 10146 10147 void wakingUp() { 10148 synchronized(this) { 10149 mWentToSleep = false; 10150 comeOutOfSleepIfNeededLocked(); 10151 } 10152 } 10153 10154 void startRunningVoiceLocked() { 10155 if (!mRunningVoice) { 10156 mRunningVoice = true; 10157 comeOutOfSleepIfNeededLocked(); 10158 } 10159 } 10160 10161 private void updateEventDispatchingLocked() { 10162 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10163 } 10164 10165 public void setLockScreenShown(boolean shown) { 10166 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10167 != PackageManager.PERMISSION_GRANTED) { 10168 throw new SecurityException("Requires permission " 10169 + android.Manifest.permission.DEVICE_POWER); 10170 } 10171 10172 synchronized(this) { 10173 long ident = Binder.clearCallingIdentity(); 10174 try { 10175 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10176 mLockScreenShown = shown; 10177 comeOutOfSleepIfNeededLocked(); 10178 } finally { 10179 Binder.restoreCallingIdentity(ident); 10180 } 10181 } 10182 } 10183 10184 @Override 10185 public void stopAppSwitches() { 10186 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10187 != PackageManager.PERMISSION_GRANTED) { 10188 throw new SecurityException("Requires permission " 10189 + android.Manifest.permission.STOP_APP_SWITCHES); 10190 } 10191 10192 synchronized(this) { 10193 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10194 + APP_SWITCH_DELAY_TIME; 10195 mDidAppSwitch = false; 10196 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10197 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10198 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10199 } 10200 } 10201 10202 public void resumeAppSwitches() { 10203 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10204 != PackageManager.PERMISSION_GRANTED) { 10205 throw new SecurityException("Requires permission " 10206 + android.Manifest.permission.STOP_APP_SWITCHES); 10207 } 10208 10209 synchronized(this) { 10210 // Note that we don't execute any pending app switches... we will 10211 // let those wait until either the timeout, or the next start 10212 // activity request. 10213 mAppSwitchesAllowedTime = 0; 10214 } 10215 } 10216 10217 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10218 int callingPid, int callingUid, String name) { 10219 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10220 return true; 10221 } 10222 10223 int perm = checkComponentPermission( 10224 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10225 sourceUid, -1, true); 10226 if (perm == PackageManager.PERMISSION_GRANTED) { 10227 return true; 10228 } 10229 10230 // If the actual IPC caller is different from the logical source, then 10231 // also see if they are allowed to control app switches. 10232 if (callingUid != -1 && callingUid != sourceUid) { 10233 perm = checkComponentPermission( 10234 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10235 callingUid, -1, true); 10236 if (perm == PackageManager.PERMISSION_GRANTED) { 10237 return true; 10238 } 10239 } 10240 10241 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10242 return false; 10243 } 10244 10245 public void setDebugApp(String packageName, boolean waitForDebugger, 10246 boolean persistent) { 10247 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10248 "setDebugApp()"); 10249 10250 long ident = Binder.clearCallingIdentity(); 10251 try { 10252 // Note that this is not really thread safe if there are multiple 10253 // callers into it at the same time, but that's not a situation we 10254 // care about. 10255 if (persistent) { 10256 final ContentResolver resolver = mContext.getContentResolver(); 10257 Settings.Global.putString( 10258 resolver, Settings.Global.DEBUG_APP, 10259 packageName); 10260 Settings.Global.putInt( 10261 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10262 waitForDebugger ? 1 : 0); 10263 } 10264 10265 synchronized (this) { 10266 if (!persistent) { 10267 mOrigDebugApp = mDebugApp; 10268 mOrigWaitForDebugger = mWaitForDebugger; 10269 } 10270 mDebugApp = packageName; 10271 mWaitForDebugger = waitForDebugger; 10272 mDebugTransient = !persistent; 10273 if (packageName != null) { 10274 forceStopPackageLocked(packageName, -1, false, false, true, true, 10275 false, UserHandle.USER_ALL, "set debug app"); 10276 } 10277 } 10278 } finally { 10279 Binder.restoreCallingIdentity(ident); 10280 } 10281 } 10282 10283 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10284 synchronized (this) { 10285 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10286 if (!isDebuggable) { 10287 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10288 throw new SecurityException("Process not debuggable: " + app.packageName); 10289 } 10290 } 10291 10292 mOpenGlTraceApp = processName; 10293 } 10294 } 10295 10296 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10297 synchronized (this) { 10298 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10299 if (!isDebuggable) { 10300 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10301 throw new SecurityException("Process not debuggable: " + app.packageName); 10302 } 10303 } 10304 mProfileApp = processName; 10305 mProfileFile = profilerInfo.profileFile; 10306 if (mProfileFd != null) { 10307 try { 10308 mProfileFd.close(); 10309 } catch (IOException e) { 10310 } 10311 mProfileFd = null; 10312 } 10313 mProfileFd = profilerInfo.profileFd; 10314 mSamplingInterval = profilerInfo.samplingInterval; 10315 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10316 mProfileType = 0; 10317 } 10318 } 10319 10320 @Override 10321 public void setAlwaysFinish(boolean enabled) { 10322 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10323 "setAlwaysFinish()"); 10324 10325 Settings.Global.putInt( 10326 mContext.getContentResolver(), 10327 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10328 10329 synchronized (this) { 10330 mAlwaysFinishActivities = enabled; 10331 } 10332 } 10333 10334 @Override 10335 public void setActivityController(IActivityController controller) { 10336 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10337 "setActivityController()"); 10338 synchronized (this) { 10339 mController = controller; 10340 Watchdog.getInstance().setActivityController(controller); 10341 } 10342 } 10343 10344 @Override 10345 public void setUserIsMonkey(boolean userIsMonkey) { 10346 synchronized (this) { 10347 synchronized (mPidsSelfLocked) { 10348 final int callingPid = Binder.getCallingPid(); 10349 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10350 if (precessRecord == null) { 10351 throw new SecurityException("Unknown process: " + callingPid); 10352 } 10353 if (precessRecord.instrumentationUiAutomationConnection == null) { 10354 throw new SecurityException("Only an instrumentation process " 10355 + "with a UiAutomation can call setUserIsMonkey"); 10356 } 10357 } 10358 mUserIsMonkey = userIsMonkey; 10359 } 10360 } 10361 10362 @Override 10363 public boolean isUserAMonkey() { 10364 synchronized (this) { 10365 // If there is a controller also implies the user is a monkey. 10366 return (mUserIsMonkey || mController != null); 10367 } 10368 } 10369 10370 public void requestBugReport() { 10371 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10372 SystemProperties.set("ctl.start", "bugreport"); 10373 } 10374 10375 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10376 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10377 } 10378 10379 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10380 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10381 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10382 } 10383 return KEY_DISPATCHING_TIMEOUT; 10384 } 10385 10386 @Override 10387 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10388 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10389 != PackageManager.PERMISSION_GRANTED) { 10390 throw new SecurityException("Requires permission " 10391 + android.Manifest.permission.FILTER_EVENTS); 10392 } 10393 ProcessRecord proc; 10394 long timeout; 10395 synchronized (this) { 10396 synchronized (mPidsSelfLocked) { 10397 proc = mPidsSelfLocked.get(pid); 10398 } 10399 timeout = getInputDispatchingTimeoutLocked(proc); 10400 } 10401 10402 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10403 return -1; 10404 } 10405 10406 return timeout; 10407 } 10408 10409 /** 10410 * Handle input dispatching timeouts. 10411 * Returns whether input dispatching should be aborted or not. 10412 */ 10413 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10414 final ActivityRecord activity, final ActivityRecord parent, 10415 final boolean aboveSystem, String reason) { 10416 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10417 != PackageManager.PERMISSION_GRANTED) { 10418 throw new SecurityException("Requires permission " 10419 + android.Manifest.permission.FILTER_EVENTS); 10420 } 10421 10422 final String annotation; 10423 if (reason == null) { 10424 annotation = "Input dispatching timed out"; 10425 } else { 10426 annotation = "Input dispatching timed out (" + reason + ")"; 10427 } 10428 10429 if (proc != null) { 10430 synchronized (this) { 10431 if (proc.debugging) { 10432 return false; 10433 } 10434 10435 if (mDidDexOpt) { 10436 // Give more time since we were dexopting. 10437 mDidDexOpt = false; 10438 return false; 10439 } 10440 10441 if (proc.instrumentationClass != null) { 10442 Bundle info = new Bundle(); 10443 info.putString("shortMsg", "keyDispatchingTimedOut"); 10444 info.putString("longMsg", annotation); 10445 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10446 return true; 10447 } 10448 } 10449 mHandler.post(new Runnable() { 10450 @Override 10451 public void run() { 10452 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10453 } 10454 }); 10455 } 10456 10457 return true; 10458 } 10459 10460 public Bundle getAssistContextExtras(int requestType) { 10461 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10462 UserHandle.getCallingUserId()); 10463 if (pae == null) { 10464 return null; 10465 } 10466 synchronized (pae) { 10467 while (!pae.haveResult) { 10468 try { 10469 pae.wait(); 10470 } catch (InterruptedException e) { 10471 } 10472 } 10473 if (pae.result != null) { 10474 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10475 } 10476 } 10477 synchronized (this) { 10478 mPendingAssistExtras.remove(pae); 10479 mHandler.removeCallbacks(pae); 10480 } 10481 return pae.extras; 10482 } 10483 10484 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10485 int userHandle) { 10486 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10487 "getAssistContextExtras()"); 10488 PendingAssistExtras pae; 10489 Bundle extras = new Bundle(); 10490 synchronized (this) { 10491 ActivityRecord activity = getFocusedStack().mResumedActivity; 10492 if (activity == null) { 10493 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10494 return null; 10495 } 10496 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10497 if (activity.app == null || activity.app.thread == null) { 10498 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10499 return null; 10500 } 10501 if (activity.app.pid == Binder.getCallingPid()) { 10502 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10503 return null; 10504 } 10505 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10506 try { 10507 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10508 requestType); 10509 mPendingAssistExtras.add(pae); 10510 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10511 } catch (RemoteException e) { 10512 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10513 return null; 10514 } 10515 return pae; 10516 } 10517 } 10518 10519 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10520 PendingAssistExtras pae = (PendingAssistExtras)token; 10521 synchronized (pae) { 10522 pae.result = extras; 10523 pae.haveResult = true; 10524 pae.notifyAll(); 10525 if (pae.intent == null) { 10526 // Caller is just waiting for the result. 10527 return; 10528 } 10529 } 10530 10531 // We are now ready to launch the assist activity. 10532 synchronized (this) { 10533 boolean exists = mPendingAssistExtras.remove(pae); 10534 mHandler.removeCallbacks(pae); 10535 if (!exists) { 10536 // Timed out. 10537 return; 10538 } 10539 } 10540 pae.intent.replaceExtras(extras); 10541 if (pae.hint != null) { 10542 pae.intent.putExtra(pae.hint, true); 10543 } 10544 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10545 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10546 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10547 closeSystemDialogs("assist"); 10548 try { 10549 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10550 } catch (ActivityNotFoundException e) { 10551 Slog.w(TAG, "No activity to handle assist action.", e); 10552 } 10553 } 10554 10555 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10556 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10557 } 10558 10559 public void registerProcessObserver(IProcessObserver observer) { 10560 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10561 "registerProcessObserver()"); 10562 synchronized (this) { 10563 mProcessObservers.register(observer); 10564 } 10565 } 10566 10567 @Override 10568 public void unregisterProcessObserver(IProcessObserver observer) { 10569 synchronized (this) { 10570 mProcessObservers.unregister(observer); 10571 } 10572 } 10573 10574 @Override 10575 public boolean convertFromTranslucent(IBinder token) { 10576 final long origId = Binder.clearCallingIdentity(); 10577 try { 10578 synchronized (this) { 10579 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10580 if (r == null) { 10581 return false; 10582 } 10583 final boolean translucentChanged = r.changeWindowTranslucency(true); 10584 if (translucentChanged) { 10585 r.task.stack.releaseBackgroundResources(); 10586 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10587 } 10588 mWindowManager.setAppFullscreen(token, true); 10589 return translucentChanged; 10590 } 10591 } finally { 10592 Binder.restoreCallingIdentity(origId); 10593 } 10594 } 10595 10596 @Override 10597 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10598 final long origId = Binder.clearCallingIdentity(); 10599 try { 10600 synchronized (this) { 10601 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10602 if (r == null) { 10603 return false; 10604 } 10605 int index = r.task.mActivities.lastIndexOf(r); 10606 if (index > 0) { 10607 ActivityRecord under = r.task.mActivities.get(index - 1); 10608 under.returningOptions = options; 10609 } 10610 final boolean translucentChanged = r.changeWindowTranslucency(false); 10611 if (translucentChanged) { 10612 r.task.stack.convertToTranslucent(r); 10613 } 10614 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10615 mWindowManager.setAppFullscreen(token, false); 10616 return translucentChanged; 10617 } 10618 } finally { 10619 Binder.restoreCallingIdentity(origId); 10620 } 10621 } 10622 10623 @Override 10624 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10625 final long origId = Binder.clearCallingIdentity(); 10626 try { 10627 synchronized (this) { 10628 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10629 if (r != null) { 10630 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10631 } 10632 } 10633 return false; 10634 } finally { 10635 Binder.restoreCallingIdentity(origId); 10636 } 10637 } 10638 10639 @Override 10640 public boolean isBackgroundVisibleBehind(IBinder token) { 10641 final long origId = Binder.clearCallingIdentity(); 10642 try { 10643 synchronized (this) { 10644 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10645 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10646 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10647 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10648 return visible; 10649 } 10650 } finally { 10651 Binder.restoreCallingIdentity(origId); 10652 } 10653 } 10654 10655 @Override 10656 public ActivityOptions getActivityOptions(IBinder token) { 10657 final long origId = Binder.clearCallingIdentity(); 10658 try { 10659 synchronized (this) { 10660 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10661 if (r != null) { 10662 final ActivityOptions activityOptions = r.pendingOptions; 10663 r.pendingOptions = null; 10664 return activityOptions; 10665 } 10666 return null; 10667 } 10668 } finally { 10669 Binder.restoreCallingIdentity(origId); 10670 } 10671 } 10672 10673 @Override 10674 public void setImmersive(IBinder token, boolean immersive) { 10675 synchronized(this) { 10676 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10677 if (r == null) { 10678 throw new IllegalArgumentException(); 10679 } 10680 r.immersive = immersive; 10681 10682 // update associated state if we're frontmost 10683 if (r == mFocusedActivity) { 10684 if (DEBUG_IMMERSIVE) { 10685 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10686 } 10687 applyUpdateLockStateLocked(r); 10688 } 10689 } 10690 } 10691 10692 @Override 10693 public boolean isImmersive(IBinder token) { 10694 synchronized (this) { 10695 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10696 if (r == null) { 10697 throw new IllegalArgumentException(); 10698 } 10699 return r.immersive; 10700 } 10701 } 10702 10703 public boolean isTopActivityImmersive() { 10704 enforceNotIsolatedCaller("startActivity"); 10705 synchronized (this) { 10706 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10707 return (r != null) ? r.immersive : false; 10708 } 10709 } 10710 10711 @Override 10712 public boolean isTopOfTask(IBinder token) { 10713 synchronized (this) { 10714 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10715 if (r == null) { 10716 throw new IllegalArgumentException(); 10717 } 10718 return r.task.getTopActivity() == r; 10719 } 10720 } 10721 10722 public final void enterSafeMode() { 10723 synchronized(this) { 10724 // It only makes sense to do this before the system is ready 10725 // and started launching other packages. 10726 if (!mSystemReady) { 10727 try { 10728 AppGlobals.getPackageManager().enterSafeMode(); 10729 } catch (RemoteException e) { 10730 } 10731 } 10732 10733 mSafeMode = true; 10734 } 10735 } 10736 10737 public final void showSafeModeOverlay() { 10738 View v = LayoutInflater.from(mContext).inflate( 10739 com.android.internal.R.layout.safe_mode, null); 10740 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10741 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10742 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10743 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10744 lp.gravity = Gravity.BOTTOM | Gravity.START; 10745 lp.format = v.getBackground().getOpacity(); 10746 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10747 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10748 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10749 ((WindowManager)mContext.getSystemService( 10750 Context.WINDOW_SERVICE)).addView(v, lp); 10751 } 10752 10753 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10754 if (!(sender instanceof PendingIntentRecord)) { 10755 return; 10756 } 10757 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10758 synchronized (stats) { 10759 if (mBatteryStatsService.isOnBattery()) { 10760 mBatteryStatsService.enforceCallingPermission(); 10761 PendingIntentRecord rec = (PendingIntentRecord)sender; 10762 int MY_UID = Binder.getCallingUid(); 10763 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10764 BatteryStatsImpl.Uid.Pkg pkg = 10765 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10766 sourcePkg != null ? sourcePkg : rec.key.packageName); 10767 pkg.incWakeupsLocked(); 10768 } 10769 } 10770 } 10771 10772 public boolean killPids(int[] pids, String pReason, boolean secure) { 10773 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10774 throw new SecurityException("killPids only available to the system"); 10775 } 10776 String reason = (pReason == null) ? "Unknown" : pReason; 10777 // XXX Note: don't acquire main activity lock here, because the window 10778 // manager calls in with its locks held. 10779 10780 boolean killed = false; 10781 synchronized (mPidsSelfLocked) { 10782 int[] types = new int[pids.length]; 10783 int worstType = 0; 10784 for (int i=0; i<pids.length; i++) { 10785 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10786 if (proc != null) { 10787 int type = proc.setAdj; 10788 types[i] = type; 10789 if (type > worstType) { 10790 worstType = type; 10791 } 10792 } 10793 } 10794 10795 // If the worst oom_adj is somewhere in the cached proc LRU range, 10796 // then constrain it so we will kill all cached procs. 10797 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10798 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10799 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10800 } 10801 10802 // If this is not a secure call, don't let it kill processes that 10803 // are important. 10804 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10805 worstType = ProcessList.SERVICE_ADJ; 10806 } 10807 10808 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10809 for (int i=0; i<pids.length; i++) { 10810 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10811 if (proc == null) { 10812 continue; 10813 } 10814 int adj = proc.setAdj; 10815 if (adj >= worstType && !proc.killedByAm) { 10816 proc.kill(reason, true); 10817 killed = true; 10818 } 10819 } 10820 } 10821 return killed; 10822 } 10823 10824 @Override 10825 public void killUid(int uid, String reason) { 10826 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10827 throw new SecurityException("killUid only available to the system"); 10828 } 10829 synchronized (this) { 10830 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10831 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10832 reason != null ? reason : "kill uid"); 10833 } 10834 } 10835 10836 @Override 10837 public boolean killProcessesBelowForeground(String reason) { 10838 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10839 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10840 } 10841 10842 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10843 } 10844 10845 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10846 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10847 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10848 } 10849 10850 boolean killed = false; 10851 synchronized (mPidsSelfLocked) { 10852 final int size = mPidsSelfLocked.size(); 10853 for (int i = 0; i < size; i++) { 10854 final int pid = mPidsSelfLocked.keyAt(i); 10855 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10856 if (proc == null) continue; 10857 10858 final int adj = proc.setAdj; 10859 if (adj > belowAdj && !proc.killedByAm) { 10860 proc.kill(reason, true); 10861 killed = true; 10862 } 10863 } 10864 } 10865 return killed; 10866 } 10867 10868 @Override 10869 public void hang(final IBinder who, boolean allowRestart) { 10870 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10871 != PackageManager.PERMISSION_GRANTED) { 10872 throw new SecurityException("Requires permission " 10873 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10874 } 10875 10876 final IBinder.DeathRecipient death = new DeathRecipient() { 10877 @Override 10878 public void binderDied() { 10879 synchronized (this) { 10880 notifyAll(); 10881 } 10882 } 10883 }; 10884 10885 try { 10886 who.linkToDeath(death, 0); 10887 } catch (RemoteException e) { 10888 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10889 return; 10890 } 10891 10892 synchronized (this) { 10893 Watchdog.getInstance().setAllowRestart(allowRestart); 10894 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10895 synchronized (death) { 10896 while (who.isBinderAlive()) { 10897 try { 10898 death.wait(); 10899 } catch (InterruptedException e) { 10900 } 10901 } 10902 } 10903 Watchdog.getInstance().setAllowRestart(true); 10904 } 10905 } 10906 10907 @Override 10908 public void restart() { 10909 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10910 != PackageManager.PERMISSION_GRANTED) { 10911 throw new SecurityException("Requires permission " 10912 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10913 } 10914 10915 Log.i(TAG, "Sending shutdown broadcast..."); 10916 10917 BroadcastReceiver br = new BroadcastReceiver() { 10918 @Override public void onReceive(Context context, Intent intent) { 10919 // Now the broadcast is done, finish up the low-level shutdown. 10920 Log.i(TAG, "Shutting down activity manager..."); 10921 shutdown(10000); 10922 Log.i(TAG, "Shutdown complete, restarting!"); 10923 Process.killProcess(Process.myPid()); 10924 System.exit(10); 10925 } 10926 }; 10927 10928 // First send the high-level shut down broadcast. 10929 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10930 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10931 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10932 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10933 mContext.sendOrderedBroadcastAsUser(intent, 10934 UserHandle.ALL, null, br, mHandler, 0, null, null); 10935 */ 10936 br.onReceive(mContext, intent); 10937 } 10938 10939 private long getLowRamTimeSinceIdle(long now) { 10940 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10941 } 10942 10943 @Override 10944 public void performIdleMaintenance() { 10945 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10946 != PackageManager.PERMISSION_GRANTED) { 10947 throw new SecurityException("Requires permission " 10948 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10949 } 10950 10951 synchronized (this) { 10952 final long now = SystemClock.uptimeMillis(); 10953 final long timeSinceLastIdle = now - mLastIdleTime; 10954 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10955 mLastIdleTime = now; 10956 mLowRamTimeSinceLastIdle = 0; 10957 if (mLowRamStartTime != 0) { 10958 mLowRamStartTime = now; 10959 } 10960 10961 StringBuilder sb = new StringBuilder(128); 10962 sb.append("Idle maintenance over "); 10963 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10964 sb.append(" low RAM for "); 10965 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10966 Slog.i(TAG, sb.toString()); 10967 10968 // If at least 1/3 of our time since the last idle period has been spent 10969 // with RAM low, then we want to kill processes. 10970 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10971 10972 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10973 ProcessRecord proc = mLruProcesses.get(i); 10974 if (proc.notCachedSinceIdle) { 10975 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10976 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10977 if (doKilling && proc.initialIdlePss != 0 10978 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10979 proc.kill("idle maint (pss " + proc.lastPss 10980 + " from " + proc.initialIdlePss + ")", true); 10981 } 10982 } 10983 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10984 proc.notCachedSinceIdle = true; 10985 proc.initialIdlePss = 0; 10986 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10987 isSleeping(), now); 10988 } 10989 } 10990 10991 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10992 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10993 } 10994 } 10995 10996 private void retrieveSettings() { 10997 final ContentResolver resolver = mContext.getContentResolver(); 10998 String debugApp = Settings.Global.getString( 10999 resolver, Settings.Global.DEBUG_APP); 11000 boolean waitForDebugger = Settings.Global.getInt( 11001 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11002 boolean alwaysFinishActivities = Settings.Global.getInt( 11003 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11004 boolean forceRtl = Settings.Global.getInt( 11005 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11006 // Transfer any global setting for forcing RTL layout, into a System Property 11007 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11008 11009 Configuration configuration = new Configuration(); 11010 Settings.System.getConfiguration(resolver, configuration); 11011 if (forceRtl) { 11012 // This will take care of setting the correct layout direction flags 11013 configuration.setLayoutDirection(configuration.locale); 11014 } 11015 11016 synchronized (this) { 11017 mDebugApp = mOrigDebugApp = debugApp; 11018 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11019 mAlwaysFinishActivities = alwaysFinishActivities; 11020 // This happens before any activities are started, so we can 11021 // change mConfiguration in-place. 11022 updateConfigurationLocked(configuration, null, false, true); 11023 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11024 } 11025 } 11026 11027 /** Loads resources after the current configuration has been set. */ 11028 private void loadResourcesOnSystemReady() { 11029 final Resources res = mContext.getResources(); 11030 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11031 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11032 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11033 } 11034 11035 public boolean testIsSystemReady() { 11036 // no need to synchronize(this) just to read & return the value 11037 return mSystemReady; 11038 } 11039 11040 private static File getCalledPreBootReceiversFile() { 11041 File dataDir = Environment.getDataDirectory(); 11042 File systemDir = new File(dataDir, "system"); 11043 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11044 return fname; 11045 } 11046 11047 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11048 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11049 File file = getCalledPreBootReceiversFile(); 11050 FileInputStream fis = null; 11051 try { 11052 fis = new FileInputStream(file); 11053 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11054 int fvers = dis.readInt(); 11055 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11056 String vers = dis.readUTF(); 11057 String codename = dis.readUTF(); 11058 String build = dis.readUTF(); 11059 if (android.os.Build.VERSION.RELEASE.equals(vers) 11060 && android.os.Build.VERSION.CODENAME.equals(codename) 11061 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11062 int num = dis.readInt(); 11063 while (num > 0) { 11064 num--; 11065 String pkg = dis.readUTF(); 11066 String cls = dis.readUTF(); 11067 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11068 } 11069 } 11070 } 11071 } catch (FileNotFoundException e) { 11072 } catch (IOException e) { 11073 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11074 } finally { 11075 if (fis != null) { 11076 try { 11077 fis.close(); 11078 } catch (IOException e) { 11079 } 11080 } 11081 } 11082 return lastDoneReceivers; 11083 } 11084 11085 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11086 File file = getCalledPreBootReceiversFile(); 11087 FileOutputStream fos = null; 11088 DataOutputStream dos = null; 11089 try { 11090 fos = new FileOutputStream(file); 11091 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11092 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11093 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11094 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11095 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11096 dos.writeInt(list.size()); 11097 for (int i=0; i<list.size(); i++) { 11098 dos.writeUTF(list.get(i).getPackageName()); 11099 dos.writeUTF(list.get(i).getClassName()); 11100 } 11101 } catch (IOException e) { 11102 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11103 file.delete(); 11104 } finally { 11105 FileUtils.sync(fos); 11106 if (dos != null) { 11107 try { 11108 dos.close(); 11109 } catch (IOException e) { 11110 // TODO Auto-generated catch block 11111 e.printStackTrace(); 11112 } 11113 } 11114 } 11115 } 11116 11117 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11118 ArrayList<ComponentName> doneReceivers, int userId) { 11119 boolean waitingUpdate = false; 11120 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11121 List<ResolveInfo> ris = null; 11122 try { 11123 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11124 intent, null, 0, userId); 11125 } catch (RemoteException e) { 11126 } 11127 if (ris != null) { 11128 for (int i=ris.size()-1; i>=0; i--) { 11129 if ((ris.get(i).activityInfo.applicationInfo.flags 11130 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11131 ris.remove(i); 11132 } 11133 } 11134 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11135 11136 // For User 0, load the version number. When delivering to a new user, deliver 11137 // to all receivers. 11138 if (userId == UserHandle.USER_OWNER) { 11139 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11140 for (int i=0; i<ris.size(); i++) { 11141 ActivityInfo ai = ris.get(i).activityInfo; 11142 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11143 if (lastDoneReceivers.contains(comp)) { 11144 // We already did the pre boot receiver for this app with the current 11145 // platform version, so don't do it again... 11146 ris.remove(i); 11147 i--; 11148 // ...however, do keep it as one that has been done, so we don't 11149 // forget about it when rewriting the file of last done receivers. 11150 doneReceivers.add(comp); 11151 } 11152 } 11153 } 11154 11155 // If primary user, send broadcast to all available users, else just to userId 11156 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11157 : new int[] { userId }; 11158 for (int i = 0; i < ris.size(); i++) { 11159 ActivityInfo ai = ris.get(i).activityInfo; 11160 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11161 doneReceivers.add(comp); 11162 intent.setComponent(comp); 11163 for (int j=0; j<users.length; j++) { 11164 IIntentReceiver finisher = null; 11165 // On last receiver and user, set up a completion callback 11166 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11167 finisher = new IIntentReceiver.Stub() { 11168 public void performReceive(Intent intent, int resultCode, 11169 String data, Bundle extras, boolean ordered, 11170 boolean sticky, int sendingUser) { 11171 // The raw IIntentReceiver interface is called 11172 // with the AM lock held, so redispatch to 11173 // execute our code without the lock. 11174 mHandler.post(onFinishCallback); 11175 } 11176 }; 11177 } 11178 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11179 + " for user " + users[j]); 11180 broadcastIntentLocked(null, null, intent, null, finisher, 11181 0, null, null, null, AppOpsManager.OP_NONE, 11182 true, false, MY_PID, Process.SYSTEM_UID, 11183 users[j]); 11184 if (finisher != null) { 11185 waitingUpdate = true; 11186 } 11187 } 11188 } 11189 } 11190 11191 return waitingUpdate; 11192 } 11193 11194 public void systemReady(final Runnable goingCallback) { 11195 synchronized(this) { 11196 if (mSystemReady) { 11197 // If we're done calling all the receivers, run the next "boot phase" passed in 11198 // by the SystemServer 11199 if (goingCallback != null) { 11200 goingCallback.run(); 11201 } 11202 return; 11203 } 11204 11205 // Make sure we have the current profile info, since it is needed for 11206 // security checks. 11207 updateCurrentProfileIdsLocked(); 11208 11209 if (mRecentTasks == null) { 11210 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11211 if (!mRecentTasks.isEmpty()) { 11212 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11213 } 11214 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11215 mTaskPersister.startPersisting(); 11216 } 11217 11218 // Check to see if there are any update receivers to run. 11219 if (!mDidUpdate) { 11220 if (mWaitingUpdate) { 11221 return; 11222 } 11223 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11224 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11225 public void run() { 11226 synchronized (ActivityManagerService.this) { 11227 mDidUpdate = true; 11228 } 11229 writeLastDonePreBootReceivers(doneReceivers); 11230 showBootMessage(mContext.getText( 11231 R.string.android_upgrading_complete), 11232 false); 11233 systemReady(goingCallback); 11234 } 11235 }, doneReceivers, UserHandle.USER_OWNER); 11236 11237 if (mWaitingUpdate) { 11238 return; 11239 } 11240 mDidUpdate = true; 11241 } 11242 11243 mAppOpsService.systemReady(); 11244 mSystemReady = true; 11245 } 11246 11247 ArrayList<ProcessRecord> procsToKill = null; 11248 synchronized(mPidsSelfLocked) { 11249 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11250 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11251 if (!isAllowedWhileBooting(proc.info)){ 11252 if (procsToKill == null) { 11253 procsToKill = new ArrayList<ProcessRecord>(); 11254 } 11255 procsToKill.add(proc); 11256 } 11257 } 11258 } 11259 11260 synchronized(this) { 11261 if (procsToKill != null) { 11262 for (int i=procsToKill.size()-1; i>=0; i--) { 11263 ProcessRecord proc = procsToKill.get(i); 11264 Slog.i(TAG, "Removing system update proc: " + proc); 11265 removeProcessLocked(proc, true, false, "system update done"); 11266 } 11267 } 11268 11269 // Now that we have cleaned up any update processes, we 11270 // are ready to start launching real processes and know that 11271 // we won't trample on them any more. 11272 mProcessesReady = true; 11273 } 11274 11275 Slog.i(TAG, "System now ready"); 11276 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11277 SystemClock.uptimeMillis()); 11278 11279 synchronized(this) { 11280 // Make sure we have no pre-ready processes sitting around. 11281 11282 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11283 ResolveInfo ri = mContext.getPackageManager() 11284 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11285 STOCK_PM_FLAGS); 11286 CharSequence errorMsg = null; 11287 if (ri != null) { 11288 ActivityInfo ai = ri.activityInfo; 11289 ApplicationInfo app = ai.applicationInfo; 11290 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11291 mTopAction = Intent.ACTION_FACTORY_TEST; 11292 mTopData = null; 11293 mTopComponent = new ComponentName(app.packageName, 11294 ai.name); 11295 } else { 11296 errorMsg = mContext.getResources().getText( 11297 com.android.internal.R.string.factorytest_not_system); 11298 } 11299 } else { 11300 errorMsg = mContext.getResources().getText( 11301 com.android.internal.R.string.factorytest_no_action); 11302 } 11303 if (errorMsg != null) { 11304 mTopAction = null; 11305 mTopData = null; 11306 mTopComponent = null; 11307 Message msg = Message.obtain(); 11308 msg.what = SHOW_FACTORY_ERROR_MSG; 11309 msg.getData().putCharSequence("msg", errorMsg); 11310 mHandler.sendMessage(msg); 11311 } 11312 } 11313 } 11314 11315 retrieveSettings(); 11316 loadResourcesOnSystemReady(); 11317 11318 synchronized (this) { 11319 readGrantedUriPermissionsLocked(); 11320 } 11321 11322 if (goingCallback != null) goingCallback.run(); 11323 11324 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11325 Integer.toString(mCurrentUserId), mCurrentUserId); 11326 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11327 Integer.toString(mCurrentUserId), mCurrentUserId); 11328 mSystemServiceManager.startUser(mCurrentUserId); 11329 11330 synchronized (this) { 11331 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11332 try { 11333 List apps = AppGlobals.getPackageManager(). 11334 getPersistentApplications(STOCK_PM_FLAGS); 11335 if (apps != null) { 11336 int N = apps.size(); 11337 int i; 11338 for (i=0; i<N; i++) { 11339 ApplicationInfo info 11340 = (ApplicationInfo)apps.get(i); 11341 if (info != null && 11342 !info.packageName.equals("android")) { 11343 addAppLocked(info, false, null /* ABI override */); 11344 } 11345 } 11346 } 11347 } catch (RemoteException ex) { 11348 // pm is in same process, this will never happen. 11349 } 11350 } 11351 11352 // Start up initial activity. 11353 mBooting = true; 11354 startHomeActivityLocked(mCurrentUserId); 11355 11356 try { 11357 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11358 Message msg = Message.obtain(); 11359 msg.what = SHOW_UID_ERROR_MSG; 11360 mHandler.sendMessage(msg); 11361 } 11362 } catch (RemoteException e) { 11363 } 11364 11365 long ident = Binder.clearCallingIdentity(); 11366 try { 11367 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11369 | Intent.FLAG_RECEIVER_FOREGROUND); 11370 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11371 broadcastIntentLocked(null, null, intent, 11372 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11373 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11374 intent = new Intent(Intent.ACTION_USER_STARTING); 11375 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11376 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11377 broadcastIntentLocked(null, null, intent, 11378 null, new IIntentReceiver.Stub() { 11379 @Override 11380 public void performReceive(Intent intent, int resultCode, String data, 11381 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11382 throws RemoteException { 11383 } 11384 }, 0, null, null, 11385 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11386 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11387 } catch (Throwable t) { 11388 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11389 } finally { 11390 Binder.restoreCallingIdentity(ident); 11391 } 11392 mStackSupervisor.resumeTopActivitiesLocked(); 11393 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11394 } 11395 } 11396 11397 private boolean makeAppCrashingLocked(ProcessRecord app, 11398 String shortMsg, String longMsg, String stackTrace) { 11399 app.crashing = true; 11400 app.crashingReport = generateProcessError(app, 11401 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11402 startAppProblemLocked(app); 11403 app.stopFreezingAllLocked(); 11404 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11405 } 11406 11407 private void makeAppNotRespondingLocked(ProcessRecord app, 11408 String activity, String shortMsg, String longMsg) { 11409 app.notResponding = true; 11410 app.notRespondingReport = generateProcessError(app, 11411 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11412 activity, shortMsg, longMsg, null); 11413 startAppProblemLocked(app); 11414 app.stopFreezingAllLocked(); 11415 } 11416 11417 /** 11418 * Generate a process error record, suitable for attachment to a ProcessRecord. 11419 * 11420 * @param app The ProcessRecord in which the error occurred. 11421 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11422 * ActivityManager.AppErrorStateInfo 11423 * @param activity The activity associated with the crash, if known. 11424 * @param shortMsg Short message describing the crash. 11425 * @param longMsg Long message describing the crash. 11426 * @param stackTrace Full crash stack trace, may be null. 11427 * 11428 * @return Returns a fully-formed AppErrorStateInfo record. 11429 */ 11430 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11431 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11432 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11433 11434 report.condition = condition; 11435 report.processName = app.processName; 11436 report.pid = app.pid; 11437 report.uid = app.info.uid; 11438 report.tag = activity; 11439 report.shortMsg = shortMsg; 11440 report.longMsg = longMsg; 11441 report.stackTrace = stackTrace; 11442 11443 return report; 11444 } 11445 11446 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11447 synchronized (this) { 11448 app.crashing = false; 11449 app.crashingReport = null; 11450 app.notResponding = false; 11451 app.notRespondingReport = null; 11452 if (app.anrDialog == fromDialog) { 11453 app.anrDialog = null; 11454 } 11455 if (app.waitDialog == fromDialog) { 11456 app.waitDialog = null; 11457 } 11458 if (app.pid > 0 && app.pid != MY_PID) { 11459 handleAppCrashLocked(app, null, null, null); 11460 app.kill("user request after error", true); 11461 } 11462 } 11463 } 11464 11465 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11466 String stackTrace) { 11467 long now = SystemClock.uptimeMillis(); 11468 11469 Long crashTime; 11470 if (!app.isolated) { 11471 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11472 } else { 11473 crashTime = null; 11474 } 11475 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11476 // This process loses! 11477 Slog.w(TAG, "Process " + app.info.processName 11478 + " has crashed too many times: killing!"); 11479 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11480 app.userId, app.info.processName, app.uid); 11481 mStackSupervisor.handleAppCrashLocked(app); 11482 if (!app.persistent) { 11483 // We don't want to start this process again until the user 11484 // explicitly does so... but for persistent process, we really 11485 // need to keep it running. If a persistent process is actually 11486 // repeatedly crashing, then badness for everyone. 11487 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11488 app.info.processName); 11489 if (!app.isolated) { 11490 // XXX We don't have a way to mark isolated processes 11491 // as bad, since they don't have a peristent identity. 11492 mBadProcesses.put(app.info.processName, app.uid, 11493 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11494 mProcessCrashTimes.remove(app.info.processName, app.uid); 11495 } 11496 app.bad = true; 11497 app.removed = true; 11498 // Don't let services in this process be restarted and potentially 11499 // annoy the user repeatedly. Unless it is persistent, since those 11500 // processes run critical code. 11501 removeProcessLocked(app, false, false, "crash"); 11502 mStackSupervisor.resumeTopActivitiesLocked(); 11503 return false; 11504 } 11505 mStackSupervisor.resumeTopActivitiesLocked(); 11506 } else { 11507 mStackSupervisor.finishTopRunningActivityLocked(app); 11508 } 11509 11510 // Bump up the crash count of any services currently running in the proc. 11511 for (int i=app.services.size()-1; i>=0; i--) { 11512 // Any services running in the application need to be placed 11513 // back in the pending list. 11514 ServiceRecord sr = app.services.valueAt(i); 11515 sr.crashCount++; 11516 } 11517 11518 // If the crashing process is what we consider to be the "home process" and it has been 11519 // replaced by a third-party app, clear the package preferred activities from packages 11520 // with a home activity running in the process to prevent a repeatedly crashing app 11521 // from blocking the user to manually clear the list. 11522 final ArrayList<ActivityRecord> activities = app.activities; 11523 if (app == mHomeProcess && activities.size() > 0 11524 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11525 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11526 final ActivityRecord r = activities.get(activityNdx); 11527 if (r.isHomeActivity()) { 11528 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11529 try { 11530 ActivityThread.getPackageManager() 11531 .clearPackagePreferredActivities(r.packageName); 11532 } catch (RemoteException c) { 11533 // pm is in same process, this will never happen. 11534 } 11535 } 11536 } 11537 } 11538 11539 if (!app.isolated) { 11540 // XXX Can't keep track of crash times for isolated processes, 11541 // because they don't have a perisistent identity. 11542 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11543 } 11544 11545 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11546 return true; 11547 } 11548 11549 void startAppProblemLocked(ProcessRecord app) { 11550 // If this app is not running under the current user, then we 11551 // can't give it a report button because that would require 11552 // launching the report UI under a different user. 11553 app.errorReportReceiver = null; 11554 11555 for (int userId : mCurrentProfileIds) { 11556 if (app.userId == userId) { 11557 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11558 mContext, app.info.packageName, app.info.flags); 11559 } 11560 } 11561 skipCurrentReceiverLocked(app); 11562 } 11563 11564 void skipCurrentReceiverLocked(ProcessRecord app) { 11565 for (BroadcastQueue queue : mBroadcastQueues) { 11566 queue.skipCurrentReceiverLocked(app); 11567 } 11568 } 11569 11570 /** 11571 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11572 * The application process will exit immediately after this call returns. 11573 * @param app object of the crashing app, null for the system server 11574 * @param crashInfo describing the exception 11575 */ 11576 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11577 ProcessRecord r = findAppProcess(app, "Crash"); 11578 final String processName = app == null ? "system_server" 11579 : (r == null ? "unknown" : r.processName); 11580 11581 handleApplicationCrashInner("crash", r, processName, crashInfo); 11582 } 11583 11584 /* Native crash reporting uses this inner version because it needs to be somewhat 11585 * decoupled from the AM-managed cleanup lifecycle 11586 */ 11587 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11588 ApplicationErrorReport.CrashInfo crashInfo) { 11589 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11590 UserHandle.getUserId(Binder.getCallingUid()), processName, 11591 r == null ? -1 : r.info.flags, 11592 crashInfo.exceptionClassName, 11593 crashInfo.exceptionMessage, 11594 crashInfo.throwFileName, 11595 crashInfo.throwLineNumber); 11596 11597 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11598 11599 crashApplication(r, crashInfo); 11600 } 11601 11602 public void handleApplicationStrictModeViolation( 11603 IBinder app, 11604 int violationMask, 11605 StrictMode.ViolationInfo info) { 11606 ProcessRecord r = findAppProcess(app, "StrictMode"); 11607 if (r == null) { 11608 return; 11609 } 11610 11611 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11612 Integer stackFingerprint = info.hashCode(); 11613 boolean logIt = true; 11614 synchronized (mAlreadyLoggedViolatedStacks) { 11615 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11616 logIt = false; 11617 // TODO: sub-sample into EventLog for these, with 11618 // the info.durationMillis? Then we'd get 11619 // the relative pain numbers, without logging all 11620 // the stack traces repeatedly. We'd want to do 11621 // likewise in the client code, which also does 11622 // dup suppression, before the Binder call. 11623 } else { 11624 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11625 mAlreadyLoggedViolatedStacks.clear(); 11626 } 11627 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11628 } 11629 } 11630 if (logIt) { 11631 logStrictModeViolationToDropBox(r, info); 11632 } 11633 } 11634 11635 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11636 AppErrorResult result = new AppErrorResult(); 11637 synchronized (this) { 11638 final long origId = Binder.clearCallingIdentity(); 11639 11640 Message msg = Message.obtain(); 11641 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11642 HashMap<String, Object> data = new HashMap<String, Object>(); 11643 data.put("result", result); 11644 data.put("app", r); 11645 data.put("violationMask", violationMask); 11646 data.put("info", info); 11647 msg.obj = data; 11648 mHandler.sendMessage(msg); 11649 11650 Binder.restoreCallingIdentity(origId); 11651 } 11652 int res = result.get(); 11653 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11654 } 11655 } 11656 11657 // Depending on the policy in effect, there could be a bunch of 11658 // these in quick succession so we try to batch these together to 11659 // minimize disk writes, number of dropbox entries, and maximize 11660 // compression, by having more fewer, larger records. 11661 private void logStrictModeViolationToDropBox( 11662 ProcessRecord process, 11663 StrictMode.ViolationInfo info) { 11664 if (info == null) { 11665 return; 11666 } 11667 final boolean isSystemApp = process == null || 11668 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11669 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11670 final String processName = process == null ? "unknown" : process.processName; 11671 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11672 final DropBoxManager dbox = (DropBoxManager) 11673 mContext.getSystemService(Context.DROPBOX_SERVICE); 11674 11675 // Exit early if the dropbox isn't configured to accept this report type. 11676 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11677 11678 boolean bufferWasEmpty; 11679 boolean needsFlush; 11680 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11681 synchronized (sb) { 11682 bufferWasEmpty = sb.length() == 0; 11683 appendDropBoxProcessHeaders(process, processName, sb); 11684 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11685 sb.append("System-App: ").append(isSystemApp).append("\n"); 11686 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11687 if (info.violationNumThisLoop != 0) { 11688 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11689 } 11690 if (info.numAnimationsRunning != 0) { 11691 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11692 } 11693 if (info.broadcastIntentAction != null) { 11694 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11695 } 11696 if (info.durationMillis != -1) { 11697 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11698 } 11699 if (info.numInstances != -1) { 11700 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11701 } 11702 if (info.tags != null) { 11703 for (String tag : info.tags) { 11704 sb.append("Span-Tag: ").append(tag).append("\n"); 11705 } 11706 } 11707 sb.append("\n"); 11708 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11709 sb.append(info.crashInfo.stackTrace); 11710 } 11711 sb.append("\n"); 11712 11713 // Only buffer up to ~64k. Various logging bits truncate 11714 // things at 128k. 11715 needsFlush = (sb.length() > 64 * 1024); 11716 } 11717 11718 // Flush immediately if the buffer's grown too large, or this 11719 // is a non-system app. Non-system apps are isolated with a 11720 // different tag & policy and not batched. 11721 // 11722 // Batching is useful during internal testing with 11723 // StrictMode settings turned up high. Without batching, 11724 // thousands of separate files could be created on boot. 11725 if (!isSystemApp || needsFlush) { 11726 new Thread("Error dump: " + dropboxTag) { 11727 @Override 11728 public void run() { 11729 String report; 11730 synchronized (sb) { 11731 report = sb.toString(); 11732 sb.delete(0, sb.length()); 11733 sb.trimToSize(); 11734 } 11735 if (report.length() != 0) { 11736 dbox.addText(dropboxTag, report); 11737 } 11738 } 11739 }.start(); 11740 return; 11741 } 11742 11743 // System app batching: 11744 if (!bufferWasEmpty) { 11745 // An existing dropbox-writing thread is outstanding, so 11746 // we don't need to start it up. The existing thread will 11747 // catch the buffer appends we just did. 11748 return; 11749 } 11750 11751 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11752 // (After this point, we shouldn't access AMS internal data structures.) 11753 new Thread("Error dump: " + dropboxTag) { 11754 @Override 11755 public void run() { 11756 // 5 second sleep to let stacks arrive and be batched together 11757 try { 11758 Thread.sleep(5000); // 5 seconds 11759 } catch (InterruptedException e) {} 11760 11761 String errorReport; 11762 synchronized (mStrictModeBuffer) { 11763 errorReport = mStrictModeBuffer.toString(); 11764 if (errorReport.length() == 0) { 11765 return; 11766 } 11767 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11768 mStrictModeBuffer.trimToSize(); 11769 } 11770 dbox.addText(dropboxTag, errorReport); 11771 } 11772 }.start(); 11773 } 11774 11775 /** 11776 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11777 * @param app object of the crashing app, null for the system server 11778 * @param tag reported by the caller 11779 * @param system whether this wtf is coming from the system 11780 * @param crashInfo describing the context of the error 11781 * @return true if the process should exit immediately (WTF is fatal) 11782 */ 11783 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11784 final ApplicationErrorReport.CrashInfo crashInfo) { 11785 final int callingUid = Binder.getCallingUid(); 11786 final int callingPid = Binder.getCallingPid(); 11787 11788 if (system) { 11789 // If this is coming from the system, we could very well have low-level 11790 // system locks held, so we want to do this all asynchronously. And we 11791 // never want this to become fatal, so there is that too. 11792 mHandler.post(new Runnable() { 11793 @Override public void run() { 11794 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11795 } 11796 }); 11797 return false; 11798 } 11799 11800 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11801 crashInfo); 11802 11803 if (r != null && r.pid != Process.myPid() && 11804 Settings.Global.getInt(mContext.getContentResolver(), 11805 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11806 crashApplication(r, crashInfo); 11807 return true; 11808 } else { 11809 return false; 11810 } 11811 } 11812 11813 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11814 final ApplicationErrorReport.CrashInfo crashInfo) { 11815 final ProcessRecord r = findAppProcess(app, "WTF"); 11816 final String processName = app == null ? "system_server" 11817 : (r == null ? "unknown" : r.processName); 11818 11819 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11820 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11821 11822 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11823 11824 return r; 11825 } 11826 11827 /** 11828 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11829 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11830 */ 11831 private ProcessRecord findAppProcess(IBinder app, String reason) { 11832 if (app == null) { 11833 return null; 11834 } 11835 11836 synchronized (this) { 11837 final int NP = mProcessNames.getMap().size(); 11838 for (int ip=0; ip<NP; ip++) { 11839 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11840 final int NA = apps.size(); 11841 for (int ia=0; ia<NA; ia++) { 11842 ProcessRecord p = apps.valueAt(ia); 11843 if (p.thread != null && p.thread.asBinder() == app) { 11844 return p; 11845 } 11846 } 11847 } 11848 11849 Slog.w(TAG, "Can't find mystery application for " + reason 11850 + " from pid=" + Binder.getCallingPid() 11851 + " uid=" + Binder.getCallingUid() + ": " + app); 11852 return null; 11853 } 11854 } 11855 11856 /** 11857 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11858 * to append various headers to the dropbox log text. 11859 */ 11860 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11861 StringBuilder sb) { 11862 // Watchdog thread ends up invoking this function (with 11863 // a null ProcessRecord) to add the stack file to dropbox. 11864 // Do not acquire a lock on this (am) in such cases, as it 11865 // could cause a potential deadlock, if and when watchdog 11866 // is invoked due to unavailability of lock on am and it 11867 // would prevent watchdog from killing system_server. 11868 if (process == null) { 11869 sb.append("Process: ").append(processName).append("\n"); 11870 return; 11871 } 11872 // Note: ProcessRecord 'process' is guarded by the service 11873 // instance. (notably process.pkgList, which could otherwise change 11874 // concurrently during execution of this method) 11875 synchronized (this) { 11876 sb.append("Process: ").append(processName).append("\n"); 11877 int flags = process.info.flags; 11878 IPackageManager pm = AppGlobals.getPackageManager(); 11879 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11880 for (int ip=0; ip<process.pkgList.size(); ip++) { 11881 String pkg = process.pkgList.keyAt(ip); 11882 sb.append("Package: ").append(pkg); 11883 try { 11884 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11885 if (pi != null) { 11886 sb.append(" v").append(pi.versionCode); 11887 if (pi.versionName != null) { 11888 sb.append(" (").append(pi.versionName).append(")"); 11889 } 11890 } 11891 } catch (RemoteException e) { 11892 Slog.e(TAG, "Error getting package info: " + pkg, e); 11893 } 11894 sb.append("\n"); 11895 } 11896 } 11897 } 11898 11899 private static String processClass(ProcessRecord process) { 11900 if (process == null || process.pid == MY_PID) { 11901 return "system_server"; 11902 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11903 return "system_app"; 11904 } else { 11905 return "data_app"; 11906 } 11907 } 11908 11909 /** 11910 * Write a description of an error (crash, WTF, ANR) to the drop box. 11911 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11912 * @param process which caused the error, null means the system server 11913 * @param activity which triggered the error, null if unknown 11914 * @param parent activity related to the error, null if unknown 11915 * @param subject line related to the error, null if absent 11916 * @param report in long form describing the error, null if absent 11917 * @param logFile to include in the report, null if none 11918 * @param crashInfo giving an application stack trace, null if absent 11919 */ 11920 public void addErrorToDropBox(String eventType, 11921 ProcessRecord process, String processName, ActivityRecord activity, 11922 ActivityRecord parent, String subject, 11923 final String report, final File logFile, 11924 final ApplicationErrorReport.CrashInfo crashInfo) { 11925 // NOTE -- this must never acquire the ActivityManagerService lock, 11926 // otherwise the watchdog may be prevented from resetting the system. 11927 11928 final String dropboxTag = processClass(process) + "_" + eventType; 11929 final DropBoxManager dbox = (DropBoxManager) 11930 mContext.getSystemService(Context.DROPBOX_SERVICE); 11931 11932 // Exit early if the dropbox isn't configured to accept this report type. 11933 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11934 11935 final StringBuilder sb = new StringBuilder(1024); 11936 appendDropBoxProcessHeaders(process, processName, sb); 11937 if (activity != null) { 11938 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11939 } 11940 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11941 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11942 } 11943 if (parent != null && parent != activity) { 11944 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11945 } 11946 if (subject != null) { 11947 sb.append("Subject: ").append(subject).append("\n"); 11948 } 11949 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11950 if (Debug.isDebuggerConnected()) { 11951 sb.append("Debugger: Connected\n"); 11952 } 11953 sb.append("\n"); 11954 11955 // Do the rest in a worker thread to avoid blocking the caller on I/O 11956 // (After this point, we shouldn't access AMS internal data structures.) 11957 Thread worker = new Thread("Error dump: " + dropboxTag) { 11958 @Override 11959 public void run() { 11960 if (report != null) { 11961 sb.append(report); 11962 } 11963 if (logFile != null) { 11964 try { 11965 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11966 "\n\n[[TRUNCATED]]")); 11967 } catch (IOException e) { 11968 Slog.e(TAG, "Error reading " + logFile, e); 11969 } 11970 } 11971 if (crashInfo != null && crashInfo.stackTrace != null) { 11972 sb.append(crashInfo.stackTrace); 11973 } 11974 11975 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11976 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11977 if (lines > 0) { 11978 sb.append("\n"); 11979 11980 // Merge several logcat streams, and take the last N lines 11981 InputStreamReader input = null; 11982 try { 11983 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11984 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11985 "-b", "crash", 11986 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11987 11988 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11989 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11990 input = new InputStreamReader(logcat.getInputStream()); 11991 11992 int num; 11993 char[] buf = new char[8192]; 11994 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11995 } catch (IOException e) { 11996 Slog.e(TAG, "Error running logcat", e); 11997 } finally { 11998 if (input != null) try { input.close(); } catch (IOException e) {} 11999 } 12000 } 12001 12002 dbox.addText(dropboxTag, sb.toString()); 12003 } 12004 }; 12005 12006 if (process == null) { 12007 // If process is null, we are being called from some internal code 12008 // and may be about to die -- run this synchronously. 12009 worker.run(); 12010 } else { 12011 worker.start(); 12012 } 12013 } 12014 12015 /** 12016 * Bring up the "unexpected error" dialog box for a crashing app. 12017 * Deal with edge cases (intercepts from instrumented applications, 12018 * ActivityController, error intent receivers, that sort of thing). 12019 * @param r the application crashing 12020 * @param crashInfo describing the failure 12021 */ 12022 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12023 long timeMillis = System.currentTimeMillis(); 12024 String shortMsg = crashInfo.exceptionClassName; 12025 String longMsg = crashInfo.exceptionMessage; 12026 String stackTrace = crashInfo.stackTrace; 12027 if (shortMsg != null && longMsg != null) { 12028 longMsg = shortMsg + ": " + longMsg; 12029 } else if (shortMsg != null) { 12030 longMsg = shortMsg; 12031 } 12032 12033 AppErrorResult result = new AppErrorResult(); 12034 synchronized (this) { 12035 if (mController != null) { 12036 try { 12037 String name = r != null ? r.processName : null; 12038 int pid = r != null ? r.pid : Binder.getCallingPid(); 12039 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12040 if (!mController.appCrashed(name, pid, 12041 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12042 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12043 && "Native crash".equals(crashInfo.exceptionClassName)) { 12044 Slog.w(TAG, "Skip killing native crashed app " + name 12045 + "(" + pid + ") during testing"); 12046 } else { 12047 Slog.w(TAG, "Force-killing crashed app " + name 12048 + " at watcher's request"); 12049 if (r != null) { 12050 r.kill("crash", true); 12051 } else { 12052 // Huh. 12053 Process.killProcess(pid); 12054 Process.killProcessGroup(uid, pid); 12055 } 12056 } 12057 return; 12058 } 12059 } catch (RemoteException e) { 12060 mController = null; 12061 Watchdog.getInstance().setActivityController(null); 12062 } 12063 } 12064 12065 final long origId = Binder.clearCallingIdentity(); 12066 12067 // If this process is running instrumentation, finish it. 12068 if (r != null && r.instrumentationClass != null) { 12069 Slog.w(TAG, "Error in app " + r.processName 12070 + " running instrumentation " + r.instrumentationClass + ":"); 12071 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12072 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12073 Bundle info = new Bundle(); 12074 info.putString("shortMsg", shortMsg); 12075 info.putString("longMsg", longMsg); 12076 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12077 Binder.restoreCallingIdentity(origId); 12078 return; 12079 } 12080 12081 // If we can't identify the process or it's already exceeded its crash quota, 12082 // quit right away without showing a crash dialog. 12083 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12084 Binder.restoreCallingIdentity(origId); 12085 return; 12086 } 12087 12088 Message msg = Message.obtain(); 12089 msg.what = SHOW_ERROR_MSG; 12090 HashMap data = new HashMap(); 12091 data.put("result", result); 12092 data.put("app", r); 12093 msg.obj = data; 12094 mHandler.sendMessage(msg); 12095 12096 Binder.restoreCallingIdentity(origId); 12097 } 12098 12099 int res = result.get(); 12100 12101 Intent appErrorIntent = null; 12102 synchronized (this) { 12103 if (r != null && !r.isolated) { 12104 // XXX Can't keep track of crash time for isolated processes, 12105 // since they don't have a persistent identity. 12106 mProcessCrashTimes.put(r.info.processName, r.uid, 12107 SystemClock.uptimeMillis()); 12108 } 12109 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12110 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12111 } 12112 } 12113 12114 if (appErrorIntent != null) { 12115 try { 12116 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12117 } catch (ActivityNotFoundException e) { 12118 Slog.w(TAG, "bug report receiver dissappeared", e); 12119 } 12120 } 12121 } 12122 12123 Intent createAppErrorIntentLocked(ProcessRecord r, 12124 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12125 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12126 if (report == null) { 12127 return null; 12128 } 12129 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12130 result.setComponent(r.errorReportReceiver); 12131 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12132 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12133 return result; 12134 } 12135 12136 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12137 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12138 if (r.errorReportReceiver == null) { 12139 return null; 12140 } 12141 12142 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12143 return null; 12144 } 12145 12146 ApplicationErrorReport report = new ApplicationErrorReport(); 12147 report.packageName = r.info.packageName; 12148 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12149 report.processName = r.processName; 12150 report.time = timeMillis; 12151 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12152 12153 if (r.crashing || r.forceCrashReport) { 12154 report.type = ApplicationErrorReport.TYPE_CRASH; 12155 report.crashInfo = crashInfo; 12156 } else if (r.notResponding) { 12157 report.type = ApplicationErrorReport.TYPE_ANR; 12158 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12159 12160 report.anrInfo.activity = r.notRespondingReport.tag; 12161 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12162 report.anrInfo.info = r.notRespondingReport.longMsg; 12163 } 12164 12165 return report; 12166 } 12167 12168 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12169 enforceNotIsolatedCaller("getProcessesInErrorState"); 12170 // assume our apps are happy - lazy create the list 12171 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12172 12173 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12174 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12175 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12176 12177 synchronized (this) { 12178 12179 // iterate across all processes 12180 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12181 ProcessRecord app = mLruProcesses.get(i); 12182 if (!allUsers && app.userId != userId) { 12183 continue; 12184 } 12185 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12186 // This one's in trouble, so we'll generate a report for it 12187 // crashes are higher priority (in case there's a crash *and* an anr) 12188 ActivityManager.ProcessErrorStateInfo report = null; 12189 if (app.crashing) { 12190 report = app.crashingReport; 12191 } else if (app.notResponding) { 12192 report = app.notRespondingReport; 12193 } 12194 12195 if (report != null) { 12196 if (errList == null) { 12197 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12198 } 12199 errList.add(report); 12200 } else { 12201 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12202 " crashing = " + app.crashing + 12203 " notResponding = " + app.notResponding); 12204 } 12205 } 12206 } 12207 } 12208 12209 return errList; 12210 } 12211 12212 static int procStateToImportance(int procState, int memAdj, 12213 ActivityManager.RunningAppProcessInfo currApp) { 12214 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12215 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12216 currApp.lru = memAdj; 12217 } else { 12218 currApp.lru = 0; 12219 } 12220 return imp; 12221 } 12222 12223 private void fillInProcMemInfo(ProcessRecord app, 12224 ActivityManager.RunningAppProcessInfo outInfo) { 12225 outInfo.pid = app.pid; 12226 outInfo.uid = app.info.uid; 12227 if (mHeavyWeightProcess == app) { 12228 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12229 } 12230 if (app.persistent) { 12231 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12232 } 12233 if (app.activities.size() > 0) { 12234 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12235 } 12236 outInfo.lastTrimLevel = app.trimMemoryLevel; 12237 int adj = app.curAdj; 12238 int procState = app.curProcState; 12239 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12240 outInfo.importanceReasonCode = app.adjTypeCode; 12241 outInfo.processState = app.curProcState; 12242 } 12243 12244 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12245 enforceNotIsolatedCaller("getRunningAppProcesses"); 12246 // Lazy instantiation of list 12247 List<ActivityManager.RunningAppProcessInfo> runList = null; 12248 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12249 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12250 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12251 synchronized (this) { 12252 // Iterate across all processes 12253 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12254 ProcessRecord app = mLruProcesses.get(i); 12255 if (!allUsers && app.userId != userId) { 12256 continue; 12257 } 12258 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12259 // Generate process state info for running application 12260 ActivityManager.RunningAppProcessInfo currApp = 12261 new ActivityManager.RunningAppProcessInfo(app.processName, 12262 app.pid, app.getPackageList()); 12263 fillInProcMemInfo(app, currApp); 12264 if (app.adjSource instanceof ProcessRecord) { 12265 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12266 currApp.importanceReasonImportance = 12267 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12268 app.adjSourceProcState); 12269 } else if (app.adjSource instanceof ActivityRecord) { 12270 ActivityRecord r = (ActivityRecord)app.adjSource; 12271 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12272 } 12273 if (app.adjTarget instanceof ComponentName) { 12274 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12275 } 12276 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12277 // + " lru=" + currApp.lru); 12278 if (runList == null) { 12279 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12280 } 12281 runList.add(currApp); 12282 } 12283 } 12284 } 12285 return runList; 12286 } 12287 12288 public List<ApplicationInfo> getRunningExternalApplications() { 12289 enforceNotIsolatedCaller("getRunningExternalApplications"); 12290 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12291 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12292 if (runningApps != null && runningApps.size() > 0) { 12293 Set<String> extList = new HashSet<String>(); 12294 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12295 if (app.pkgList != null) { 12296 for (String pkg : app.pkgList) { 12297 extList.add(pkg); 12298 } 12299 } 12300 } 12301 IPackageManager pm = AppGlobals.getPackageManager(); 12302 for (String pkg : extList) { 12303 try { 12304 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12305 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12306 retList.add(info); 12307 } 12308 } catch (RemoteException e) { 12309 } 12310 } 12311 } 12312 return retList; 12313 } 12314 12315 @Override 12316 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12317 enforceNotIsolatedCaller("getMyMemoryState"); 12318 synchronized (this) { 12319 ProcessRecord proc; 12320 synchronized (mPidsSelfLocked) { 12321 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12322 } 12323 fillInProcMemInfo(proc, outInfo); 12324 } 12325 } 12326 12327 @Override 12328 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12329 if (checkCallingPermission(android.Manifest.permission.DUMP) 12330 != PackageManager.PERMISSION_GRANTED) { 12331 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12332 + Binder.getCallingPid() 12333 + ", uid=" + Binder.getCallingUid() 12334 + " without permission " 12335 + android.Manifest.permission.DUMP); 12336 return; 12337 } 12338 12339 boolean dumpAll = false; 12340 boolean dumpClient = false; 12341 String dumpPackage = null; 12342 12343 int opti = 0; 12344 while (opti < args.length) { 12345 String opt = args[opti]; 12346 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12347 break; 12348 } 12349 opti++; 12350 if ("-a".equals(opt)) { 12351 dumpAll = true; 12352 } else if ("-c".equals(opt)) { 12353 dumpClient = true; 12354 } else if ("-h".equals(opt)) { 12355 pw.println("Activity manager dump options:"); 12356 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12357 pw.println(" cmd may be one of:"); 12358 pw.println(" a[ctivities]: activity stack state"); 12359 pw.println(" r[recents]: recent activities state"); 12360 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12361 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12362 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12363 pw.println(" o[om]: out of memory management"); 12364 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12365 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12366 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12367 pw.println(" service [COMP_SPEC]: service client-side state"); 12368 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12369 pw.println(" all: dump all activities"); 12370 pw.println(" top: dump the top activity"); 12371 pw.println(" write: write all pending state to storage"); 12372 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12373 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12374 pw.println(" a partial substring in a component name, a"); 12375 pw.println(" hex object identifier."); 12376 pw.println(" -a: include all available server state."); 12377 pw.println(" -c: include client state."); 12378 return; 12379 } else { 12380 pw.println("Unknown argument: " + opt + "; use -h for help"); 12381 } 12382 } 12383 12384 long origId = Binder.clearCallingIdentity(); 12385 boolean more = false; 12386 // Is the caller requesting to dump a particular piece of data? 12387 if (opti < args.length) { 12388 String cmd = args[opti]; 12389 opti++; 12390 if ("activities".equals(cmd) || "a".equals(cmd)) { 12391 synchronized (this) { 12392 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12393 } 12394 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12395 synchronized (this) { 12396 dumpRecentsLocked(fd, pw, args, opti, true, null); 12397 } 12398 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12399 String[] newArgs; 12400 String name; 12401 if (opti >= args.length) { 12402 name = null; 12403 newArgs = EMPTY_STRING_ARRAY; 12404 } else { 12405 name = args[opti]; 12406 opti++; 12407 newArgs = new String[args.length - opti]; 12408 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12409 args.length - opti); 12410 } 12411 synchronized (this) { 12412 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12413 } 12414 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12415 String[] newArgs; 12416 String name; 12417 if (opti >= args.length) { 12418 name = null; 12419 newArgs = EMPTY_STRING_ARRAY; 12420 } else { 12421 name = args[opti]; 12422 opti++; 12423 newArgs = new String[args.length - opti]; 12424 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12425 args.length - opti); 12426 } 12427 synchronized (this) { 12428 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12429 } 12430 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12431 String[] newArgs; 12432 String name; 12433 if (opti >= args.length) { 12434 name = null; 12435 newArgs = EMPTY_STRING_ARRAY; 12436 } else { 12437 name = args[opti]; 12438 opti++; 12439 newArgs = new String[args.length - opti]; 12440 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12441 args.length - opti); 12442 } 12443 synchronized (this) { 12444 dumpProcessesLocked(fd, pw, args, opti, true, name); 12445 } 12446 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12447 synchronized (this) { 12448 dumpOomLocked(fd, pw, args, opti, true); 12449 } 12450 } else if ("provider".equals(cmd)) { 12451 String[] newArgs; 12452 String name; 12453 if (opti >= args.length) { 12454 name = null; 12455 newArgs = EMPTY_STRING_ARRAY; 12456 } else { 12457 name = args[opti]; 12458 opti++; 12459 newArgs = new String[args.length - opti]; 12460 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12461 } 12462 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12463 pw.println("No providers match: " + name); 12464 pw.println("Use -h for help."); 12465 } 12466 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12467 synchronized (this) { 12468 dumpProvidersLocked(fd, pw, args, opti, true, null); 12469 } 12470 } else if ("service".equals(cmd)) { 12471 String[] newArgs; 12472 String name; 12473 if (opti >= args.length) { 12474 name = null; 12475 newArgs = EMPTY_STRING_ARRAY; 12476 } else { 12477 name = args[opti]; 12478 opti++; 12479 newArgs = new String[args.length - opti]; 12480 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12481 args.length - opti); 12482 } 12483 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12484 pw.println("No services match: " + name); 12485 pw.println("Use -h for help."); 12486 } 12487 } else if ("package".equals(cmd)) { 12488 String[] newArgs; 12489 if (opti >= args.length) { 12490 pw.println("package: no package name specified"); 12491 pw.println("Use -h for help."); 12492 } else { 12493 dumpPackage = args[opti]; 12494 opti++; 12495 newArgs = new String[args.length - opti]; 12496 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12497 args.length - opti); 12498 args = newArgs; 12499 opti = 0; 12500 more = true; 12501 } 12502 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12503 synchronized (this) { 12504 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12505 } 12506 } else if ("write".equals(cmd)) { 12507 mTaskPersister.flush(); 12508 pw.println("All tasks persisted."); 12509 return; 12510 } else { 12511 // Dumping a single activity? 12512 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12513 pw.println("Bad activity command, or no activities match: " + cmd); 12514 pw.println("Use -h for help."); 12515 } 12516 } 12517 if (!more) { 12518 Binder.restoreCallingIdentity(origId); 12519 return; 12520 } 12521 } 12522 12523 // No piece of data specified, dump everything. 12524 synchronized (this) { 12525 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12526 pw.println(); 12527 if (dumpAll) { 12528 pw.println("-------------------------------------------------------------------------------"); 12529 } 12530 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12531 pw.println(); 12532 if (dumpAll) { 12533 pw.println("-------------------------------------------------------------------------------"); 12534 } 12535 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12536 pw.println(); 12537 if (dumpAll) { 12538 pw.println("-------------------------------------------------------------------------------"); 12539 } 12540 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12541 pw.println(); 12542 if (dumpAll) { 12543 pw.println("-------------------------------------------------------------------------------"); 12544 } 12545 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12546 pw.println(); 12547 if (dumpAll) { 12548 pw.println("-------------------------------------------------------------------------------"); 12549 } 12550 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12551 pw.println(); 12552 if (dumpAll) { 12553 pw.println("-------------------------------------------------------------------------------"); 12554 } 12555 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12556 } 12557 Binder.restoreCallingIdentity(origId); 12558 } 12559 12560 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12561 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12562 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12563 12564 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12565 dumpPackage); 12566 boolean needSep = printedAnything; 12567 12568 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12569 dumpPackage, needSep, " mFocusedActivity: "); 12570 if (printed) { 12571 printedAnything = true; 12572 needSep = false; 12573 } 12574 12575 if (dumpPackage == null) { 12576 if (needSep) { 12577 pw.println(); 12578 } 12579 needSep = true; 12580 printedAnything = true; 12581 mStackSupervisor.dump(pw, " "); 12582 } 12583 12584 if (!printedAnything) { 12585 pw.println(" (nothing)"); 12586 } 12587 } 12588 12589 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12590 int opti, boolean dumpAll, String dumpPackage) { 12591 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12592 12593 boolean printedAnything = false; 12594 12595 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12596 boolean printedHeader = false; 12597 12598 final int N = mRecentTasks.size(); 12599 for (int i=0; i<N; i++) { 12600 TaskRecord tr = mRecentTasks.get(i); 12601 if (dumpPackage != null) { 12602 if (tr.realActivity == null || 12603 !dumpPackage.equals(tr.realActivity)) { 12604 continue; 12605 } 12606 } 12607 if (!printedHeader) { 12608 pw.println(" Recent tasks:"); 12609 printedHeader = true; 12610 printedAnything = true; 12611 } 12612 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12613 pw.println(tr); 12614 if (dumpAll) { 12615 mRecentTasks.get(i).dump(pw, " "); 12616 } 12617 } 12618 } 12619 12620 if (!printedAnything) { 12621 pw.println(" (nothing)"); 12622 } 12623 } 12624 12625 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12626 int opti, boolean dumpAll, String dumpPackage) { 12627 boolean needSep = false; 12628 boolean printedAnything = false; 12629 int numPers = 0; 12630 12631 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12632 12633 if (dumpAll) { 12634 final int NP = mProcessNames.getMap().size(); 12635 for (int ip=0; ip<NP; ip++) { 12636 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12637 final int NA = procs.size(); 12638 for (int ia=0; ia<NA; ia++) { 12639 ProcessRecord r = procs.valueAt(ia); 12640 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12641 continue; 12642 } 12643 if (!needSep) { 12644 pw.println(" All known processes:"); 12645 needSep = true; 12646 printedAnything = true; 12647 } 12648 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12649 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12650 pw.print(" "); pw.println(r); 12651 r.dump(pw, " "); 12652 if (r.persistent) { 12653 numPers++; 12654 } 12655 } 12656 } 12657 } 12658 12659 if (mIsolatedProcesses.size() > 0) { 12660 boolean printed = false; 12661 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12662 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12663 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12664 continue; 12665 } 12666 if (!printed) { 12667 if (needSep) { 12668 pw.println(); 12669 } 12670 pw.println(" Isolated process list (sorted by uid):"); 12671 printedAnything = true; 12672 printed = true; 12673 needSep = true; 12674 } 12675 pw.println(String.format("%sIsolated #%2d: %s", 12676 " ", i, r.toString())); 12677 } 12678 } 12679 12680 if (mLruProcesses.size() > 0) { 12681 if (needSep) { 12682 pw.println(); 12683 } 12684 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12685 pw.print(" total, non-act at "); 12686 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12687 pw.print(", non-svc at "); 12688 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12689 pw.println("):"); 12690 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12691 needSep = true; 12692 printedAnything = true; 12693 } 12694 12695 if (dumpAll || dumpPackage != null) { 12696 synchronized (mPidsSelfLocked) { 12697 boolean printed = false; 12698 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12699 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12700 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12701 continue; 12702 } 12703 if (!printed) { 12704 if (needSep) pw.println(); 12705 needSep = true; 12706 pw.println(" PID mappings:"); 12707 printed = true; 12708 printedAnything = true; 12709 } 12710 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12711 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12712 } 12713 } 12714 } 12715 12716 if (mForegroundProcesses.size() > 0) { 12717 synchronized (mPidsSelfLocked) { 12718 boolean printed = false; 12719 for (int i=0; i<mForegroundProcesses.size(); i++) { 12720 ProcessRecord r = mPidsSelfLocked.get( 12721 mForegroundProcesses.valueAt(i).pid); 12722 if (dumpPackage != null && (r == null 12723 || !r.pkgList.containsKey(dumpPackage))) { 12724 continue; 12725 } 12726 if (!printed) { 12727 if (needSep) pw.println(); 12728 needSep = true; 12729 pw.println(" Foreground Processes:"); 12730 printed = true; 12731 printedAnything = true; 12732 } 12733 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12734 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12735 } 12736 } 12737 } 12738 12739 if (mPersistentStartingProcesses.size() > 0) { 12740 if (needSep) pw.println(); 12741 needSep = true; 12742 printedAnything = true; 12743 pw.println(" Persisent processes that are starting:"); 12744 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12745 "Starting Norm", "Restarting PERS", dumpPackage); 12746 } 12747 12748 if (mRemovedProcesses.size() > 0) { 12749 if (needSep) pw.println(); 12750 needSep = true; 12751 printedAnything = true; 12752 pw.println(" Processes that are being removed:"); 12753 dumpProcessList(pw, this, mRemovedProcesses, " ", 12754 "Removed Norm", "Removed PERS", dumpPackage); 12755 } 12756 12757 if (mProcessesOnHold.size() > 0) { 12758 if (needSep) pw.println(); 12759 needSep = true; 12760 printedAnything = true; 12761 pw.println(" Processes that are on old until the system is ready:"); 12762 dumpProcessList(pw, this, mProcessesOnHold, " ", 12763 "OnHold Norm", "OnHold PERS", dumpPackage); 12764 } 12765 12766 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12767 12768 if (mProcessCrashTimes.getMap().size() > 0) { 12769 boolean printed = false; 12770 long now = SystemClock.uptimeMillis(); 12771 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12772 final int NP = pmap.size(); 12773 for (int ip=0; ip<NP; ip++) { 12774 String pname = pmap.keyAt(ip); 12775 SparseArray<Long> uids = pmap.valueAt(ip); 12776 final int N = uids.size(); 12777 for (int i=0; i<N; i++) { 12778 int puid = uids.keyAt(i); 12779 ProcessRecord r = mProcessNames.get(pname, puid); 12780 if (dumpPackage != null && (r == null 12781 || !r.pkgList.containsKey(dumpPackage))) { 12782 continue; 12783 } 12784 if (!printed) { 12785 if (needSep) pw.println(); 12786 needSep = true; 12787 pw.println(" Time since processes crashed:"); 12788 printed = true; 12789 printedAnything = true; 12790 } 12791 pw.print(" Process "); pw.print(pname); 12792 pw.print(" uid "); pw.print(puid); 12793 pw.print(": last crashed "); 12794 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12795 pw.println(" ago"); 12796 } 12797 } 12798 } 12799 12800 if (mBadProcesses.getMap().size() > 0) { 12801 boolean printed = false; 12802 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12803 final int NP = pmap.size(); 12804 for (int ip=0; ip<NP; ip++) { 12805 String pname = pmap.keyAt(ip); 12806 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12807 final int N = uids.size(); 12808 for (int i=0; i<N; i++) { 12809 int puid = uids.keyAt(i); 12810 ProcessRecord r = mProcessNames.get(pname, puid); 12811 if (dumpPackage != null && (r == null 12812 || !r.pkgList.containsKey(dumpPackage))) { 12813 continue; 12814 } 12815 if (!printed) { 12816 if (needSep) pw.println(); 12817 needSep = true; 12818 pw.println(" Bad processes:"); 12819 printedAnything = true; 12820 } 12821 BadProcessInfo info = uids.valueAt(i); 12822 pw.print(" Bad process "); pw.print(pname); 12823 pw.print(" uid "); pw.print(puid); 12824 pw.print(": crashed at time "); pw.println(info.time); 12825 if (info.shortMsg != null) { 12826 pw.print(" Short msg: "); pw.println(info.shortMsg); 12827 } 12828 if (info.longMsg != null) { 12829 pw.print(" Long msg: "); pw.println(info.longMsg); 12830 } 12831 if (info.stack != null) { 12832 pw.println(" Stack:"); 12833 int lastPos = 0; 12834 for (int pos=0; pos<info.stack.length(); pos++) { 12835 if (info.stack.charAt(pos) == '\n') { 12836 pw.print(" "); 12837 pw.write(info.stack, lastPos, pos-lastPos); 12838 pw.println(); 12839 lastPos = pos+1; 12840 } 12841 } 12842 if (lastPos < info.stack.length()) { 12843 pw.print(" "); 12844 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12845 pw.println(); 12846 } 12847 } 12848 } 12849 } 12850 } 12851 12852 if (dumpPackage == null) { 12853 pw.println(); 12854 needSep = false; 12855 pw.println(" mStartedUsers:"); 12856 for (int i=0; i<mStartedUsers.size(); i++) { 12857 UserStartedState uss = mStartedUsers.valueAt(i); 12858 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12859 pw.print(": "); uss.dump("", pw); 12860 } 12861 pw.print(" mStartedUserArray: ["); 12862 for (int i=0; i<mStartedUserArray.length; i++) { 12863 if (i > 0) pw.print(", "); 12864 pw.print(mStartedUserArray[i]); 12865 } 12866 pw.println("]"); 12867 pw.print(" mUserLru: ["); 12868 for (int i=0; i<mUserLru.size(); i++) { 12869 if (i > 0) pw.print(", "); 12870 pw.print(mUserLru.get(i)); 12871 } 12872 pw.println("]"); 12873 if (dumpAll) { 12874 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12875 } 12876 synchronized (mUserProfileGroupIdsSelfLocked) { 12877 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12878 pw.println(" mUserProfileGroupIds:"); 12879 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12880 pw.print(" User #"); 12881 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12882 pw.print(" -> profile #"); 12883 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12884 } 12885 } 12886 } 12887 } 12888 if (mHomeProcess != null && (dumpPackage == null 12889 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12890 if (needSep) { 12891 pw.println(); 12892 needSep = false; 12893 } 12894 pw.println(" mHomeProcess: " + mHomeProcess); 12895 } 12896 if (mPreviousProcess != null && (dumpPackage == null 12897 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12898 if (needSep) { 12899 pw.println(); 12900 needSep = false; 12901 } 12902 pw.println(" mPreviousProcess: " + mPreviousProcess); 12903 } 12904 if (dumpAll) { 12905 StringBuilder sb = new StringBuilder(128); 12906 sb.append(" mPreviousProcessVisibleTime: "); 12907 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12908 pw.println(sb); 12909 } 12910 if (mHeavyWeightProcess != null && (dumpPackage == null 12911 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12912 if (needSep) { 12913 pw.println(); 12914 needSep = false; 12915 } 12916 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12917 } 12918 if (dumpPackage == null) { 12919 pw.println(" mConfiguration: " + mConfiguration); 12920 } 12921 if (dumpAll) { 12922 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12923 if (mCompatModePackages.getPackages().size() > 0) { 12924 boolean printed = false; 12925 for (Map.Entry<String, Integer> entry 12926 : mCompatModePackages.getPackages().entrySet()) { 12927 String pkg = entry.getKey(); 12928 int mode = entry.getValue(); 12929 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12930 continue; 12931 } 12932 if (!printed) { 12933 pw.println(" mScreenCompatPackages:"); 12934 printed = true; 12935 } 12936 pw.print(" "); pw.print(pkg); pw.print(": "); 12937 pw.print(mode); pw.println(); 12938 } 12939 } 12940 } 12941 if (dumpPackage == null) { 12942 if (mSleeping || mWentToSleep || mLockScreenShown) { 12943 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12944 + " mLockScreenShown " + mLockScreenShown); 12945 } 12946 if (mShuttingDown || mRunningVoice) { 12947 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12948 } 12949 } 12950 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12951 || mOrigWaitForDebugger) { 12952 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12953 || dumpPackage.equals(mOrigDebugApp)) { 12954 if (needSep) { 12955 pw.println(); 12956 needSep = false; 12957 } 12958 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12959 + " mDebugTransient=" + mDebugTransient 12960 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12961 } 12962 } 12963 if (mOpenGlTraceApp != null) { 12964 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12965 if (needSep) { 12966 pw.println(); 12967 needSep = false; 12968 } 12969 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12970 } 12971 } 12972 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12973 || mProfileFd != null) { 12974 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12975 if (needSep) { 12976 pw.println(); 12977 needSep = false; 12978 } 12979 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12980 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12981 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12982 + mAutoStopProfiler); 12983 pw.println(" mProfileType=" + mProfileType); 12984 } 12985 } 12986 if (dumpPackage == null) { 12987 if (mAlwaysFinishActivities || mController != null) { 12988 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12989 + " mController=" + mController); 12990 } 12991 if (dumpAll) { 12992 pw.println(" Total persistent processes: " + numPers); 12993 pw.println(" mProcessesReady=" + mProcessesReady 12994 + " mSystemReady=" + mSystemReady 12995 + " mBooted=" + mBooted 12996 + " mFactoryTest=" + mFactoryTest); 12997 pw.println(" mBooting=" + mBooting 12998 + " mCallFinishBooting=" + mCallFinishBooting 12999 + " mBootAnimationComplete=" + mBootAnimationComplete); 13000 pw.print(" mLastPowerCheckRealtime="); 13001 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13002 pw.println(""); 13003 pw.print(" mLastPowerCheckUptime="); 13004 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13005 pw.println(""); 13006 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13007 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13008 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13009 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13010 + " (" + mLruProcesses.size() + " total)" 13011 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13012 + " mNumServiceProcs=" + mNumServiceProcs 13013 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13014 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13015 + " mLastMemoryLevel" + mLastMemoryLevel 13016 + " mLastNumProcesses" + mLastNumProcesses); 13017 long now = SystemClock.uptimeMillis(); 13018 pw.print(" mLastIdleTime="); 13019 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13020 pw.print(" mLowRamSinceLastIdle="); 13021 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13022 pw.println(); 13023 } 13024 } 13025 13026 if (!printedAnything) { 13027 pw.println(" (nothing)"); 13028 } 13029 } 13030 13031 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13032 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13033 if (mProcessesToGc.size() > 0) { 13034 boolean printed = false; 13035 long now = SystemClock.uptimeMillis(); 13036 for (int i=0; i<mProcessesToGc.size(); i++) { 13037 ProcessRecord proc = mProcessesToGc.get(i); 13038 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13039 continue; 13040 } 13041 if (!printed) { 13042 if (needSep) pw.println(); 13043 needSep = true; 13044 pw.println(" Processes that are waiting to GC:"); 13045 printed = true; 13046 } 13047 pw.print(" Process "); pw.println(proc); 13048 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13049 pw.print(", last gced="); 13050 pw.print(now-proc.lastRequestedGc); 13051 pw.print(" ms ago, last lowMem="); 13052 pw.print(now-proc.lastLowMemory); 13053 pw.println(" ms ago"); 13054 13055 } 13056 } 13057 return needSep; 13058 } 13059 13060 void printOomLevel(PrintWriter pw, String name, int adj) { 13061 pw.print(" "); 13062 if (adj >= 0) { 13063 pw.print(' '); 13064 if (adj < 10) pw.print(' '); 13065 } else { 13066 if (adj > -10) pw.print(' '); 13067 } 13068 pw.print(adj); 13069 pw.print(": "); 13070 pw.print(name); 13071 pw.print(" ("); 13072 pw.print(mProcessList.getMemLevel(adj)/1024); 13073 pw.println(" kB)"); 13074 } 13075 13076 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13077 int opti, boolean dumpAll) { 13078 boolean needSep = false; 13079 13080 if (mLruProcesses.size() > 0) { 13081 if (needSep) pw.println(); 13082 needSep = true; 13083 pw.println(" OOM levels:"); 13084 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13085 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13086 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13087 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13088 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13089 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13090 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13091 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13092 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13093 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13094 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13095 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13096 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13097 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13098 13099 if (needSep) pw.println(); 13100 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13101 pw.print(" total, non-act at "); 13102 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13103 pw.print(", non-svc at "); 13104 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13105 pw.println("):"); 13106 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13107 needSep = true; 13108 } 13109 13110 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13111 13112 pw.println(); 13113 pw.println(" mHomeProcess: " + mHomeProcess); 13114 pw.println(" mPreviousProcess: " + mPreviousProcess); 13115 if (mHeavyWeightProcess != null) { 13116 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13117 } 13118 13119 return true; 13120 } 13121 13122 /** 13123 * There are three ways to call this: 13124 * - no provider specified: dump all the providers 13125 * - a flattened component name that matched an existing provider was specified as the 13126 * first arg: dump that one provider 13127 * - the first arg isn't the flattened component name of an existing provider: 13128 * dump all providers whose component contains the first arg as a substring 13129 */ 13130 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13131 int opti, boolean dumpAll) { 13132 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13133 } 13134 13135 static class ItemMatcher { 13136 ArrayList<ComponentName> components; 13137 ArrayList<String> strings; 13138 ArrayList<Integer> objects; 13139 boolean all; 13140 13141 ItemMatcher() { 13142 all = true; 13143 } 13144 13145 void build(String name) { 13146 ComponentName componentName = ComponentName.unflattenFromString(name); 13147 if (componentName != null) { 13148 if (components == null) { 13149 components = new ArrayList<ComponentName>(); 13150 } 13151 components.add(componentName); 13152 all = false; 13153 } else { 13154 int objectId = 0; 13155 // Not a '/' separated full component name; maybe an object ID? 13156 try { 13157 objectId = Integer.parseInt(name, 16); 13158 if (objects == null) { 13159 objects = new ArrayList<Integer>(); 13160 } 13161 objects.add(objectId); 13162 all = false; 13163 } catch (RuntimeException e) { 13164 // Not an integer; just do string match. 13165 if (strings == null) { 13166 strings = new ArrayList<String>(); 13167 } 13168 strings.add(name); 13169 all = false; 13170 } 13171 } 13172 } 13173 13174 int build(String[] args, int opti) { 13175 for (; opti<args.length; opti++) { 13176 String name = args[opti]; 13177 if ("--".equals(name)) { 13178 return opti+1; 13179 } 13180 build(name); 13181 } 13182 return opti; 13183 } 13184 13185 boolean match(Object object, ComponentName comp) { 13186 if (all) { 13187 return true; 13188 } 13189 if (components != null) { 13190 for (int i=0; i<components.size(); i++) { 13191 if (components.get(i).equals(comp)) { 13192 return true; 13193 } 13194 } 13195 } 13196 if (objects != null) { 13197 for (int i=0; i<objects.size(); i++) { 13198 if (System.identityHashCode(object) == objects.get(i)) { 13199 return true; 13200 } 13201 } 13202 } 13203 if (strings != null) { 13204 String flat = comp.flattenToString(); 13205 for (int i=0; i<strings.size(); i++) { 13206 if (flat.contains(strings.get(i))) { 13207 return true; 13208 } 13209 } 13210 } 13211 return false; 13212 } 13213 } 13214 13215 /** 13216 * There are three things that cmd can be: 13217 * - a flattened component name that matches an existing activity 13218 * - the cmd arg isn't the flattened component name of an existing activity: 13219 * dump all activity whose component contains the cmd as a substring 13220 * - A hex number of the ActivityRecord object instance. 13221 */ 13222 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13223 int opti, boolean dumpAll) { 13224 ArrayList<ActivityRecord> activities; 13225 13226 synchronized (this) { 13227 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13228 } 13229 13230 if (activities.size() <= 0) { 13231 return false; 13232 } 13233 13234 String[] newArgs = new String[args.length - opti]; 13235 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13236 13237 TaskRecord lastTask = null; 13238 boolean needSep = false; 13239 for (int i=activities.size()-1; i>=0; i--) { 13240 ActivityRecord r = activities.get(i); 13241 if (needSep) { 13242 pw.println(); 13243 } 13244 needSep = true; 13245 synchronized (this) { 13246 if (lastTask != r.task) { 13247 lastTask = r.task; 13248 pw.print("TASK "); pw.print(lastTask.affinity); 13249 pw.print(" id="); pw.println(lastTask.taskId); 13250 if (dumpAll) { 13251 lastTask.dump(pw, " "); 13252 } 13253 } 13254 } 13255 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13256 } 13257 return true; 13258 } 13259 13260 /** 13261 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13262 * there is a thread associated with the activity. 13263 */ 13264 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13265 final ActivityRecord r, String[] args, boolean dumpAll) { 13266 String innerPrefix = prefix + " "; 13267 synchronized (this) { 13268 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13269 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13270 pw.print(" pid="); 13271 if (r.app != null) pw.println(r.app.pid); 13272 else pw.println("(not running)"); 13273 if (dumpAll) { 13274 r.dump(pw, innerPrefix); 13275 } 13276 } 13277 if (r.app != null && r.app.thread != null) { 13278 // flush anything that is already in the PrintWriter since the thread is going 13279 // to write to the file descriptor directly 13280 pw.flush(); 13281 try { 13282 TransferPipe tp = new TransferPipe(); 13283 try { 13284 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13285 r.appToken, innerPrefix, args); 13286 tp.go(fd); 13287 } finally { 13288 tp.kill(); 13289 } 13290 } catch (IOException e) { 13291 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13292 } catch (RemoteException e) { 13293 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13294 } 13295 } 13296 } 13297 13298 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13299 int opti, boolean dumpAll, String dumpPackage) { 13300 boolean needSep = false; 13301 boolean onlyHistory = false; 13302 boolean printedAnything = false; 13303 13304 if ("history".equals(dumpPackage)) { 13305 if (opti < args.length && "-s".equals(args[opti])) { 13306 dumpAll = false; 13307 } 13308 onlyHistory = true; 13309 dumpPackage = null; 13310 } 13311 13312 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13313 if (!onlyHistory && dumpAll) { 13314 if (mRegisteredReceivers.size() > 0) { 13315 boolean printed = false; 13316 Iterator it = mRegisteredReceivers.values().iterator(); 13317 while (it.hasNext()) { 13318 ReceiverList r = (ReceiverList)it.next(); 13319 if (dumpPackage != null && (r.app == null || 13320 !dumpPackage.equals(r.app.info.packageName))) { 13321 continue; 13322 } 13323 if (!printed) { 13324 pw.println(" Registered Receivers:"); 13325 needSep = true; 13326 printed = true; 13327 printedAnything = true; 13328 } 13329 pw.print(" * "); pw.println(r); 13330 r.dump(pw, " "); 13331 } 13332 } 13333 13334 if (mReceiverResolver.dump(pw, needSep ? 13335 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13336 " ", dumpPackage, false)) { 13337 needSep = true; 13338 printedAnything = true; 13339 } 13340 } 13341 13342 for (BroadcastQueue q : mBroadcastQueues) { 13343 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13344 printedAnything |= needSep; 13345 } 13346 13347 needSep = true; 13348 13349 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13350 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13351 if (needSep) { 13352 pw.println(); 13353 } 13354 needSep = true; 13355 printedAnything = true; 13356 pw.print(" Sticky broadcasts for user "); 13357 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13358 StringBuilder sb = new StringBuilder(128); 13359 for (Map.Entry<String, ArrayList<Intent>> ent 13360 : mStickyBroadcasts.valueAt(user).entrySet()) { 13361 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13362 if (dumpAll) { 13363 pw.println(":"); 13364 ArrayList<Intent> intents = ent.getValue(); 13365 final int N = intents.size(); 13366 for (int i=0; i<N; i++) { 13367 sb.setLength(0); 13368 sb.append(" Intent: "); 13369 intents.get(i).toShortString(sb, false, true, false, false); 13370 pw.println(sb.toString()); 13371 Bundle bundle = intents.get(i).getExtras(); 13372 if (bundle != null) { 13373 pw.print(" "); 13374 pw.println(bundle.toString()); 13375 } 13376 } 13377 } else { 13378 pw.println(""); 13379 } 13380 } 13381 } 13382 } 13383 13384 if (!onlyHistory && dumpAll) { 13385 pw.println(); 13386 for (BroadcastQueue queue : mBroadcastQueues) { 13387 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13388 + queue.mBroadcastsScheduled); 13389 } 13390 pw.println(" mHandler:"); 13391 mHandler.dump(new PrintWriterPrinter(pw), " "); 13392 needSep = true; 13393 printedAnything = true; 13394 } 13395 13396 if (!printedAnything) { 13397 pw.println(" (nothing)"); 13398 } 13399 } 13400 13401 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13402 int opti, boolean dumpAll, String dumpPackage) { 13403 boolean needSep; 13404 boolean printedAnything = false; 13405 13406 ItemMatcher matcher = new ItemMatcher(); 13407 matcher.build(args, opti); 13408 13409 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13410 13411 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13412 printedAnything |= needSep; 13413 13414 if (mLaunchingProviders.size() > 0) { 13415 boolean printed = false; 13416 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13417 ContentProviderRecord r = mLaunchingProviders.get(i); 13418 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13419 continue; 13420 } 13421 if (!printed) { 13422 if (needSep) pw.println(); 13423 needSep = true; 13424 pw.println(" Launching content providers:"); 13425 printed = true; 13426 printedAnything = true; 13427 } 13428 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13429 pw.println(r); 13430 } 13431 } 13432 13433 if (mGrantedUriPermissions.size() > 0) { 13434 boolean printed = false; 13435 int dumpUid = -2; 13436 if (dumpPackage != null) { 13437 try { 13438 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13439 } catch (NameNotFoundException e) { 13440 dumpUid = -1; 13441 } 13442 } 13443 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13444 int uid = mGrantedUriPermissions.keyAt(i); 13445 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13446 continue; 13447 } 13448 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13449 if (!printed) { 13450 if (needSep) pw.println(); 13451 needSep = true; 13452 pw.println(" Granted Uri Permissions:"); 13453 printed = true; 13454 printedAnything = true; 13455 } 13456 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13457 for (UriPermission perm : perms.values()) { 13458 pw.print(" "); pw.println(perm); 13459 if (dumpAll) { 13460 perm.dump(pw, " "); 13461 } 13462 } 13463 } 13464 } 13465 13466 if (!printedAnything) { 13467 pw.println(" (nothing)"); 13468 } 13469 } 13470 13471 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13472 int opti, boolean dumpAll, String dumpPackage) { 13473 boolean printed = false; 13474 13475 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13476 13477 if (mIntentSenderRecords.size() > 0) { 13478 Iterator<WeakReference<PendingIntentRecord>> it 13479 = mIntentSenderRecords.values().iterator(); 13480 while (it.hasNext()) { 13481 WeakReference<PendingIntentRecord> ref = it.next(); 13482 PendingIntentRecord rec = ref != null ? ref.get(): null; 13483 if (dumpPackage != null && (rec == null 13484 || !dumpPackage.equals(rec.key.packageName))) { 13485 continue; 13486 } 13487 printed = true; 13488 if (rec != null) { 13489 pw.print(" * "); pw.println(rec); 13490 if (dumpAll) { 13491 rec.dump(pw, " "); 13492 } 13493 } else { 13494 pw.print(" * "); pw.println(ref); 13495 } 13496 } 13497 } 13498 13499 if (!printed) { 13500 pw.println(" (nothing)"); 13501 } 13502 } 13503 13504 private static final int dumpProcessList(PrintWriter pw, 13505 ActivityManagerService service, List list, 13506 String prefix, String normalLabel, String persistentLabel, 13507 String dumpPackage) { 13508 int numPers = 0; 13509 final int N = list.size()-1; 13510 for (int i=N; i>=0; i--) { 13511 ProcessRecord r = (ProcessRecord)list.get(i); 13512 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13513 continue; 13514 } 13515 pw.println(String.format("%s%s #%2d: %s", 13516 prefix, (r.persistent ? persistentLabel : normalLabel), 13517 i, r.toString())); 13518 if (r.persistent) { 13519 numPers++; 13520 } 13521 } 13522 return numPers; 13523 } 13524 13525 private static final boolean dumpProcessOomList(PrintWriter pw, 13526 ActivityManagerService service, List<ProcessRecord> origList, 13527 String prefix, String normalLabel, String persistentLabel, 13528 boolean inclDetails, String dumpPackage) { 13529 13530 ArrayList<Pair<ProcessRecord, Integer>> list 13531 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13532 for (int i=0; i<origList.size(); i++) { 13533 ProcessRecord r = origList.get(i); 13534 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13535 continue; 13536 } 13537 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13538 } 13539 13540 if (list.size() <= 0) { 13541 return false; 13542 } 13543 13544 Comparator<Pair<ProcessRecord, Integer>> comparator 13545 = new Comparator<Pair<ProcessRecord, Integer>>() { 13546 @Override 13547 public int compare(Pair<ProcessRecord, Integer> object1, 13548 Pair<ProcessRecord, Integer> object2) { 13549 if (object1.first.setAdj != object2.first.setAdj) { 13550 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13551 } 13552 if (object1.second.intValue() != object2.second.intValue()) { 13553 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13554 } 13555 return 0; 13556 } 13557 }; 13558 13559 Collections.sort(list, comparator); 13560 13561 final long curRealtime = SystemClock.elapsedRealtime(); 13562 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13563 final long curUptime = SystemClock.uptimeMillis(); 13564 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13565 13566 for (int i=list.size()-1; i>=0; i--) { 13567 ProcessRecord r = list.get(i).first; 13568 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13569 char schedGroup; 13570 switch (r.setSchedGroup) { 13571 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13572 schedGroup = 'B'; 13573 break; 13574 case Process.THREAD_GROUP_DEFAULT: 13575 schedGroup = 'F'; 13576 break; 13577 default: 13578 schedGroup = '?'; 13579 break; 13580 } 13581 char foreground; 13582 if (r.foregroundActivities) { 13583 foreground = 'A'; 13584 } else if (r.foregroundServices) { 13585 foreground = 'S'; 13586 } else { 13587 foreground = ' '; 13588 } 13589 String procState = ProcessList.makeProcStateString(r.curProcState); 13590 pw.print(prefix); 13591 pw.print(r.persistent ? persistentLabel : normalLabel); 13592 pw.print(" #"); 13593 int num = (origList.size()-1)-list.get(i).second; 13594 if (num < 10) pw.print(' '); 13595 pw.print(num); 13596 pw.print(": "); 13597 pw.print(oomAdj); 13598 pw.print(' '); 13599 pw.print(schedGroup); 13600 pw.print('/'); 13601 pw.print(foreground); 13602 pw.print('/'); 13603 pw.print(procState); 13604 pw.print(" trm:"); 13605 if (r.trimMemoryLevel < 10) pw.print(' '); 13606 pw.print(r.trimMemoryLevel); 13607 pw.print(' '); 13608 pw.print(r.toShortString()); 13609 pw.print(" ("); 13610 pw.print(r.adjType); 13611 pw.println(')'); 13612 if (r.adjSource != null || r.adjTarget != null) { 13613 pw.print(prefix); 13614 pw.print(" "); 13615 if (r.adjTarget instanceof ComponentName) { 13616 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13617 } else if (r.adjTarget != null) { 13618 pw.print(r.adjTarget.toString()); 13619 } else { 13620 pw.print("{null}"); 13621 } 13622 pw.print("<="); 13623 if (r.adjSource instanceof ProcessRecord) { 13624 pw.print("Proc{"); 13625 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13626 pw.println("}"); 13627 } else if (r.adjSource != null) { 13628 pw.println(r.adjSource.toString()); 13629 } else { 13630 pw.println("{null}"); 13631 } 13632 } 13633 if (inclDetails) { 13634 pw.print(prefix); 13635 pw.print(" "); 13636 pw.print("oom: max="); pw.print(r.maxAdj); 13637 pw.print(" curRaw="); pw.print(r.curRawAdj); 13638 pw.print(" setRaw="); pw.print(r.setRawAdj); 13639 pw.print(" cur="); pw.print(r.curAdj); 13640 pw.print(" set="); pw.println(r.setAdj); 13641 pw.print(prefix); 13642 pw.print(" "); 13643 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13644 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13645 pw.print(" lastPss="); pw.print(r.lastPss); 13646 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13647 pw.print(prefix); 13648 pw.print(" "); 13649 pw.print("cached="); pw.print(r.cached); 13650 pw.print(" empty="); pw.print(r.empty); 13651 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13652 13653 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13654 if (r.lastWakeTime != 0) { 13655 long wtime; 13656 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13657 synchronized (stats) { 13658 wtime = stats.getProcessWakeTime(r.info.uid, 13659 r.pid, curRealtime); 13660 } 13661 long timeUsed = wtime - r.lastWakeTime; 13662 pw.print(prefix); 13663 pw.print(" "); 13664 pw.print("keep awake over "); 13665 TimeUtils.formatDuration(realtimeSince, pw); 13666 pw.print(" used "); 13667 TimeUtils.formatDuration(timeUsed, pw); 13668 pw.print(" ("); 13669 pw.print((timeUsed*100)/realtimeSince); 13670 pw.println("%)"); 13671 } 13672 if (r.lastCpuTime != 0) { 13673 long timeUsed = r.curCpuTime - r.lastCpuTime; 13674 pw.print(prefix); 13675 pw.print(" "); 13676 pw.print("run cpu over "); 13677 TimeUtils.formatDuration(uptimeSince, pw); 13678 pw.print(" used "); 13679 TimeUtils.formatDuration(timeUsed, pw); 13680 pw.print(" ("); 13681 pw.print((timeUsed*100)/uptimeSince); 13682 pw.println("%)"); 13683 } 13684 } 13685 } 13686 } 13687 return true; 13688 } 13689 13690 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13691 String[] args) { 13692 ArrayList<ProcessRecord> procs; 13693 synchronized (this) { 13694 if (args != null && args.length > start 13695 && args[start].charAt(0) != '-') { 13696 procs = new ArrayList<ProcessRecord>(); 13697 int pid = -1; 13698 try { 13699 pid = Integer.parseInt(args[start]); 13700 } catch (NumberFormatException e) { 13701 } 13702 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13703 ProcessRecord proc = mLruProcesses.get(i); 13704 if (proc.pid == pid) { 13705 procs.add(proc); 13706 } else if (allPkgs && proc.pkgList != null 13707 && proc.pkgList.containsKey(args[start])) { 13708 procs.add(proc); 13709 } else if (proc.processName.equals(args[start])) { 13710 procs.add(proc); 13711 } 13712 } 13713 if (procs.size() <= 0) { 13714 return null; 13715 } 13716 } else { 13717 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13718 } 13719 } 13720 return procs; 13721 } 13722 13723 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13724 PrintWriter pw, String[] args) { 13725 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13726 if (procs == null) { 13727 pw.println("No process found for: " + args[0]); 13728 return; 13729 } 13730 13731 long uptime = SystemClock.uptimeMillis(); 13732 long realtime = SystemClock.elapsedRealtime(); 13733 pw.println("Applications Graphics Acceleration Info:"); 13734 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13735 13736 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13737 ProcessRecord r = procs.get(i); 13738 if (r.thread != null) { 13739 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13740 pw.flush(); 13741 try { 13742 TransferPipe tp = new TransferPipe(); 13743 try { 13744 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13745 tp.go(fd); 13746 } finally { 13747 tp.kill(); 13748 } 13749 } catch (IOException e) { 13750 pw.println("Failure while dumping the app: " + r); 13751 pw.flush(); 13752 } catch (RemoteException e) { 13753 pw.println("Got a RemoteException while dumping the app " + r); 13754 pw.flush(); 13755 } 13756 } 13757 } 13758 } 13759 13760 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13761 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13762 if (procs == null) { 13763 pw.println("No process found for: " + args[0]); 13764 return; 13765 } 13766 13767 pw.println("Applications Database Info:"); 13768 13769 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13770 ProcessRecord r = procs.get(i); 13771 if (r.thread != null) { 13772 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13773 pw.flush(); 13774 try { 13775 TransferPipe tp = new TransferPipe(); 13776 try { 13777 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13778 tp.go(fd); 13779 } finally { 13780 tp.kill(); 13781 } 13782 } catch (IOException e) { 13783 pw.println("Failure while dumping the app: " + r); 13784 pw.flush(); 13785 } catch (RemoteException e) { 13786 pw.println("Got a RemoteException while dumping the app " + r); 13787 pw.flush(); 13788 } 13789 } 13790 } 13791 } 13792 13793 final static class MemItem { 13794 final boolean isProc; 13795 final String label; 13796 final String shortLabel; 13797 final long pss; 13798 final int id; 13799 final boolean hasActivities; 13800 ArrayList<MemItem> subitems; 13801 13802 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13803 boolean _hasActivities) { 13804 isProc = true; 13805 label = _label; 13806 shortLabel = _shortLabel; 13807 pss = _pss; 13808 id = _id; 13809 hasActivities = _hasActivities; 13810 } 13811 13812 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13813 isProc = false; 13814 label = _label; 13815 shortLabel = _shortLabel; 13816 pss = _pss; 13817 id = _id; 13818 hasActivities = false; 13819 } 13820 } 13821 13822 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13823 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13824 if (sort && !isCompact) { 13825 Collections.sort(items, new Comparator<MemItem>() { 13826 @Override 13827 public int compare(MemItem lhs, MemItem rhs) { 13828 if (lhs.pss < rhs.pss) { 13829 return 1; 13830 } else if (lhs.pss > rhs.pss) { 13831 return -1; 13832 } 13833 return 0; 13834 } 13835 }); 13836 } 13837 13838 for (int i=0; i<items.size(); i++) { 13839 MemItem mi = items.get(i); 13840 if (!isCompact) { 13841 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13842 } else if (mi.isProc) { 13843 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13844 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13845 pw.println(mi.hasActivities ? ",a" : ",e"); 13846 } else { 13847 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13848 pw.println(mi.pss); 13849 } 13850 if (mi.subitems != null) { 13851 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13852 true, isCompact); 13853 } 13854 } 13855 } 13856 13857 // These are in KB. 13858 static final long[] DUMP_MEM_BUCKETS = new long[] { 13859 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13860 120*1024, 160*1024, 200*1024, 13861 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13862 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13863 }; 13864 13865 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13866 boolean stackLike) { 13867 int start = label.lastIndexOf('.'); 13868 if (start >= 0) start++; 13869 else start = 0; 13870 int end = label.length(); 13871 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13872 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13873 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13874 out.append(bucket); 13875 out.append(stackLike ? "MB." : "MB "); 13876 out.append(label, start, end); 13877 return; 13878 } 13879 } 13880 out.append(memKB/1024); 13881 out.append(stackLike ? "MB." : "MB "); 13882 out.append(label, start, end); 13883 } 13884 13885 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13886 ProcessList.NATIVE_ADJ, 13887 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13888 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13889 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13890 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13891 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13892 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13893 }; 13894 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13895 "Native", 13896 "System", "Persistent", "Persistent Service", "Foreground", 13897 "Visible", "Perceptible", 13898 "Heavy Weight", "Backup", 13899 "A Services", "Home", 13900 "Previous", "B Services", "Cached" 13901 }; 13902 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13903 "native", 13904 "sys", "pers", "persvc", "fore", 13905 "vis", "percept", 13906 "heavy", "backup", 13907 "servicea", "home", 13908 "prev", "serviceb", "cached" 13909 }; 13910 13911 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13912 long realtime, boolean isCheckinRequest, boolean isCompact) { 13913 if (isCheckinRequest || isCompact) { 13914 // short checkin version 13915 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13916 } else { 13917 pw.println("Applications Memory Usage (kB):"); 13918 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13919 } 13920 } 13921 13922 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13923 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13924 boolean dumpDetails = false; 13925 boolean dumpFullDetails = false; 13926 boolean dumpDalvik = false; 13927 boolean oomOnly = false; 13928 boolean isCompact = false; 13929 boolean localOnly = false; 13930 boolean packages = false; 13931 13932 int opti = 0; 13933 while (opti < args.length) { 13934 String opt = args[opti]; 13935 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13936 break; 13937 } 13938 opti++; 13939 if ("-a".equals(opt)) { 13940 dumpDetails = true; 13941 dumpFullDetails = true; 13942 dumpDalvik = true; 13943 } else if ("-d".equals(opt)) { 13944 dumpDalvik = true; 13945 } else if ("-c".equals(opt)) { 13946 isCompact = true; 13947 } else if ("--oom".equals(opt)) { 13948 oomOnly = true; 13949 } else if ("--local".equals(opt)) { 13950 localOnly = true; 13951 } else if ("--package".equals(opt)) { 13952 packages = true; 13953 } else if ("-h".equals(opt)) { 13954 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13955 pw.println(" -a: include all available information for each process."); 13956 pw.println(" -d: include dalvik details when dumping process details."); 13957 pw.println(" -c: dump in a compact machine-parseable representation."); 13958 pw.println(" --oom: only show processes organized by oom adj."); 13959 pw.println(" --local: only collect details locally, don't call process."); 13960 pw.println(" --package: interpret process arg as package, dumping all"); 13961 pw.println(" processes that have loaded that package."); 13962 pw.println("If [process] is specified it can be the name or "); 13963 pw.println("pid of a specific process to dump."); 13964 return; 13965 } else { 13966 pw.println("Unknown argument: " + opt + "; use -h for help"); 13967 } 13968 } 13969 13970 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13971 long uptime = SystemClock.uptimeMillis(); 13972 long realtime = SystemClock.elapsedRealtime(); 13973 final long[] tmpLong = new long[1]; 13974 13975 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13976 if (procs == null) { 13977 // No Java processes. Maybe they want to print a native process. 13978 if (args != null && args.length > opti 13979 && args[opti].charAt(0) != '-') { 13980 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13981 = new ArrayList<ProcessCpuTracker.Stats>(); 13982 updateCpuStatsNow(); 13983 int findPid = -1; 13984 try { 13985 findPid = Integer.parseInt(args[opti]); 13986 } catch (NumberFormatException e) { 13987 } 13988 synchronized (mProcessCpuTracker) { 13989 final int N = mProcessCpuTracker.countStats(); 13990 for (int i=0; i<N; i++) { 13991 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13992 if (st.pid == findPid || (st.baseName != null 13993 && st.baseName.equals(args[opti]))) { 13994 nativeProcs.add(st); 13995 } 13996 } 13997 } 13998 if (nativeProcs.size() > 0) { 13999 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14000 isCompact); 14001 Debug.MemoryInfo mi = null; 14002 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14003 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14004 final int pid = r.pid; 14005 if (!isCheckinRequest && dumpDetails) { 14006 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14007 } 14008 if (mi == null) { 14009 mi = new Debug.MemoryInfo(); 14010 } 14011 if (dumpDetails || (!brief && !oomOnly)) { 14012 Debug.getMemoryInfo(pid, mi); 14013 } else { 14014 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14015 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14016 } 14017 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14018 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14019 if (isCheckinRequest) { 14020 pw.println(); 14021 } 14022 } 14023 return; 14024 } 14025 } 14026 pw.println("No process found for: " + args[opti]); 14027 return; 14028 } 14029 14030 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14031 dumpDetails = true; 14032 } 14033 14034 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14035 14036 String[] innerArgs = new String[args.length-opti]; 14037 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14038 14039 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14040 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14041 long nativePss=0, dalvikPss=0, otherPss=0; 14042 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14043 14044 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14045 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14046 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14047 14048 long totalPss = 0; 14049 long cachedPss = 0; 14050 14051 Debug.MemoryInfo mi = null; 14052 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14053 final ProcessRecord r = procs.get(i); 14054 final IApplicationThread thread; 14055 final int pid; 14056 final int oomAdj; 14057 final boolean hasActivities; 14058 synchronized (this) { 14059 thread = r.thread; 14060 pid = r.pid; 14061 oomAdj = r.getSetAdjWithServices(); 14062 hasActivities = r.activities.size() > 0; 14063 } 14064 if (thread != null) { 14065 if (!isCheckinRequest && dumpDetails) { 14066 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14067 } 14068 if (mi == null) { 14069 mi = new Debug.MemoryInfo(); 14070 } 14071 if (dumpDetails || (!brief && !oomOnly)) { 14072 Debug.getMemoryInfo(pid, mi); 14073 } else { 14074 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14075 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14076 } 14077 if (dumpDetails) { 14078 if (localOnly) { 14079 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14080 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14081 if (isCheckinRequest) { 14082 pw.println(); 14083 } 14084 } else { 14085 try { 14086 pw.flush(); 14087 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14088 dumpDalvik, innerArgs); 14089 } catch (RemoteException e) { 14090 if (!isCheckinRequest) { 14091 pw.println("Got RemoteException!"); 14092 pw.flush(); 14093 } 14094 } 14095 } 14096 } 14097 14098 final long myTotalPss = mi.getTotalPss(); 14099 final long myTotalUss = mi.getTotalUss(); 14100 14101 synchronized (this) { 14102 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14103 // Record this for posterity if the process has been stable. 14104 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14105 } 14106 } 14107 14108 if (!isCheckinRequest && mi != null) { 14109 totalPss += myTotalPss; 14110 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14111 (hasActivities ? " / activities)" : ")"), 14112 r.processName, myTotalPss, pid, hasActivities); 14113 procMems.add(pssItem); 14114 procMemsMap.put(pid, pssItem); 14115 14116 nativePss += mi.nativePss; 14117 dalvikPss += mi.dalvikPss; 14118 otherPss += mi.otherPss; 14119 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14120 long mem = mi.getOtherPss(j); 14121 miscPss[j] += mem; 14122 otherPss -= mem; 14123 } 14124 14125 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14126 cachedPss += myTotalPss; 14127 } 14128 14129 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14130 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14131 || oomIndex == (oomPss.length-1)) { 14132 oomPss[oomIndex] += myTotalPss; 14133 if (oomProcs[oomIndex] == null) { 14134 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14135 } 14136 oomProcs[oomIndex].add(pssItem); 14137 break; 14138 } 14139 } 14140 } 14141 } 14142 } 14143 14144 long nativeProcTotalPss = 0; 14145 14146 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14147 // If we are showing aggregations, also look for native processes to 14148 // include so that our aggregations are more accurate. 14149 updateCpuStatsNow(); 14150 synchronized (mProcessCpuTracker) { 14151 final int N = mProcessCpuTracker.countStats(); 14152 for (int i=0; i<N; i++) { 14153 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14154 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14155 if (mi == null) { 14156 mi = new Debug.MemoryInfo(); 14157 } 14158 if (!brief && !oomOnly) { 14159 Debug.getMemoryInfo(st.pid, mi); 14160 } else { 14161 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14162 mi.nativePrivateDirty = (int)tmpLong[0]; 14163 } 14164 14165 final long myTotalPss = mi.getTotalPss(); 14166 totalPss += myTotalPss; 14167 nativeProcTotalPss += myTotalPss; 14168 14169 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14170 st.name, myTotalPss, st.pid, false); 14171 procMems.add(pssItem); 14172 14173 nativePss += mi.nativePss; 14174 dalvikPss += mi.dalvikPss; 14175 otherPss += mi.otherPss; 14176 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14177 long mem = mi.getOtherPss(j); 14178 miscPss[j] += mem; 14179 otherPss -= mem; 14180 } 14181 oomPss[0] += myTotalPss; 14182 if (oomProcs[0] == null) { 14183 oomProcs[0] = new ArrayList<MemItem>(); 14184 } 14185 oomProcs[0].add(pssItem); 14186 } 14187 } 14188 } 14189 14190 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14191 14192 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14193 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14194 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14195 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14196 String label = Debug.MemoryInfo.getOtherLabel(j); 14197 catMems.add(new MemItem(label, label, miscPss[j], j)); 14198 } 14199 14200 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14201 for (int j=0; j<oomPss.length; j++) { 14202 if (oomPss[j] != 0) { 14203 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14204 : DUMP_MEM_OOM_LABEL[j]; 14205 MemItem item = new MemItem(label, label, oomPss[j], 14206 DUMP_MEM_OOM_ADJ[j]); 14207 item.subitems = oomProcs[j]; 14208 oomMems.add(item); 14209 } 14210 } 14211 14212 if (!brief && !oomOnly && !isCompact) { 14213 pw.println(); 14214 pw.println("Total PSS by process:"); 14215 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14216 pw.println(); 14217 } 14218 if (!isCompact) { 14219 pw.println("Total PSS by OOM adjustment:"); 14220 } 14221 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14222 if (!brief && !oomOnly) { 14223 PrintWriter out = categoryPw != null ? categoryPw : pw; 14224 if (!isCompact) { 14225 out.println(); 14226 out.println("Total PSS by category:"); 14227 } 14228 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14229 } 14230 if (!isCompact) { 14231 pw.println(); 14232 } 14233 MemInfoReader memInfo = new MemInfoReader(); 14234 memInfo.readMemInfo(); 14235 if (nativeProcTotalPss > 0) { 14236 synchronized (this) { 14237 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14238 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14239 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14240 nativeProcTotalPss); 14241 } 14242 } 14243 if (!brief) { 14244 if (!isCompact) { 14245 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14246 pw.print(" kB (status "); 14247 switch (mLastMemoryLevel) { 14248 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14249 pw.println("normal)"); 14250 break; 14251 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14252 pw.println("moderate)"); 14253 break; 14254 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14255 pw.println("low)"); 14256 break; 14257 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14258 pw.println("critical)"); 14259 break; 14260 default: 14261 pw.print(mLastMemoryLevel); 14262 pw.println(")"); 14263 break; 14264 } 14265 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14266 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14267 pw.print(cachedPss); pw.print(" cached pss + "); 14268 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14269 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14270 } else { 14271 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14272 pw.print(cachedPss + memInfo.getCachedSizeKb() 14273 + memInfo.getFreeSizeKb()); pw.print(","); 14274 pw.println(totalPss - cachedPss); 14275 } 14276 } 14277 if (!isCompact) { 14278 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14279 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14280 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14281 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14282 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14283 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14284 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14285 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14286 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14287 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14288 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14289 } 14290 if (!brief) { 14291 if (memInfo.getZramTotalSizeKb() != 0) { 14292 if (!isCompact) { 14293 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14294 pw.print(" kB physical used for "); 14295 pw.print(memInfo.getSwapTotalSizeKb() 14296 - memInfo.getSwapFreeSizeKb()); 14297 pw.print(" kB in swap ("); 14298 pw.print(memInfo.getSwapTotalSizeKb()); 14299 pw.println(" kB total swap)"); 14300 } else { 14301 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14302 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14303 pw.println(memInfo.getSwapFreeSizeKb()); 14304 } 14305 } 14306 final int[] SINGLE_LONG_FORMAT = new int[] { 14307 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14308 }; 14309 long[] longOut = new long[1]; 14310 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14311 SINGLE_LONG_FORMAT, null, longOut, null); 14312 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14313 longOut[0] = 0; 14314 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14315 SINGLE_LONG_FORMAT, null, longOut, null); 14316 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14317 longOut[0] = 0; 14318 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14319 SINGLE_LONG_FORMAT, null, longOut, null); 14320 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14321 longOut[0] = 0; 14322 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14323 SINGLE_LONG_FORMAT, null, longOut, null); 14324 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14325 if (!isCompact) { 14326 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14327 pw.print(" KSM: "); pw.print(sharing); 14328 pw.print(" kB saved from shared "); 14329 pw.print(shared); pw.println(" kB"); 14330 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14331 pw.print(voltile); pw.println(" kB volatile"); 14332 } 14333 pw.print(" Tuning: "); 14334 pw.print(ActivityManager.staticGetMemoryClass()); 14335 pw.print(" (large "); 14336 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14337 pw.print("), oom "); 14338 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14339 pw.print(" kB"); 14340 pw.print(", restore limit "); 14341 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14342 pw.print(" kB"); 14343 if (ActivityManager.isLowRamDeviceStatic()) { 14344 pw.print(" (low-ram)"); 14345 } 14346 if (ActivityManager.isHighEndGfx()) { 14347 pw.print(" (high-end-gfx)"); 14348 } 14349 pw.println(); 14350 } else { 14351 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14352 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14353 pw.println(voltile); 14354 pw.print("tuning,"); 14355 pw.print(ActivityManager.staticGetMemoryClass()); 14356 pw.print(','); 14357 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14358 pw.print(','); 14359 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14360 if (ActivityManager.isLowRamDeviceStatic()) { 14361 pw.print(",low-ram"); 14362 } 14363 if (ActivityManager.isHighEndGfx()) { 14364 pw.print(",high-end-gfx"); 14365 } 14366 pw.println(); 14367 } 14368 } 14369 } 14370 } 14371 14372 /** 14373 * Searches array of arguments for the specified string 14374 * @param args array of argument strings 14375 * @param value value to search for 14376 * @return true if the value is contained in the array 14377 */ 14378 private static boolean scanArgs(String[] args, String value) { 14379 if (args != null) { 14380 for (String arg : args) { 14381 if (value.equals(arg)) { 14382 return true; 14383 } 14384 } 14385 } 14386 return false; 14387 } 14388 14389 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14390 ContentProviderRecord cpr, boolean always) { 14391 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14392 14393 if (!inLaunching || always) { 14394 synchronized (cpr) { 14395 cpr.launchingApp = null; 14396 cpr.notifyAll(); 14397 } 14398 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14399 String names[] = cpr.info.authority.split(";"); 14400 for (int j = 0; j < names.length; j++) { 14401 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14402 } 14403 } 14404 14405 for (int i=0; i<cpr.connections.size(); i++) { 14406 ContentProviderConnection conn = cpr.connections.get(i); 14407 if (conn.waiting) { 14408 // If this connection is waiting for the provider, then we don't 14409 // need to mess with its process unless we are always removing 14410 // or for some reason the provider is not currently launching. 14411 if (inLaunching && !always) { 14412 continue; 14413 } 14414 } 14415 ProcessRecord capp = conn.client; 14416 conn.dead = true; 14417 if (conn.stableCount > 0) { 14418 if (!capp.persistent && capp.thread != null 14419 && capp.pid != 0 14420 && capp.pid != MY_PID) { 14421 capp.kill("depends on provider " 14422 + cpr.name.flattenToShortString() 14423 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14424 } 14425 } else if (capp.thread != null && conn.provider.provider != null) { 14426 try { 14427 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14428 } catch (RemoteException e) { 14429 } 14430 // In the protocol here, we don't expect the client to correctly 14431 // clean up this connection, we'll just remove it. 14432 cpr.connections.remove(i); 14433 conn.client.conProviders.remove(conn); 14434 } 14435 } 14436 14437 if (inLaunching && always) { 14438 mLaunchingProviders.remove(cpr); 14439 } 14440 return inLaunching; 14441 } 14442 14443 /** 14444 * Main code for cleaning up a process when it has gone away. This is 14445 * called both as a result of the process dying, or directly when stopping 14446 * a process when running in single process mode. 14447 * 14448 * @return Returns true if the given process has been restarted, so the 14449 * app that was passed in must remain on the process lists. 14450 */ 14451 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14452 boolean restarting, boolean allowRestart, int index) { 14453 if (index >= 0) { 14454 removeLruProcessLocked(app); 14455 ProcessList.remove(app.pid); 14456 } 14457 14458 mProcessesToGc.remove(app); 14459 mPendingPssProcesses.remove(app); 14460 14461 // Dismiss any open dialogs. 14462 if (app.crashDialog != null && !app.forceCrashReport) { 14463 app.crashDialog.dismiss(); 14464 app.crashDialog = null; 14465 } 14466 if (app.anrDialog != null) { 14467 app.anrDialog.dismiss(); 14468 app.anrDialog = null; 14469 } 14470 if (app.waitDialog != null) { 14471 app.waitDialog.dismiss(); 14472 app.waitDialog = null; 14473 } 14474 14475 app.crashing = false; 14476 app.notResponding = false; 14477 14478 app.resetPackageList(mProcessStats); 14479 app.unlinkDeathRecipient(); 14480 app.makeInactive(mProcessStats); 14481 app.waitingToKill = null; 14482 app.forcingToForeground = null; 14483 updateProcessForegroundLocked(app, false, false); 14484 app.foregroundActivities = false; 14485 app.hasShownUi = false; 14486 app.treatLikeActivity = false; 14487 app.hasAboveClient = false; 14488 app.hasClientActivities = false; 14489 14490 mServices.killServicesLocked(app, allowRestart); 14491 14492 boolean restart = false; 14493 14494 // Remove published content providers. 14495 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14496 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14497 final boolean always = app.bad || !allowRestart; 14498 if (removeDyingProviderLocked(app, cpr, always) || always) { 14499 // We left the provider in the launching list, need to 14500 // restart it. 14501 restart = true; 14502 } 14503 14504 cpr.provider = null; 14505 cpr.proc = null; 14506 } 14507 app.pubProviders.clear(); 14508 14509 // Take care of any launching providers waiting for this process. 14510 if (checkAppInLaunchingProvidersLocked(app, false)) { 14511 restart = true; 14512 } 14513 14514 // Unregister from connected content providers. 14515 if (!app.conProviders.isEmpty()) { 14516 for (int i=0; i<app.conProviders.size(); i++) { 14517 ContentProviderConnection conn = app.conProviders.get(i); 14518 conn.provider.connections.remove(conn); 14519 } 14520 app.conProviders.clear(); 14521 } 14522 14523 // At this point there may be remaining entries in mLaunchingProviders 14524 // where we were the only one waiting, so they are no longer of use. 14525 // Look for these and clean up if found. 14526 // XXX Commented out for now. Trying to figure out a way to reproduce 14527 // the actual situation to identify what is actually going on. 14528 if (false) { 14529 for (int i=0; i<mLaunchingProviders.size(); i++) { 14530 ContentProviderRecord cpr = (ContentProviderRecord) 14531 mLaunchingProviders.get(i); 14532 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14533 synchronized (cpr) { 14534 cpr.launchingApp = null; 14535 cpr.notifyAll(); 14536 } 14537 } 14538 } 14539 } 14540 14541 skipCurrentReceiverLocked(app); 14542 14543 // Unregister any receivers. 14544 for (int i=app.receivers.size()-1; i>=0; i--) { 14545 removeReceiverLocked(app.receivers.valueAt(i)); 14546 } 14547 app.receivers.clear(); 14548 14549 // If the app is undergoing backup, tell the backup manager about it 14550 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14551 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14552 + mBackupTarget.appInfo + " died during backup"); 14553 try { 14554 IBackupManager bm = IBackupManager.Stub.asInterface( 14555 ServiceManager.getService(Context.BACKUP_SERVICE)); 14556 bm.agentDisconnected(app.info.packageName); 14557 } catch (RemoteException e) { 14558 // can't happen; backup manager is local 14559 } 14560 } 14561 14562 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14563 ProcessChangeItem item = mPendingProcessChanges.get(i); 14564 if (item.pid == app.pid) { 14565 mPendingProcessChanges.remove(i); 14566 mAvailProcessChanges.add(item); 14567 } 14568 } 14569 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14570 14571 // If the caller is restarting this app, then leave it in its 14572 // current lists and let the caller take care of it. 14573 if (restarting) { 14574 return false; 14575 } 14576 14577 if (!app.persistent || app.isolated) { 14578 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14579 "Removing non-persistent process during cleanup: " + app); 14580 mProcessNames.remove(app.processName, app.uid); 14581 mIsolatedProcesses.remove(app.uid); 14582 if (mHeavyWeightProcess == app) { 14583 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14584 mHeavyWeightProcess.userId, 0)); 14585 mHeavyWeightProcess = null; 14586 } 14587 } else if (!app.removed) { 14588 // This app is persistent, so we need to keep its record around. 14589 // If it is not already on the pending app list, add it there 14590 // and start a new process for it. 14591 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14592 mPersistentStartingProcesses.add(app); 14593 restart = true; 14594 } 14595 } 14596 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14597 "Clean-up removing on hold: " + app); 14598 mProcessesOnHold.remove(app); 14599 14600 if (app == mHomeProcess) { 14601 mHomeProcess = null; 14602 } 14603 if (app == mPreviousProcess) { 14604 mPreviousProcess = null; 14605 } 14606 14607 if (restart && !app.isolated) { 14608 // We have components that still need to be running in the 14609 // process, so re-launch it. 14610 if (index < 0) { 14611 ProcessList.remove(app.pid); 14612 } 14613 mProcessNames.put(app.processName, app.uid, app); 14614 startProcessLocked(app, "restart", app.processName); 14615 return true; 14616 } else if (app.pid > 0 && app.pid != MY_PID) { 14617 // Goodbye! 14618 boolean removed; 14619 synchronized (mPidsSelfLocked) { 14620 mPidsSelfLocked.remove(app.pid); 14621 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14622 } 14623 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14624 if (app.isolated) { 14625 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14626 } 14627 app.setPid(0); 14628 } 14629 return false; 14630 } 14631 14632 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14633 // Look through the content providers we are waiting to have launched, 14634 // and if any run in this process then either schedule a restart of 14635 // the process or kill the client waiting for it if this process has 14636 // gone bad. 14637 int NL = mLaunchingProviders.size(); 14638 boolean restart = false; 14639 for (int i=0; i<NL; i++) { 14640 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14641 if (cpr.launchingApp == app) { 14642 if (!alwaysBad && !app.bad) { 14643 restart = true; 14644 } else { 14645 removeDyingProviderLocked(app, cpr, true); 14646 // cpr should have been removed from mLaunchingProviders 14647 NL = mLaunchingProviders.size(); 14648 i--; 14649 } 14650 } 14651 } 14652 return restart; 14653 } 14654 14655 // ========================================================= 14656 // SERVICES 14657 // ========================================================= 14658 14659 @Override 14660 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14661 int flags) { 14662 enforceNotIsolatedCaller("getServices"); 14663 synchronized (this) { 14664 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14665 } 14666 } 14667 14668 @Override 14669 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14670 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14671 synchronized (this) { 14672 return mServices.getRunningServiceControlPanelLocked(name); 14673 } 14674 } 14675 14676 @Override 14677 public ComponentName startService(IApplicationThread caller, Intent service, 14678 String resolvedType, int userId) { 14679 enforceNotIsolatedCaller("startService"); 14680 // Refuse possible leaked file descriptors 14681 if (service != null && service.hasFileDescriptors() == true) { 14682 throw new IllegalArgumentException("File descriptors passed in Intent"); 14683 } 14684 14685 if (DEBUG_SERVICE) 14686 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14687 synchronized(this) { 14688 final int callingPid = Binder.getCallingPid(); 14689 final int callingUid = Binder.getCallingUid(); 14690 final long origId = Binder.clearCallingIdentity(); 14691 ComponentName res = mServices.startServiceLocked(caller, service, 14692 resolvedType, callingPid, callingUid, userId); 14693 Binder.restoreCallingIdentity(origId); 14694 return res; 14695 } 14696 } 14697 14698 ComponentName startServiceInPackage(int uid, 14699 Intent service, String resolvedType, int userId) { 14700 synchronized(this) { 14701 if (DEBUG_SERVICE) 14702 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14703 final long origId = Binder.clearCallingIdentity(); 14704 ComponentName res = mServices.startServiceLocked(null, service, 14705 resolvedType, -1, uid, userId); 14706 Binder.restoreCallingIdentity(origId); 14707 return res; 14708 } 14709 } 14710 14711 @Override 14712 public int stopService(IApplicationThread caller, Intent service, 14713 String resolvedType, int userId) { 14714 enforceNotIsolatedCaller("stopService"); 14715 // Refuse possible leaked file descriptors 14716 if (service != null && service.hasFileDescriptors() == true) { 14717 throw new IllegalArgumentException("File descriptors passed in Intent"); 14718 } 14719 14720 synchronized(this) { 14721 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14722 } 14723 } 14724 14725 @Override 14726 public IBinder peekService(Intent service, String resolvedType) { 14727 enforceNotIsolatedCaller("peekService"); 14728 // Refuse possible leaked file descriptors 14729 if (service != null && service.hasFileDescriptors() == true) { 14730 throw new IllegalArgumentException("File descriptors passed in Intent"); 14731 } 14732 synchronized(this) { 14733 return mServices.peekServiceLocked(service, resolvedType); 14734 } 14735 } 14736 14737 @Override 14738 public boolean stopServiceToken(ComponentName className, IBinder token, 14739 int startId) { 14740 synchronized(this) { 14741 return mServices.stopServiceTokenLocked(className, token, startId); 14742 } 14743 } 14744 14745 @Override 14746 public void setServiceForeground(ComponentName className, IBinder token, 14747 int id, Notification notification, boolean removeNotification) { 14748 synchronized(this) { 14749 mServices.setServiceForegroundLocked(className, token, id, notification, 14750 removeNotification); 14751 } 14752 } 14753 14754 @Override 14755 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14756 boolean requireFull, String name, String callerPackage) { 14757 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14758 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14759 } 14760 14761 int unsafeConvertIncomingUser(int userId) { 14762 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14763 ? mCurrentUserId : userId; 14764 } 14765 14766 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14767 int allowMode, String name, String callerPackage) { 14768 final int callingUserId = UserHandle.getUserId(callingUid); 14769 if (callingUserId == userId) { 14770 return userId; 14771 } 14772 14773 // Note that we may be accessing mCurrentUserId outside of a lock... 14774 // shouldn't be a big deal, if this is being called outside 14775 // of a locked context there is intrinsically a race with 14776 // the value the caller will receive and someone else changing it. 14777 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14778 // we will switch to the calling user if access to the current user fails. 14779 int targetUserId = unsafeConvertIncomingUser(userId); 14780 14781 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14782 final boolean allow; 14783 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14784 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14785 // If the caller has this permission, they always pass go. And collect $200. 14786 allow = true; 14787 } else if (allowMode == ALLOW_FULL_ONLY) { 14788 // We require full access, sucks to be you. 14789 allow = false; 14790 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14791 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14792 // If the caller does not have either permission, they are always doomed. 14793 allow = false; 14794 } else if (allowMode == ALLOW_NON_FULL) { 14795 // We are blanket allowing non-full access, you lucky caller! 14796 allow = true; 14797 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14798 // We may or may not allow this depending on whether the two users are 14799 // in the same profile. 14800 synchronized (mUserProfileGroupIdsSelfLocked) { 14801 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14802 UserInfo.NO_PROFILE_GROUP_ID); 14803 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14804 UserInfo.NO_PROFILE_GROUP_ID); 14805 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14806 && callingProfile == targetProfile; 14807 } 14808 } else { 14809 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14810 } 14811 if (!allow) { 14812 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14813 // In this case, they would like to just execute as their 14814 // owner user instead of failing. 14815 targetUserId = callingUserId; 14816 } else { 14817 StringBuilder builder = new StringBuilder(128); 14818 builder.append("Permission Denial: "); 14819 builder.append(name); 14820 if (callerPackage != null) { 14821 builder.append(" from "); 14822 builder.append(callerPackage); 14823 } 14824 builder.append(" asks to run as user "); 14825 builder.append(userId); 14826 builder.append(" but is calling from user "); 14827 builder.append(UserHandle.getUserId(callingUid)); 14828 builder.append("; this requires "); 14829 builder.append(INTERACT_ACROSS_USERS_FULL); 14830 if (allowMode != ALLOW_FULL_ONLY) { 14831 builder.append(" or "); 14832 builder.append(INTERACT_ACROSS_USERS); 14833 } 14834 String msg = builder.toString(); 14835 Slog.w(TAG, msg); 14836 throw new SecurityException(msg); 14837 } 14838 } 14839 } 14840 if (!allowAll && targetUserId < 0) { 14841 throw new IllegalArgumentException( 14842 "Call does not support special user #" + targetUserId); 14843 } 14844 // Check shell permission 14845 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14846 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14847 targetUserId)) { 14848 throw new SecurityException("Shell does not have permission to access user " 14849 + targetUserId + "\n " + Debug.getCallers(3)); 14850 } 14851 } 14852 return targetUserId; 14853 } 14854 14855 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14856 String className, int flags) { 14857 boolean result = false; 14858 // For apps that don't have pre-defined UIDs, check for permission 14859 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14860 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14861 if (ActivityManager.checkUidPermission( 14862 INTERACT_ACROSS_USERS, 14863 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14864 ComponentName comp = new ComponentName(aInfo.packageName, className); 14865 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14866 + " requests FLAG_SINGLE_USER, but app does not hold " 14867 + INTERACT_ACROSS_USERS; 14868 Slog.w(TAG, msg); 14869 throw new SecurityException(msg); 14870 } 14871 // Permission passed 14872 result = true; 14873 } 14874 } else if ("system".equals(componentProcessName)) { 14875 result = true; 14876 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14877 // Phone app and persistent apps are allowed to export singleuser providers. 14878 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14879 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14880 } 14881 if (DEBUG_MU) { 14882 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14883 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14884 } 14885 return result; 14886 } 14887 14888 /** 14889 * Checks to see if the caller is in the same app as the singleton 14890 * component, or the component is in a special app. It allows special apps 14891 * to export singleton components but prevents exporting singleton 14892 * components for regular apps. 14893 */ 14894 boolean isValidSingletonCall(int callingUid, int componentUid) { 14895 int componentAppId = UserHandle.getAppId(componentUid); 14896 return UserHandle.isSameApp(callingUid, componentUid) 14897 || componentAppId == Process.SYSTEM_UID 14898 || componentAppId == Process.PHONE_UID 14899 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14900 == PackageManager.PERMISSION_GRANTED; 14901 } 14902 14903 public int bindService(IApplicationThread caller, IBinder token, 14904 Intent service, String resolvedType, 14905 IServiceConnection connection, int flags, int userId) { 14906 enforceNotIsolatedCaller("bindService"); 14907 14908 // Refuse possible leaked file descriptors 14909 if (service != null && service.hasFileDescriptors() == true) { 14910 throw new IllegalArgumentException("File descriptors passed in Intent"); 14911 } 14912 14913 synchronized(this) { 14914 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14915 connection, flags, userId); 14916 } 14917 } 14918 14919 public boolean unbindService(IServiceConnection connection) { 14920 synchronized (this) { 14921 return mServices.unbindServiceLocked(connection); 14922 } 14923 } 14924 14925 public void publishService(IBinder token, Intent intent, IBinder service) { 14926 // Refuse possible leaked file descriptors 14927 if (intent != null && intent.hasFileDescriptors() == true) { 14928 throw new IllegalArgumentException("File descriptors passed in Intent"); 14929 } 14930 14931 synchronized(this) { 14932 if (!(token instanceof ServiceRecord)) { 14933 throw new IllegalArgumentException("Invalid service token"); 14934 } 14935 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14936 } 14937 } 14938 14939 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14940 // Refuse possible leaked file descriptors 14941 if (intent != null && intent.hasFileDescriptors() == true) { 14942 throw new IllegalArgumentException("File descriptors passed in Intent"); 14943 } 14944 14945 synchronized(this) { 14946 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14947 } 14948 } 14949 14950 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14951 synchronized(this) { 14952 if (!(token instanceof ServiceRecord)) { 14953 throw new IllegalArgumentException("Invalid service token"); 14954 } 14955 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14956 } 14957 } 14958 14959 // ========================================================= 14960 // BACKUP AND RESTORE 14961 // ========================================================= 14962 14963 // Cause the target app to be launched if necessary and its backup agent 14964 // instantiated. The backup agent will invoke backupAgentCreated() on the 14965 // activity manager to announce its creation. 14966 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14967 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14968 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14969 14970 synchronized(this) { 14971 // !!! TODO: currently no check here that we're already bound 14972 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14973 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14974 synchronized (stats) { 14975 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14976 } 14977 14978 // Backup agent is now in use, its package can't be stopped. 14979 try { 14980 AppGlobals.getPackageManager().setPackageStoppedState( 14981 app.packageName, false, UserHandle.getUserId(app.uid)); 14982 } catch (RemoteException e) { 14983 } catch (IllegalArgumentException e) { 14984 Slog.w(TAG, "Failed trying to unstop package " 14985 + app.packageName + ": " + e); 14986 } 14987 14988 BackupRecord r = new BackupRecord(ss, app, backupMode); 14989 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14990 ? new ComponentName(app.packageName, app.backupAgentName) 14991 : new ComponentName("android", "FullBackupAgent"); 14992 // startProcessLocked() returns existing proc's record if it's already running 14993 ProcessRecord proc = startProcessLocked(app.processName, app, 14994 false, 0, "backup", hostingName, false, false, false); 14995 if (proc == null) { 14996 Slog.e(TAG, "Unable to start backup agent process " + r); 14997 return false; 14998 } 14999 15000 r.app = proc; 15001 mBackupTarget = r; 15002 mBackupAppName = app.packageName; 15003 15004 // Try not to kill the process during backup 15005 updateOomAdjLocked(proc); 15006 15007 // If the process is already attached, schedule the creation of the backup agent now. 15008 // If it is not yet live, this will be done when it attaches to the framework. 15009 if (proc.thread != null) { 15010 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15011 try { 15012 proc.thread.scheduleCreateBackupAgent(app, 15013 compatibilityInfoForPackageLocked(app), backupMode); 15014 } catch (RemoteException e) { 15015 // Will time out on the backup manager side 15016 } 15017 } else { 15018 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15019 } 15020 // Invariants: at this point, the target app process exists and the application 15021 // is either already running or in the process of coming up. mBackupTarget and 15022 // mBackupAppName describe the app, so that when it binds back to the AM we 15023 // know that it's scheduled for a backup-agent operation. 15024 } 15025 15026 return true; 15027 } 15028 15029 @Override 15030 public void clearPendingBackup() { 15031 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15032 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15033 15034 synchronized (this) { 15035 mBackupTarget = null; 15036 mBackupAppName = null; 15037 } 15038 } 15039 15040 // A backup agent has just come up 15041 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15042 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15043 + " = " + agent); 15044 15045 synchronized(this) { 15046 if (!agentPackageName.equals(mBackupAppName)) { 15047 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15048 return; 15049 } 15050 } 15051 15052 long oldIdent = Binder.clearCallingIdentity(); 15053 try { 15054 IBackupManager bm = IBackupManager.Stub.asInterface( 15055 ServiceManager.getService(Context.BACKUP_SERVICE)); 15056 bm.agentConnected(agentPackageName, agent); 15057 } catch (RemoteException e) { 15058 // can't happen; the backup manager service is local 15059 } catch (Exception e) { 15060 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15061 e.printStackTrace(); 15062 } finally { 15063 Binder.restoreCallingIdentity(oldIdent); 15064 } 15065 } 15066 15067 // done with this agent 15068 public void unbindBackupAgent(ApplicationInfo appInfo) { 15069 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15070 if (appInfo == null) { 15071 Slog.w(TAG, "unbind backup agent for null app"); 15072 return; 15073 } 15074 15075 synchronized(this) { 15076 try { 15077 if (mBackupAppName == null) { 15078 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15079 return; 15080 } 15081 15082 if (!mBackupAppName.equals(appInfo.packageName)) { 15083 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15084 return; 15085 } 15086 15087 // Not backing this app up any more; reset its OOM adjustment 15088 final ProcessRecord proc = mBackupTarget.app; 15089 updateOomAdjLocked(proc); 15090 15091 // If the app crashed during backup, 'thread' will be null here 15092 if (proc.thread != null) { 15093 try { 15094 proc.thread.scheduleDestroyBackupAgent(appInfo, 15095 compatibilityInfoForPackageLocked(appInfo)); 15096 } catch (Exception e) { 15097 Slog.e(TAG, "Exception when unbinding backup agent:"); 15098 e.printStackTrace(); 15099 } 15100 } 15101 } finally { 15102 mBackupTarget = null; 15103 mBackupAppName = null; 15104 } 15105 } 15106 } 15107 // ========================================================= 15108 // BROADCASTS 15109 // ========================================================= 15110 15111 private final List getStickiesLocked(String action, IntentFilter filter, 15112 List cur, int userId) { 15113 final ContentResolver resolver = mContext.getContentResolver(); 15114 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15115 if (stickies == null) { 15116 return cur; 15117 } 15118 final ArrayList<Intent> list = stickies.get(action); 15119 if (list == null) { 15120 return cur; 15121 } 15122 int N = list.size(); 15123 for (int i=0; i<N; i++) { 15124 Intent intent = list.get(i); 15125 if (filter.match(resolver, intent, true, TAG) >= 0) { 15126 if (cur == null) { 15127 cur = new ArrayList<Intent>(); 15128 } 15129 cur.add(intent); 15130 } 15131 } 15132 return cur; 15133 } 15134 15135 boolean isPendingBroadcastProcessLocked(int pid) { 15136 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15137 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15138 } 15139 15140 void skipPendingBroadcastLocked(int pid) { 15141 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15142 for (BroadcastQueue queue : mBroadcastQueues) { 15143 queue.skipPendingBroadcastLocked(pid); 15144 } 15145 } 15146 15147 // The app just attached; send any pending broadcasts that it should receive 15148 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15149 boolean didSomething = false; 15150 for (BroadcastQueue queue : mBroadcastQueues) { 15151 didSomething |= queue.sendPendingBroadcastsLocked(app); 15152 } 15153 return didSomething; 15154 } 15155 15156 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15157 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15158 enforceNotIsolatedCaller("registerReceiver"); 15159 int callingUid; 15160 int callingPid; 15161 synchronized(this) { 15162 ProcessRecord callerApp = null; 15163 if (caller != null) { 15164 callerApp = getRecordForAppLocked(caller); 15165 if (callerApp == null) { 15166 throw new SecurityException( 15167 "Unable to find app for caller " + caller 15168 + " (pid=" + Binder.getCallingPid() 15169 + ") when registering receiver " + receiver); 15170 } 15171 if (callerApp.info.uid != Process.SYSTEM_UID && 15172 !callerApp.pkgList.containsKey(callerPackage) && 15173 !"android".equals(callerPackage)) { 15174 throw new SecurityException("Given caller package " + callerPackage 15175 + " is not running in process " + callerApp); 15176 } 15177 callingUid = callerApp.info.uid; 15178 callingPid = callerApp.pid; 15179 } else { 15180 callerPackage = null; 15181 callingUid = Binder.getCallingUid(); 15182 callingPid = Binder.getCallingPid(); 15183 } 15184 15185 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15186 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15187 15188 List allSticky = null; 15189 15190 // Look for any matching sticky broadcasts... 15191 Iterator actions = filter.actionsIterator(); 15192 if (actions != null) { 15193 while (actions.hasNext()) { 15194 String action = (String)actions.next(); 15195 allSticky = getStickiesLocked(action, filter, allSticky, 15196 UserHandle.USER_ALL); 15197 allSticky = getStickiesLocked(action, filter, allSticky, 15198 UserHandle.getUserId(callingUid)); 15199 } 15200 } else { 15201 allSticky = getStickiesLocked(null, filter, allSticky, 15202 UserHandle.USER_ALL); 15203 allSticky = getStickiesLocked(null, filter, allSticky, 15204 UserHandle.getUserId(callingUid)); 15205 } 15206 15207 // The first sticky in the list is returned directly back to 15208 // the client. 15209 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15210 15211 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15212 + ": " + sticky); 15213 15214 if (receiver == null) { 15215 return sticky; 15216 } 15217 15218 ReceiverList rl 15219 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15220 if (rl == null) { 15221 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15222 userId, receiver); 15223 if (rl.app != null) { 15224 rl.app.receivers.add(rl); 15225 } else { 15226 try { 15227 receiver.asBinder().linkToDeath(rl, 0); 15228 } catch (RemoteException e) { 15229 return sticky; 15230 } 15231 rl.linkedToDeath = true; 15232 } 15233 mRegisteredReceivers.put(receiver.asBinder(), rl); 15234 } else if (rl.uid != callingUid) { 15235 throw new IllegalArgumentException( 15236 "Receiver requested to register for uid " + callingUid 15237 + " was previously registered for uid " + rl.uid); 15238 } else if (rl.pid != callingPid) { 15239 throw new IllegalArgumentException( 15240 "Receiver requested to register for pid " + callingPid 15241 + " was previously registered for pid " + rl.pid); 15242 } else if (rl.userId != userId) { 15243 throw new IllegalArgumentException( 15244 "Receiver requested to register for user " + userId 15245 + " was previously registered for user " + rl.userId); 15246 } 15247 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15248 permission, callingUid, userId); 15249 rl.add(bf); 15250 if (!bf.debugCheck()) { 15251 Slog.w(TAG, "==> For Dynamic broadast"); 15252 } 15253 mReceiverResolver.addFilter(bf); 15254 15255 // Enqueue broadcasts for all existing stickies that match 15256 // this filter. 15257 if (allSticky != null) { 15258 ArrayList receivers = new ArrayList(); 15259 receivers.add(bf); 15260 15261 int N = allSticky.size(); 15262 for (int i=0; i<N; i++) { 15263 Intent intent = (Intent)allSticky.get(i); 15264 BroadcastQueue queue = broadcastQueueForIntent(intent); 15265 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15266 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15267 null, null, false, true, true, -1); 15268 queue.enqueueParallelBroadcastLocked(r); 15269 queue.scheduleBroadcastsLocked(); 15270 } 15271 } 15272 15273 return sticky; 15274 } 15275 } 15276 15277 public void unregisterReceiver(IIntentReceiver receiver) { 15278 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15279 15280 final long origId = Binder.clearCallingIdentity(); 15281 try { 15282 boolean doTrim = false; 15283 15284 synchronized(this) { 15285 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15286 if (rl != null) { 15287 if (rl.curBroadcast != null) { 15288 BroadcastRecord r = rl.curBroadcast; 15289 final boolean doNext = finishReceiverLocked( 15290 receiver.asBinder(), r.resultCode, r.resultData, 15291 r.resultExtras, r.resultAbort); 15292 if (doNext) { 15293 doTrim = true; 15294 r.queue.processNextBroadcast(false); 15295 } 15296 } 15297 15298 if (rl.app != null) { 15299 rl.app.receivers.remove(rl); 15300 } 15301 removeReceiverLocked(rl); 15302 if (rl.linkedToDeath) { 15303 rl.linkedToDeath = false; 15304 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15305 } 15306 } 15307 } 15308 15309 // If we actually concluded any broadcasts, we might now be able 15310 // to trim the recipients' apps from our working set 15311 if (doTrim) { 15312 trimApplications(); 15313 return; 15314 } 15315 15316 } finally { 15317 Binder.restoreCallingIdentity(origId); 15318 } 15319 } 15320 15321 void removeReceiverLocked(ReceiverList rl) { 15322 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15323 int N = rl.size(); 15324 for (int i=0; i<N; i++) { 15325 mReceiverResolver.removeFilter(rl.get(i)); 15326 } 15327 } 15328 15329 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15330 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15331 ProcessRecord r = mLruProcesses.get(i); 15332 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15333 try { 15334 r.thread.dispatchPackageBroadcast(cmd, packages); 15335 } catch (RemoteException ex) { 15336 } 15337 } 15338 } 15339 } 15340 15341 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15342 int callingUid, int[] users) { 15343 List<ResolveInfo> receivers = null; 15344 try { 15345 HashSet<ComponentName> singleUserReceivers = null; 15346 boolean scannedFirstReceivers = false; 15347 for (int user : users) { 15348 // Skip users that have Shell restrictions 15349 if (callingUid == Process.SHELL_UID 15350 && getUserManagerLocked().hasUserRestriction( 15351 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15352 continue; 15353 } 15354 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15355 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15356 if (user != 0 && newReceivers != null) { 15357 // If this is not the primary user, we need to check for 15358 // any receivers that should be filtered out. 15359 for (int i=0; i<newReceivers.size(); i++) { 15360 ResolveInfo ri = newReceivers.get(i); 15361 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15362 newReceivers.remove(i); 15363 i--; 15364 } 15365 } 15366 } 15367 if (newReceivers != null && newReceivers.size() == 0) { 15368 newReceivers = null; 15369 } 15370 if (receivers == null) { 15371 receivers = newReceivers; 15372 } else if (newReceivers != null) { 15373 // We need to concatenate the additional receivers 15374 // found with what we have do far. This would be easy, 15375 // but we also need to de-dup any receivers that are 15376 // singleUser. 15377 if (!scannedFirstReceivers) { 15378 // Collect any single user receivers we had already retrieved. 15379 scannedFirstReceivers = true; 15380 for (int i=0; i<receivers.size(); i++) { 15381 ResolveInfo ri = receivers.get(i); 15382 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15383 ComponentName cn = new ComponentName( 15384 ri.activityInfo.packageName, ri.activityInfo.name); 15385 if (singleUserReceivers == null) { 15386 singleUserReceivers = new HashSet<ComponentName>(); 15387 } 15388 singleUserReceivers.add(cn); 15389 } 15390 } 15391 } 15392 // Add the new results to the existing results, tracking 15393 // and de-dupping single user receivers. 15394 for (int i=0; i<newReceivers.size(); i++) { 15395 ResolveInfo ri = newReceivers.get(i); 15396 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15397 ComponentName cn = new ComponentName( 15398 ri.activityInfo.packageName, ri.activityInfo.name); 15399 if (singleUserReceivers == null) { 15400 singleUserReceivers = new HashSet<ComponentName>(); 15401 } 15402 if (!singleUserReceivers.contains(cn)) { 15403 singleUserReceivers.add(cn); 15404 receivers.add(ri); 15405 } 15406 } else { 15407 receivers.add(ri); 15408 } 15409 } 15410 } 15411 } 15412 } catch (RemoteException ex) { 15413 // pm is in same process, this will never happen. 15414 } 15415 return receivers; 15416 } 15417 15418 private final int broadcastIntentLocked(ProcessRecord callerApp, 15419 String callerPackage, Intent intent, String resolvedType, 15420 IIntentReceiver resultTo, int resultCode, String resultData, 15421 Bundle map, String requiredPermission, int appOp, 15422 boolean ordered, boolean sticky, int callingPid, int callingUid, 15423 int userId) { 15424 intent = new Intent(intent); 15425 15426 // By default broadcasts do not go to stopped apps. 15427 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15428 15429 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15430 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15431 + " ordered=" + ordered + " userid=" + userId); 15432 if ((resultTo != null) && !ordered) { 15433 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15434 } 15435 15436 userId = handleIncomingUser(callingPid, callingUid, userId, 15437 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15438 15439 // Make sure that the user who is receiving this broadcast is started. 15440 // If not, we will just skip it. 15441 15442 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15443 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15444 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15445 Slog.w(TAG, "Skipping broadcast of " + intent 15446 + ": user " + userId + " is stopped"); 15447 return ActivityManager.BROADCAST_SUCCESS; 15448 } 15449 } 15450 15451 /* 15452 * Prevent non-system code (defined here to be non-persistent 15453 * processes) from sending protected broadcasts. 15454 */ 15455 int callingAppId = UserHandle.getAppId(callingUid); 15456 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15457 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15458 || callingAppId == Process.NFC_UID || callingUid == 0) { 15459 // Always okay. 15460 } else if (callerApp == null || !callerApp.persistent) { 15461 try { 15462 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15463 intent.getAction())) { 15464 String msg = "Permission Denial: not allowed to send broadcast " 15465 + intent.getAction() + " from pid=" 15466 + callingPid + ", uid=" + callingUid; 15467 Slog.w(TAG, msg); 15468 throw new SecurityException(msg); 15469 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15470 // Special case for compatibility: we don't want apps to send this, 15471 // but historically it has not been protected and apps may be using it 15472 // to poke their own app widget. So, instead of making it protected, 15473 // just limit it to the caller. 15474 if (callerApp == null) { 15475 String msg = "Permission Denial: not allowed to send broadcast " 15476 + intent.getAction() + " from unknown caller."; 15477 Slog.w(TAG, msg); 15478 throw new SecurityException(msg); 15479 } else if (intent.getComponent() != null) { 15480 // They are good enough to send to an explicit component... verify 15481 // it is being sent to the calling app. 15482 if (!intent.getComponent().getPackageName().equals( 15483 callerApp.info.packageName)) { 15484 String msg = "Permission Denial: not allowed to send broadcast " 15485 + intent.getAction() + " to " 15486 + intent.getComponent().getPackageName() + " from " 15487 + callerApp.info.packageName; 15488 Slog.w(TAG, msg); 15489 throw new SecurityException(msg); 15490 } 15491 } else { 15492 // Limit broadcast to their own package. 15493 intent.setPackage(callerApp.info.packageName); 15494 } 15495 } 15496 } catch (RemoteException e) { 15497 Slog.w(TAG, "Remote exception", e); 15498 return ActivityManager.BROADCAST_SUCCESS; 15499 } 15500 } 15501 15502 // Handle special intents: if this broadcast is from the package 15503 // manager about a package being removed, we need to remove all of 15504 // its activities from the history stack. 15505 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15506 intent.getAction()); 15507 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15508 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15509 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15510 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15511 || uidRemoved) { 15512 if (checkComponentPermission( 15513 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15514 callingPid, callingUid, -1, true) 15515 == PackageManager.PERMISSION_GRANTED) { 15516 if (uidRemoved) { 15517 final Bundle intentExtras = intent.getExtras(); 15518 final int uid = intentExtras != null 15519 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15520 if (uid >= 0) { 15521 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15522 synchronized (bs) { 15523 bs.removeUidStatsLocked(uid); 15524 } 15525 mAppOpsService.uidRemoved(uid); 15526 } 15527 } else { 15528 // If resources are unavailable just force stop all 15529 // those packages and flush the attribute cache as well. 15530 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15531 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15532 if (list != null && (list.length > 0)) { 15533 for (String pkg : list) { 15534 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15535 "storage unmount"); 15536 } 15537 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15538 sendPackageBroadcastLocked( 15539 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15540 } 15541 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15542 intent.getAction())) { 15543 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15544 } else { 15545 Uri data = intent.getData(); 15546 String ssp; 15547 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15548 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15549 intent.getAction()); 15550 boolean fullUninstall = removed && 15551 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15552 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15553 forceStopPackageLocked(ssp, UserHandle.getAppId( 15554 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15555 false, fullUninstall, userId, 15556 removed ? "pkg removed" : "pkg changed"); 15557 } 15558 if (removed) { 15559 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15560 new String[] {ssp}, userId); 15561 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15562 mAppOpsService.packageRemoved( 15563 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15564 15565 // Remove all permissions granted from/to this package 15566 removeUriPermissionsForPackageLocked(ssp, userId, true); 15567 } 15568 } 15569 } 15570 } 15571 } 15572 } else { 15573 String msg = "Permission Denial: " + intent.getAction() 15574 + " broadcast from " + callerPackage + " (pid=" + callingPid 15575 + ", uid=" + callingUid + ")" 15576 + " requires " 15577 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15578 Slog.w(TAG, msg); 15579 throw new SecurityException(msg); 15580 } 15581 15582 // Special case for adding a package: by default turn on compatibility 15583 // mode. 15584 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15585 Uri data = intent.getData(); 15586 String ssp; 15587 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15588 mCompatModePackages.handlePackageAddedLocked(ssp, 15589 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15590 } 15591 } 15592 15593 /* 15594 * If this is the time zone changed action, queue up a message that will reset the timezone 15595 * of all currently running processes. This message will get queued up before the broadcast 15596 * happens. 15597 */ 15598 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15599 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15600 } 15601 15602 /* 15603 * If the user set the time, let all running processes know. 15604 */ 15605 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15606 final int is24Hour = intent.getBooleanExtra( 15607 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15608 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15609 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15610 synchronized (stats) { 15611 stats.noteCurrentTimeChangedLocked(); 15612 } 15613 } 15614 15615 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15616 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15617 } 15618 15619 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15620 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15621 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15622 } 15623 15624 // Add to the sticky list if requested. 15625 if (sticky) { 15626 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15627 callingPid, callingUid) 15628 != PackageManager.PERMISSION_GRANTED) { 15629 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15630 + callingPid + ", uid=" + callingUid 15631 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15632 Slog.w(TAG, msg); 15633 throw new SecurityException(msg); 15634 } 15635 if (requiredPermission != null) { 15636 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15637 + " and enforce permission " + requiredPermission); 15638 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15639 } 15640 if (intent.getComponent() != null) { 15641 throw new SecurityException( 15642 "Sticky broadcasts can't target a specific component"); 15643 } 15644 // We use userId directly here, since the "all" target is maintained 15645 // as a separate set of sticky broadcasts. 15646 if (userId != UserHandle.USER_ALL) { 15647 // But first, if this is not a broadcast to all users, then 15648 // make sure it doesn't conflict with an existing broadcast to 15649 // all users. 15650 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15651 UserHandle.USER_ALL); 15652 if (stickies != null) { 15653 ArrayList<Intent> list = stickies.get(intent.getAction()); 15654 if (list != null) { 15655 int N = list.size(); 15656 int i; 15657 for (i=0; i<N; i++) { 15658 if (intent.filterEquals(list.get(i))) { 15659 throw new IllegalArgumentException( 15660 "Sticky broadcast " + intent + " for user " 15661 + userId + " conflicts with existing global broadcast"); 15662 } 15663 } 15664 } 15665 } 15666 } 15667 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15668 if (stickies == null) { 15669 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15670 mStickyBroadcasts.put(userId, stickies); 15671 } 15672 ArrayList<Intent> list = stickies.get(intent.getAction()); 15673 if (list == null) { 15674 list = new ArrayList<Intent>(); 15675 stickies.put(intent.getAction(), list); 15676 } 15677 int N = list.size(); 15678 int i; 15679 for (i=0; i<N; i++) { 15680 if (intent.filterEquals(list.get(i))) { 15681 // This sticky already exists, replace it. 15682 list.set(i, new Intent(intent)); 15683 break; 15684 } 15685 } 15686 if (i >= N) { 15687 list.add(new Intent(intent)); 15688 } 15689 } 15690 15691 int[] users; 15692 if (userId == UserHandle.USER_ALL) { 15693 // Caller wants broadcast to go to all started users. 15694 users = mStartedUserArray; 15695 } else { 15696 // Caller wants broadcast to go to one specific user. 15697 users = new int[] {userId}; 15698 } 15699 15700 // Figure out who all will receive this broadcast. 15701 List receivers = null; 15702 List<BroadcastFilter> registeredReceivers = null; 15703 // Need to resolve the intent to interested receivers... 15704 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15705 == 0) { 15706 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15707 } 15708 if (intent.getComponent() == null) { 15709 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15710 // Query one target user at a time, excluding shell-restricted users 15711 UserManagerService ums = getUserManagerLocked(); 15712 for (int i = 0; i < users.length; i++) { 15713 if (ums.hasUserRestriction( 15714 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15715 continue; 15716 } 15717 List<BroadcastFilter> registeredReceiversForUser = 15718 mReceiverResolver.queryIntent(intent, 15719 resolvedType, false, users[i]); 15720 if (registeredReceivers == null) { 15721 registeredReceivers = registeredReceiversForUser; 15722 } else if (registeredReceiversForUser != null) { 15723 registeredReceivers.addAll(registeredReceiversForUser); 15724 } 15725 } 15726 } else { 15727 registeredReceivers = mReceiverResolver.queryIntent(intent, 15728 resolvedType, false, userId); 15729 } 15730 } 15731 15732 final boolean replacePending = 15733 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15734 15735 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15736 + " replacePending=" + replacePending); 15737 15738 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15739 if (!ordered && NR > 0) { 15740 // If we are not serializing this broadcast, then send the 15741 // registered receivers separately so they don't wait for the 15742 // components to be launched. 15743 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15744 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15745 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15746 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15747 ordered, sticky, false, userId); 15748 if (DEBUG_BROADCAST) Slog.v( 15749 TAG, "Enqueueing parallel broadcast " + r); 15750 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15751 if (!replaced) { 15752 queue.enqueueParallelBroadcastLocked(r); 15753 queue.scheduleBroadcastsLocked(); 15754 } 15755 registeredReceivers = null; 15756 NR = 0; 15757 } 15758 15759 // Merge into one list. 15760 int ir = 0; 15761 if (receivers != null) { 15762 // A special case for PACKAGE_ADDED: do not allow the package 15763 // being added to see this broadcast. This prevents them from 15764 // using this as a back door to get run as soon as they are 15765 // installed. Maybe in the future we want to have a special install 15766 // broadcast or such for apps, but we'd like to deliberately make 15767 // this decision. 15768 String skipPackages[] = null; 15769 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15770 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15771 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15772 Uri data = intent.getData(); 15773 if (data != null) { 15774 String pkgName = data.getSchemeSpecificPart(); 15775 if (pkgName != null) { 15776 skipPackages = new String[] { pkgName }; 15777 } 15778 } 15779 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15780 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15781 } 15782 if (skipPackages != null && (skipPackages.length > 0)) { 15783 for (String skipPackage : skipPackages) { 15784 if (skipPackage != null) { 15785 int NT = receivers.size(); 15786 for (int it=0; it<NT; it++) { 15787 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15788 if (curt.activityInfo.packageName.equals(skipPackage)) { 15789 receivers.remove(it); 15790 it--; 15791 NT--; 15792 } 15793 } 15794 } 15795 } 15796 } 15797 15798 int NT = receivers != null ? receivers.size() : 0; 15799 int it = 0; 15800 ResolveInfo curt = null; 15801 BroadcastFilter curr = null; 15802 while (it < NT && ir < NR) { 15803 if (curt == null) { 15804 curt = (ResolveInfo)receivers.get(it); 15805 } 15806 if (curr == null) { 15807 curr = registeredReceivers.get(ir); 15808 } 15809 if (curr.getPriority() >= curt.priority) { 15810 // Insert this broadcast record into the final list. 15811 receivers.add(it, curr); 15812 ir++; 15813 curr = null; 15814 it++; 15815 NT++; 15816 } else { 15817 // Skip to the next ResolveInfo in the final list. 15818 it++; 15819 curt = null; 15820 } 15821 } 15822 } 15823 while (ir < NR) { 15824 if (receivers == null) { 15825 receivers = new ArrayList(); 15826 } 15827 receivers.add(registeredReceivers.get(ir)); 15828 ir++; 15829 } 15830 15831 if ((receivers != null && receivers.size() > 0) 15832 || resultTo != null) { 15833 BroadcastQueue queue = broadcastQueueForIntent(intent); 15834 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15835 callerPackage, callingPid, callingUid, resolvedType, 15836 requiredPermission, appOp, receivers, resultTo, resultCode, 15837 resultData, map, ordered, sticky, false, userId); 15838 if (DEBUG_BROADCAST) Slog.v( 15839 TAG, "Enqueueing ordered broadcast " + r 15840 + ": prev had " + queue.mOrderedBroadcasts.size()); 15841 if (DEBUG_BROADCAST) { 15842 int seq = r.intent.getIntExtra("seq", -1); 15843 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15844 } 15845 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15846 if (!replaced) { 15847 queue.enqueueOrderedBroadcastLocked(r); 15848 queue.scheduleBroadcastsLocked(); 15849 } 15850 } 15851 15852 return ActivityManager.BROADCAST_SUCCESS; 15853 } 15854 15855 final Intent verifyBroadcastLocked(Intent intent) { 15856 // Refuse possible leaked file descriptors 15857 if (intent != null && intent.hasFileDescriptors() == true) { 15858 throw new IllegalArgumentException("File descriptors passed in Intent"); 15859 } 15860 15861 int flags = intent.getFlags(); 15862 15863 if (!mProcessesReady) { 15864 // if the caller really truly claims to know what they're doing, go 15865 // ahead and allow the broadcast without launching any receivers 15866 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15867 intent = new Intent(intent); 15868 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15869 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15870 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15871 + " before boot completion"); 15872 throw new IllegalStateException("Cannot broadcast before boot completed"); 15873 } 15874 } 15875 15876 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15877 throw new IllegalArgumentException( 15878 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15879 } 15880 15881 return intent; 15882 } 15883 15884 public final int broadcastIntent(IApplicationThread caller, 15885 Intent intent, String resolvedType, IIntentReceiver resultTo, 15886 int resultCode, String resultData, Bundle map, 15887 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15888 enforceNotIsolatedCaller("broadcastIntent"); 15889 synchronized(this) { 15890 intent = verifyBroadcastLocked(intent); 15891 15892 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15893 final int callingPid = Binder.getCallingPid(); 15894 final int callingUid = Binder.getCallingUid(); 15895 final long origId = Binder.clearCallingIdentity(); 15896 int res = broadcastIntentLocked(callerApp, 15897 callerApp != null ? callerApp.info.packageName : null, 15898 intent, resolvedType, resultTo, 15899 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15900 callingPid, callingUid, userId); 15901 Binder.restoreCallingIdentity(origId); 15902 return res; 15903 } 15904 } 15905 15906 int broadcastIntentInPackage(String packageName, int uid, 15907 Intent intent, String resolvedType, IIntentReceiver resultTo, 15908 int resultCode, String resultData, Bundle map, 15909 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15910 synchronized(this) { 15911 intent = verifyBroadcastLocked(intent); 15912 15913 final long origId = Binder.clearCallingIdentity(); 15914 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15915 resultTo, resultCode, resultData, map, requiredPermission, 15916 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15917 Binder.restoreCallingIdentity(origId); 15918 return res; 15919 } 15920 } 15921 15922 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15923 // Refuse possible leaked file descriptors 15924 if (intent != null && intent.hasFileDescriptors() == true) { 15925 throw new IllegalArgumentException("File descriptors passed in Intent"); 15926 } 15927 15928 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15929 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15930 15931 synchronized(this) { 15932 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15933 != PackageManager.PERMISSION_GRANTED) { 15934 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15935 + Binder.getCallingPid() 15936 + ", uid=" + Binder.getCallingUid() 15937 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15938 Slog.w(TAG, msg); 15939 throw new SecurityException(msg); 15940 } 15941 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15942 if (stickies != null) { 15943 ArrayList<Intent> list = stickies.get(intent.getAction()); 15944 if (list != null) { 15945 int N = list.size(); 15946 int i; 15947 for (i=0; i<N; i++) { 15948 if (intent.filterEquals(list.get(i))) { 15949 list.remove(i); 15950 break; 15951 } 15952 } 15953 if (list.size() <= 0) { 15954 stickies.remove(intent.getAction()); 15955 } 15956 } 15957 if (stickies.size() <= 0) { 15958 mStickyBroadcasts.remove(userId); 15959 } 15960 } 15961 } 15962 } 15963 15964 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15965 String resultData, Bundle resultExtras, boolean resultAbort) { 15966 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15967 if (r == null) { 15968 Slog.w(TAG, "finishReceiver called but not found on queue"); 15969 return false; 15970 } 15971 15972 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15973 } 15974 15975 void backgroundServicesFinishedLocked(int userId) { 15976 for (BroadcastQueue queue : mBroadcastQueues) { 15977 queue.backgroundServicesFinishedLocked(userId); 15978 } 15979 } 15980 15981 public void finishReceiver(IBinder who, int resultCode, String resultData, 15982 Bundle resultExtras, boolean resultAbort) { 15983 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15984 15985 // Refuse possible leaked file descriptors 15986 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15987 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15988 } 15989 15990 final long origId = Binder.clearCallingIdentity(); 15991 try { 15992 boolean doNext = false; 15993 BroadcastRecord r; 15994 15995 synchronized(this) { 15996 r = broadcastRecordForReceiverLocked(who); 15997 if (r != null) { 15998 doNext = r.queue.finishReceiverLocked(r, resultCode, 15999 resultData, resultExtras, resultAbort, true); 16000 } 16001 } 16002 16003 if (doNext) { 16004 r.queue.processNextBroadcast(false); 16005 } 16006 trimApplications(); 16007 } finally { 16008 Binder.restoreCallingIdentity(origId); 16009 } 16010 } 16011 16012 // ========================================================= 16013 // INSTRUMENTATION 16014 // ========================================================= 16015 16016 public boolean startInstrumentation(ComponentName className, 16017 String profileFile, int flags, Bundle arguments, 16018 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16019 int userId, String abiOverride) { 16020 enforceNotIsolatedCaller("startInstrumentation"); 16021 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16022 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16023 // Refuse possible leaked file descriptors 16024 if (arguments != null && arguments.hasFileDescriptors()) { 16025 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16026 } 16027 16028 synchronized(this) { 16029 InstrumentationInfo ii = null; 16030 ApplicationInfo ai = null; 16031 try { 16032 ii = mContext.getPackageManager().getInstrumentationInfo( 16033 className, STOCK_PM_FLAGS); 16034 ai = AppGlobals.getPackageManager().getApplicationInfo( 16035 ii.targetPackage, STOCK_PM_FLAGS, userId); 16036 } catch (PackageManager.NameNotFoundException e) { 16037 } catch (RemoteException e) { 16038 } 16039 if (ii == null) { 16040 reportStartInstrumentationFailure(watcher, className, 16041 "Unable to find instrumentation info for: " + className); 16042 return false; 16043 } 16044 if (ai == null) { 16045 reportStartInstrumentationFailure(watcher, className, 16046 "Unable to find instrumentation target package: " + ii.targetPackage); 16047 return false; 16048 } 16049 16050 int match = mContext.getPackageManager().checkSignatures( 16051 ii.targetPackage, ii.packageName); 16052 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16053 String msg = "Permission Denial: starting instrumentation " 16054 + className + " from pid=" 16055 + Binder.getCallingPid() 16056 + ", uid=" + Binder.getCallingPid() 16057 + " not allowed because package " + ii.packageName 16058 + " does not have a signature matching the target " 16059 + ii.targetPackage; 16060 reportStartInstrumentationFailure(watcher, className, msg); 16061 throw new SecurityException(msg); 16062 } 16063 16064 final long origId = Binder.clearCallingIdentity(); 16065 // Instrumentation can kill and relaunch even persistent processes 16066 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16067 "start instr"); 16068 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16069 app.instrumentationClass = className; 16070 app.instrumentationInfo = ai; 16071 app.instrumentationProfileFile = profileFile; 16072 app.instrumentationArguments = arguments; 16073 app.instrumentationWatcher = watcher; 16074 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16075 app.instrumentationResultClass = className; 16076 Binder.restoreCallingIdentity(origId); 16077 } 16078 16079 return true; 16080 } 16081 16082 /** 16083 * Report errors that occur while attempting to start Instrumentation. Always writes the 16084 * error to the logs, but if somebody is watching, send the report there too. This enables 16085 * the "am" command to report errors with more information. 16086 * 16087 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16088 * @param cn The component name of the instrumentation. 16089 * @param report The error report. 16090 */ 16091 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16092 ComponentName cn, String report) { 16093 Slog.w(TAG, report); 16094 try { 16095 if (watcher != null) { 16096 Bundle results = new Bundle(); 16097 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16098 results.putString("Error", report); 16099 watcher.instrumentationStatus(cn, -1, results); 16100 } 16101 } catch (RemoteException e) { 16102 Slog.w(TAG, e); 16103 } 16104 } 16105 16106 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16107 if (app.instrumentationWatcher != null) { 16108 try { 16109 // NOTE: IInstrumentationWatcher *must* be oneway here 16110 app.instrumentationWatcher.instrumentationFinished( 16111 app.instrumentationClass, 16112 resultCode, 16113 results); 16114 } catch (RemoteException e) { 16115 } 16116 } 16117 if (app.instrumentationUiAutomationConnection != null) { 16118 try { 16119 app.instrumentationUiAutomationConnection.shutdown(); 16120 } catch (RemoteException re) { 16121 /* ignore */ 16122 } 16123 // Only a UiAutomation can set this flag and now that 16124 // it is finished we make sure it is reset to its default. 16125 mUserIsMonkey = false; 16126 } 16127 app.instrumentationWatcher = null; 16128 app.instrumentationUiAutomationConnection = null; 16129 app.instrumentationClass = null; 16130 app.instrumentationInfo = null; 16131 app.instrumentationProfileFile = null; 16132 app.instrumentationArguments = null; 16133 16134 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16135 "finished inst"); 16136 } 16137 16138 public void finishInstrumentation(IApplicationThread target, 16139 int resultCode, Bundle results) { 16140 int userId = UserHandle.getCallingUserId(); 16141 // Refuse possible leaked file descriptors 16142 if (results != null && results.hasFileDescriptors()) { 16143 throw new IllegalArgumentException("File descriptors passed in Intent"); 16144 } 16145 16146 synchronized(this) { 16147 ProcessRecord app = getRecordForAppLocked(target); 16148 if (app == null) { 16149 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16150 return; 16151 } 16152 final long origId = Binder.clearCallingIdentity(); 16153 finishInstrumentationLocked(app, resultCode, results); 16154 Binder.restoreCallingIdentity(origId); 16155 } 16156 } 16157 16158 // ========================================================= 16159 // CONFIGURATION 16160 // ========================================================= 16161 16162 public ConfigurationInfo getDeviceConfigurationInfo() { 16163 ConfigurationInfo config = new ConfigurationInfo(); 16164 synchronized (this) { 16165 config.reqTouchScreen = mConfiguration.touchscreen; 16166 config.reqKeyboardType = mConfiguration.keyboard; 16167 config.reqNavigation = mConfiguration.navigation; 16168 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16169 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16170 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16171 } 16172 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16173 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16174 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16175 } 16176 config.reqGlEsVersion = GL_ES_VERSION; 16177 } 16178 return config; 16179 } 16180 16181 ActivityStack getFocusedStack() { 16182 return mStackSupervisor.getFocusedStack(); 16183 } 16184 16185 public Configuration getConfiguration() { 16186 Configuration ci; 16187 synchronized(this) { 16188 ci = new Configuration(mConfiguration); 16189 } 16190 return ci; 16191 } 16192 16193 public void updatePersistentConfiguration(Configuration values) { 16194 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16195 "updateConfiguration()"); 16196 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16197 "updateConfiguration()"); 16198 if (values == null) { 16199 throw new NullPointerException("Configuration must not be null"); 16200 } 16201 16202 synchronized(this) { 16203 final long origId = Binder.clearCallingIdentity(); 16204 updateConfigurationLocked(values, null, true, false); 16205 Binder.restoreCallingIdentity(origId); 16206 } 16207 } 16208 16209 public void updateConfiguration(Configuration values) { 16210 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16211 "updateConfiguration()"); 16212 16213 synchronized(this) { 16214 if (values == null && mWindowManager != null) { 16215 // sentinel: fetch the current configuration from the window manager 16216 values = mWindowManager.computeNewConfiguration(); 16217 } 16218 16219 if (mWindowManager != null) { 16220 mProcessList.applyDisplaySize(mWindowManager); 16221 } 16222 16223 final long origId = Binder.clearCallingIdentity(); 16224 if (values != null) { 16225 Settings.System.clearConfiguration(values); 16226 } 16227 updateConfigurationLocked(values, null, false, false); 16228 Binder.restoreCallingIdentity(origId); 16229 } 16230 } 16231 16232 /** 16233 * Do either or both things: (1) change the current configuration, and (2) 16234 * make sure the given activity is running with the (now) current 16235 * configuration. Returns true if the activity has been left running, or 16236 * false if <var>starting</var> is being destroyed to match the new 16237 * configuration. 16238 * @param persistent TODO 16239 */ 16240 boolean updateConfigurationLocked(Configuration values, 16241 ActivityRecord starting, boolean persistent, boolean initLocale) { 16242 int changes = 0; 16243 16244 if (values != null) { 16245 Configuration newConfig = new Configuration(mConfiguration); 16246 changes = newConfig.updateFrom(values); 16247 if (changes != 0) { 16248 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16249 Slog.i(TAG, "Updating configuration to: " + values); 16250 } 16251 16252 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16253 16254 if (values.locale != null && !initLocale) { 16255 saveLocaleLocked(values.locale, 16256 !values.locale.equals(mConfiguration.locale), 16257 values.userSetLocale); 16258 } 16259 16260 mConfigurationSeq++; 16261 if (mConfigurationSeq <= 0) { 16262 mConfigurationSeq = 1; 16263 } 16264 newConfig.seq = mConfigurationSeq; 16265 mConfiguration = newConfig; 16266 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16267 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16268 //mUsageStatsService.noteStartConfig(newConfig); 16269 16270 final Configuration configCopy = new Configuration(mConfiguration); 16271 16272 // TODO: If our config changes, should we auto dismiss any currently 16273 // showing dialogs? 16274 mShowDialogs = shouldShowDialogs(newConfig); 16275 16276 AttributeCache ac = AttributeCache.instance(); 16277 if (ac != null) { 16278 ac.updateConfiguration(configCopy); 16279 } 16280 16281 // Make sure all resources in our process are updated 16282 // right now, so that anyone who is going to retrieve 16283 // resource values after we return will be sure to get 16284 // the new ones. This is especially important during 16285 // boot, where the first config change needs to guarantee 16286 // all resources have that config before following boot 16287 // code is executed. 16288 mSystemThread.applyConfigurationToResources(configCopy); 16289 16290 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16291 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16292 msg.obj = new Configuration(configCopy); 16293 mHandler.sendMessage(msg); 16294 } 16295 16296 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16297 ProcessRecord app = mLruProcesses.get(i); 16298 try { 16299 if (app.thread != null) { 16300 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16301 + app.processName + " new config " + mConfiguration); 16302 app.thread.scheduleConfigurationChanged(configCopy); 16303 } 16304 } catch (Exception e) { 16305 } 16306 } 16307 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16308 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16309 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16310 | Intent.FLAG_RECEIVER_FOREGROUND); 16311 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16312 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16313 Process.SYSTEM_UID, UserHandle.USER_ALL); 16314 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16315 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16316 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16317 broadcastIntentLocked(null, null, intent, 16318 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16319 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16320 } 16321 } 16322 } 16323 16324 boolean kept = true; 16325 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16326 // mainStack is null during startup. 16327 if (mainStack != null) { 16328 if (changes != 0 && starting == null) { 16329 // If the configuration changed, and the caller is not already 16330 // in the process of starting an activity, then find the top 16331 // activity to check if its configuration needs to change. 16332 starting = mainStack.topRunningActivityLocked(null); 16333 } 16334 16335 if (starting != null) { 16336 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16337 // And we need to make sure at this point that all other activities 16338 // are made visible with the correct configuration. 16339 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16340 } 16341 } 16342 16343 if (values != null && mWindowManager != null) { 16344 mWindowManager.setNewConfiguration(mConfiguration); 16345 } 16346 16347 return kept; 16348 } 16349 16350 /** 16351 * Decide based on the configuration whether we should shouw the ANR, 16352 * crash, etc dialogs. The idea is that if there is no affordnace to 16353 * press the on-screen buttons, we shouldn't show the dialog. 16354 * 16355 * A thought: SystemUI might also want to get told about this, the Power 16356 * dialog / global actions also might want different behaviors. 16357 */ 16358 private static final boolean shouldShowDialogs(Configuration config) { 16359 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16360 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16361 } 16362 16363 /** 16364 * Save the locale. You must be inside a synchronized (this) block. 16365 */ 16366 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16367 if(isDiff) { 16368 SystemProperties.set("user.language", l.getLanguage()); 16369 SystemProperties.set("user.region", l.getCountry()); 16370 } 16371 16372 if(isPersist) { 16373 SystemProperties.set("persist.sys.language", l.getLanguage()); 16374 SystemProperties.set("persist.sys.country", l.getCountry()); 16375 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16376 16377 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16378 } 16379 } 16380 16381 @Override 16382 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16383 synchronized (this) { 16384 ActivityRecord srec = ActivityRecord.forToken(token); 16385 if (srec.task != null && srec.task.stack != null) { 16386 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16387 } 16388 } 16389 return false; 16390 } 16391 16392 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16393 Intent resultData) { 16394 16395 synchronized (this) { 16396 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16397 if (stack != null) { 16398 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16399 } 16400 return false; 16401 } 16402 } 16403 16404 public int getLaunchedFromUid(IBinder activityToken) { 16405 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16406 if (srec == null) { 16407 return -1; 16408 } 16409 return srec.launchedFromUid; 16410 } 16411 16412 public String getLaunchedFromPackage(IBinder activityToken) { 16413 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16414 if (srec == null) { 16415 return null; 16416 } 16417 return srec.launchedFromPackage; 16418 } 16419 16420 // ========================================================= 16421 // LIFETIME MANAGEMENT 16422 // ========================================================= 16423 16424 // Returns which broadcast queue the app is the current [or imminent] receiver 16425 // on, or 'null' if the app is not an active broadcast recipient. 16426 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16427 BroadcastRecord r = app.curReceiver; 16428 if (r != null) { 16429 return r.queue; 16430 } 16431 16432 // It's not the current receiver, but it might be starting up to become one 16433 synchronized (this) { 16434 for (BroadcastQueue queue : mBroadcastQueues) { 16435 r = queue.mPendingBroadcast; 16436 if (r != null && r.curApp == app) { 16437 // found it; report which queue it's in 16438 return queue; 16439 } 16440 } 16441 } 16442 16443 return null; 16444 } 16445 16446 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16447 boolean doingAll, long now) { 16448 if (mAdjSeq == app.adjSeq) { 16449 // This adjustment has already been computed. 16450 return app.curRawAdj; 16451 } 16452 16453 if (app.thread == null) { 16454 app.adjSeq = mAdjSeq; 16455 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16456 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16457 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16458 } 16459 16460 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16461 app.adjSource = null; 16462 app.adjTarget = null; 16463 app.empty = false; 16464 app.cached = false; 16465 16466 final int activitiesSize = app.activities.size(); 16467 16468 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16469 // The max adjustment doesn't allow this app to be anything 16470 // below foreground, so it is not worth doing work for it. 16471 app.adjType = "fixed"; 16472 app.adjSeq = mAdjSeq; 16473 app.curRawAdj = app.maxAdj; 16474 app.foregroundActivities = false; 16475 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16476 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16477 // System processes can do UI, and when they do we want to have 16478 // them trim their memory after the user leaves the UI. To 16479 // facilitate this, here we need to determine whether or not it 16480 // is currently showing UI. 16481 app.systemNoUi = true; 16482 if (app == TOP_APP) { 16483 app.systemNoUi = false; 16484 } else if (activitiesSize > 0) { 16485 for (int j = 0; j < activitiesSize; j++) { 16486 final ActivityRecord r = app.activities.get(j); 16487 if (r.visible) { 16488 app.systemNoUi = false; 16489 } 16490 } 16491 } 16492 if (!app.systemNoUi) { 16493 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16494 } 16495 return (app.curAdj=app.maxAdj); 16496 } 16497 16498 app.systemNoUi = false; 16499 16500 // Determine the importance of the process, starting with most 16501 // important to least, and assign an appropriate OOM adjustment. 16502 int adj; 16503 int schedGroup; 16504 int procState; 16505 boolean foregroundActivities = false; 16506 BroadcastQueue queue; 16507 if (app == TOP_APP) { 16508 // The last app on the list is the foreground app. 16509 adj = ProcessList.FOREGROUND_APP_ADJ; 16510 schedGroup = Process.THREAD_GROUP_DEFAULT; 16511 app.adjType = "top-activity"; 16512 foregroundActivities = true; 16513 procState = ActivityManager.PROCESS_STATE_TOP; 16514 } else if (app.instrumentationClass != null) { 16515 // Don't want to kill running instrumentation. 16516 adj = ProcessList.FOREGROUND_APP_ADJ; 16517 schedGroup = Process.THREAD_GROUP_DEFAULT; 16518 app.adjType = "instrumentation"; 16519 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16520 } else if ((queue = isReceivingBroadcast(app)) != null) { 16521 // An app that is currently receiving a broadcast also 16522 // counts as being in the foreground for OOM killer purposes. 16523 // It's placed in a sched group based on the nature of the 16524 // broadcast as reflected by which queue it's active in. 16525 adj = ProcessList.FOREGROUND_APP_ADJ; 16526 schedGroup = (queue == mFgBroadcastQueue) 16527 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16528 app.adjType = "broadcast"; 16529 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16530 } else if (app.executingServices.size() > 0) { 16531 // An app that is currently executing a service callback also 16532 // counts as being in the foreground. 16533 adj = ProcessList.FOREGROUND_APP_ADJ; 16534 schedGroup = app.execServicesFg ? 16535 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16536 app.adjType = "exec-service"; 16537 procState = ActivityManager.PROCESS_STATE_SERVICE; 16538 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16539 } else { 16540 // As far as we know the process is empty. We may change our mind later. 16541 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16542 // At this point we don't actually know the adjustment. Use the cached adj 16543 // value that the caller wants us to. 16544 adj = cachedAdj; 16545 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16546 app.cached = true; 16547 app.empty = true; 16548 app.adjType = "cch-empty"; 16549 } 16550 16551 // Examine all activities if not already foreground. 16552 if (!foregroundActivities && activitiesSize > 0) { 16553 for (int j = 0; j < activitiesSize; j++) { 16554 final ActivityRecord r = app.activities.get(j); 16555 if (r.app != app) { 16556 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16557 + app + "?!?"); 16558 continue; 16559 } 16560 if (r.visible) { 16561 // App has a visible activity; only upgrade adjustment. 16562 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16563 adj = ProcessList.VISIBLE_APP_ADJ; 16564 app.adjType = "visible"; 16565 } 16566 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16567 procState = ActivityManager.PROCESS_STATE_TOP; 16568 } 16569 schedGroup = Process.THREAD_GROUP_DEFAULT; 16570 app.cached = false; 16571 app.empty = false; 16572 foregroundActivities = true; 16573 break; 16574 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16575 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16576 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16577 app.adjType = "pausing"; 16578 } 16579 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16580 procState = ActivityManager.PROCESS_STATE_TOP; 16581 } 16582 schedGroup = Process.THREAD_GROUP_DEFAULT; 16583 app.cached = false; 16584 app.empty = false; 16585 foregroundActivities = true; 16586 } else if (r.state == ActivityState.STOPPING) { 16587 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16588 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16589 app.adjType = "stopping"; 16590 } 16591 // For the process state, we will at this point consider the 16592 // process to be cached. It will be cached either as an activity 16593 // or empty depending on whether the activity is finishing. We do 16594 // this so that we can treat the process as cached for purposes of 16595 // memory trimming (determing current memory level, trim command to 16596 // send to process) since there can be an arbitrary number of stopping 16597 // processes and they should soon all go into the cached state. 16598 if (!r.finishing) { 16599 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16600 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16601 } 16602 } 16603 app.cached = false; 16604 app.empty = false; 16605 foregroundActivities = true; 16606 } else { 16607 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16608 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16609 app.adjType = "cch-act"; 16610 } 16611 } 16612 } 16613 } 16614 16615 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16616 if (app.foregroundServices) { 16617 // The user is aware of this app, so make it visible. 16618 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16619 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16620 app.cached = false; 16621 app.adjType = "fg-service"; 16622 schedGroup = Process.THREAD_GROUP_DEFAULT; 16623 } else if (app.forcingToForeground != null) { 16624 // The user is aware of this app, so make it visible. 16625 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16626 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16627 app.cached = false; 16628 app.adjType = "force-fg"; 16629 app.adjSource = app.forcingToForeground; 16630 schedGroup = Process.THREAD_GROUP_DEFAULT; 16631 } 16632 } 16633 16634 if (app == mHeavyWeightProcess) { 16635 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16636 // We don't want to kill the current heavy-weight process. 16637 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16638 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16639 app.cached = false; 16640 app.adjType = "heavy"; 16641 } 16642 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16643 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16644 } 16645 } 16646 16647 if (app == mHomeProcess) { 16648 if (adj > ProcessList.HOME_APP_ADJ) { 16649 // This process is hosting what we currently consider to be the 16650 // home app, so we don't want to let it go into the background. 16651 adj = ProcessList.HOME_APP_ADJ; 16652 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16653 app.cached = false; 16654 app.adjType = "home"; 16655 } 16656 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16657 procState = ActivityManager.PROCESS_STATE_HOME; 16658 } 16659 } 16660 16661 if (app == mPreviousProcess && app.activities.size() > 0) { 16662 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16663 // This was the previous process that showed UI to the user. 16664 // We want to try to keep it around more aggressively, to give 16665 // a good experience around switching between two apps. 16666 adj = ProcessList.PREVIOUS_APP_ADJ; 16667 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16668 app.cached = false; 16669 app.adjType = "previous"; 16670 } 16671 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16672 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16673 } 16674 } 16675 16676 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16677 + " reason=" + app.adjType); 16678 16679 // By default, we use the computed adjustment. It may be changed if 16680 // there are applications dependent on our services or providers, but 16681 // this gives us a baseline and makes sure we don't get into an 16682 // infinite recursion. 16683 app.adjSeq = mAdjSeq; 16684 app.curRawAdj = adj; 16685 app.hasStartedServices = false; 16686 16687 if (mBackupTarget != null && app == mBackupTarget.app) { 16688 // If possible we want to avoid killing apps while they're being backed up 16689 if (adj > ProcessList.BACKUP_APP_ADJ) { 16690 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16691 adj = ProcessList.BACKUP_APP_ADJ; 16692 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16693 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16694 } 16695 app.adjType = "backup"; 16696 app.cached = false; 16697 } 16698 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16699 procState = ActivityManager.PROCESS_STATE_BACKUP; 16700 } 16701 } 16702 16703 boolean mayBeTop = false; 16704 16705 for (int is = app.services.size()-1; 16706 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16707 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16708 || procState > ActivityManager.PROCESS_STATE_TOP); 16709 is--) { 16710 ServiceRecord s = app.services.valueAt(is); 16711 if (s.startRequested) { 16712 app.hasStartedServices = true; 16713 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16714 procState = ActivityManager.PROCESS_STATE_SERVICE; 16715 } 16716 if (app.hasShownUi && app != mHomeProcess) { 16717 // If this process has shown some UI, let it immediately 16718 // go to the LRU list because it may be pretty heavy with 16719 // UI stuff. We'll tag it with a label just to help 16720 // debug and understand what is going on. 16721 if (adj > ProcessList.SERVICE_ADJ) { 16722 app.adjType = "cch-started-ui-services"; 16723 } 16724 } else { 16725 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16726 // This service has seen some activity within 16727 // recent memory, so we will keep its process ahead 16728 // of the background processes. 16729 if (adj > ProcessList.SERVICE_ADJ) { 16730 adj = ProcessList.SERVICE_ADJ; 16731 app.adjType = "started-services"; 16732 app.cached = false; 16733 } 16734 } 16735 // If we have let the service slide into the background 16736 // state, still have some text describing what it is doing 16737 // even though the service no longer has an impact. 16738 if (adj > ProcessList.SERVICE_ADJ) { 16739 app.adjType = "cch-started-services"; 16740 } 16741 } 16742 } 16743 for (int conni = s.connections.size()-1; 16744 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16745 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16746 || procState > ActivityManager.PROCESS_STATE_TOP); 16747 conni--) { 16748 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16749 for (int i = 0; 16750 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16751 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16752 || procState > ActivityManager.PROCESS_STATE_TOP); 16753 i++) { 16754 // XXX should compute this based on the max of 16755 // all connected clients. 16756 ConnectionRecord cr = clist.get(i); 16757 if (cr.binding.client == app) { 16758 // Binding to ourself is not interesting. 16759 continue; 16760 } 16761 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16762 ProcessRecord client = cr.binding.client; 16763 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16764 TOP_APP, doingAll, now); 16765 int clientProcState = client.curProcState; 16766 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16767 // If the other app is cached for any reason, for purposes here 16768 // we are going to consider it empty. The specific cached state 16769 // doesn't propagate except under certain conditions. 16770 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16771 } 16772 String adjType = null; 16773 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16774 // Not doing bind OOM management, so treat 16775 // this guy more like a started service. 16776 if (app.hasShownUi && app != mHomeProcess) { 16777 // If this process has shown some UI, let it immediately 16778 // go to the LRU list because it may be pretty heavy with 16779 // UI stuff. We'll tag it with a label just to help 16780 // debug and understand what is going on. 16781 if (adj > clientAdj) { 16782 adjType = "cch-bound-ui-services"; 16783 } 16784 app.cached = false; 16785 clientAdj = adj; 16786 clientProcState = procState; 16787 } else { 16788 if (now >= (s.lastActivity 16789 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16790 // This service has not seen activity within 16791 // recent memory, so allow it to drop to the 16792 // LRU list if there is no other reason to keep 16793 // it around. We'll also tag it with a label just 16794 // to help debug and undertand what is going on. 16795 if (adj > clientAdj) { 16796 adjType = "cch-bound-services"; 16797 } 16798 clientAdj = adj; 16799 } 16800 } 16801 } 16802 if (adj > clientAdj) { 16803 // If this process has recently shown UI, and 16804 // the process that is binding to it is less 16805 // important than being visible, then we don't 16806 // care about the binding as much as we care 16807 // about letting this process get into the LRU 16808 // list to be killed and restarted if needed for 16809 // memory. 16810 if (app.hasShownUi && app != mHomeProcess 16811 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16812 adjType = "cch-bound-ui-services"; 16813 } else { 16814 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16815 |Context.BIND_IMPORTANT)) != 0) { 16816 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16817 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16818 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16819 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16820 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16821 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16822 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16823 adj = clientAdj; 16824 } else { 16825 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16826 adj = ProcessList.VISIBLE_APP_ADJ; 16827 } 16828 } 16829 if (!client.cached) { 16830 app.cached = false; 16831 } 16832 adjType = "service"; 16833 } 16834 } 16835 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16836 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16837 schedGroup = Process.THREAD_GROUP_DEFAULT; 16838 } 16839 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16840 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16841 // Special handling of clients who are in the top state. 16842 // We *may* want to consider this process to be in the 16843 // top state as well, but only if there is not another 16844 // reason for it to be running. Being on the top is a 16845 // special state, meaning you are specifically running 16846 // for the current top app. If the process is already 16847 // running in the background for some other reason, it 16848 // is more important to continue considering it to be 16849 // in the background state. 16850 mayBeTop = true; 16851 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16852 } else { 16853 // Special handling for above-top states (persistent 16854 // processes). These should not bring the current process 16855 // into the top state, since they are not on top. Instead 16856 // give them the best state after that. 16857 clientProcState = 16858 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16859 } 16860 } 16861 } else { 16862 if (clientProcState < 16863 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16864 clientProcState = 16865 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16866 } 16867 } 16868 if (procState > clientProcState) { 16869 procState = clientProcState; 16870 } 16871 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16872 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16873 app.pendingUiClean = true; 16874 } 16875 if (adjType != null) { 16876 app.adjType = adjType; 16877 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16878 .REASON_SERVICE_IN_USE; 16879 app.adjSource = cr.binding.client; 16880 app.adjSourceProcState = clientProcState; 16881 app.adjTarget = s.name; 16882 } 16883 } 16884 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16885 app.treatLikeActivity = true; 16886 } 16887 final ActivityRecord a = cr.activity; 16888 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16889 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16890 (a.visible || a.state == ActivityState.RESUMED 16891 || a.state == ActivityState.PAUSING)) { 16892 adj = ProcessList.FOREGROUND_APP_ADJ; 16893 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16894 schedGroup = Process.THREAD_GROUP_DEFAULT; 16895 } 16896 app.cached = false; 16897 app.adjType = "service"; 16898 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16899 .REASON_SERVICE_IN_USE; 16900 app.adjSource = a; 16901 app.adjSourceProcState = procState; 16902 app.adjTarget = s.name; 16903 } 16904 } 16905 } 16906 } 16907 } 16908 16909 for (int provi = app.pubProviders.size()-1; 16910 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16911 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16912 || procState > ActivityManager.PROCESS_STATE_TOP); 16913 provi--) { 16914 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16915 for (int i = cpr.connections.size()-1; 16916 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16917 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16918 || procState > ActivityManager.PROCESS_STATE_TOP); 16919 i--) { 16920 ContentProviderConnection conn = cpr.connections.get(i); 16921 ProcessRecord client = conn.client; 16922 if (client == app) { 16923 // Being our own client is not interesting. 16924 continue; 16925 } 16926 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16927 int clientProcState = client.curProcState; 16928 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16929 // If the other app is cached for any reason, for purposes here 16930 // we are going to consider it empty. 16931 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16932 } 16933 if (adj > clientAdj) { 16934 if (app.hasShownUi && app != mHomeProcess 16935 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16936 app.adjType = "cch-ui-provider"; 16937 } else { 16938 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16939 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16940 app.adjType = "provider"; 16941 } 16942 app.cached &= client.cached; 16943 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16944 .REASON_PROVIDER_IN_USE; 16945 app.adjSource = client; 16946 app.adjSourceProcState = clientProcState; 16947 app.adjTarget = cpr.name; 16948 } 16949 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16950 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16951 // Special handling of clients who are in the top state. 16952 // We *may* want to consider this process to be in the 16953 // top state as well, but only if there is not another 16954 // reason for it to be running. Being on the top is a 16955 // special state, meaning you are specifically running 16956 // for the current top app. If the process is already 16957 // running in the background for some other reason, it 16958 // is more important to continue considering it to be 16959 // in the background state. 16960 mayBeTop = true; 16961 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16962 } else { 16963 // Special handling for above-top states (persistent 16964 // processes). These should not bring the current process 16965 // into the top state, since they are not on top. Instead 16966 // give them the best state after that. 16967 clientProcState = 16968 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16969 } 16970 } 16971 if (procState > clientProcState) { 16972 procState = clientProcState; 16973 } 16974 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16975 schedGroup = Process.THREAD_GROUP_DEFAULT; 16976 } 16977 } 16978 // If the provider has external (non-framework) process 16979 // dependencies, ensure that its adjustment is at least 16980 // FOREGROUND_APP_ADJ. 16981 if (cpr.hasExternalProcessHandles()) { 16982 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16983 adj = ProcessList.FOREGROUND_APP_ADJ; 16984 schedGroup = Process.THREAD_GROUP_DEFAULT; 16985 app.cached = false; 16986 app.adjType = "provider"; 16987 app.adjTarget = cpr.name; 16988 } 16989 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16990 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16991 } 16992 } 16993 } 16994 16995 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16996 // A client of one of our services or providers is in the top state. We 16997 // *may* want to be in the top state, but not if we are already running in 16998 // the background for some other reason. For the decision here, we are going 16999 // to pick out a few specific states that we want to remain in when a client 17000 // is top (states that tend to be longer-term) and otherwise allow it to go 17001 // to the top state. 17002 switch (procState) { 17003 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17004 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17005 case ActivityManager.PROCESS_STATE_SERVICE: 17006 // These all are longer-term states, so pull them up to the top 17007 // of the background states, but not all the way to the top state. 17008 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17009 break; 17010 default: 17011 // Otherwise, top is a better choice, so take it. 17012 procState = ActivityManager.PROCESS_STATE_TOP; 17013 break; 17014 } 17015 } 17016 17017 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17018 if (app.hasClientActivities) { 17019 // This is a cached process, but with client activities. Mark it so. 17020 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17021 app.adjType = "cch-client-act"; 17022 } else if (app.treatLikeActivity) { 17023 // This is a cached process, but somebody wants us to treat it like it has 17024 // an activity, okay! 17025 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17026 app.adjType = "cch-as-act"; 17027 } 17028 } 17029 17030 if (adj == ProcessList.SERVICE_ADJ) { 17031 if (doingAll) { 17032 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17033 mNewNumServiceProcs++; 17034 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17035 if (!app.serviceb) { 17036 // This service isn't far enough down on the LRU list to 17037 // normally be a B service, but if we are low on RAM and it 17038 // is large we want to force it down since we would prefer to 17039 // keep launcher over it. 17040 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17041 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17042 app.serviceHighRam = true; 17043 app.serviceb = true; 17044 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17045 } else { 17046 mNewNumAServiceProcs++; 17047 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17048 } 17049 } else { 17050 app.serviceHighRam = false; 17051 } 17052 } 17053 if (app.serviceb) { 17054 adj = ProcessList.SERVICE_B_ADJ; 17055 } 17056 } 17057 17058 app.curRawAdj = adj; 17059 17060 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17061 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17062 if (adj > app.maxAdj) { 17063 adj = app.maxAdj; 17064 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17065 schedGroup = Process.THREAD_GROUP_DEFAULT; 17066 } 17067 } 17068 17069 // Do final modification to adj. Everything we do between here and applying 17070 // the final setAdj must be done in this function, because we will also use 17071 // it when computing the final cached adj later. Note that we don't need to 17072 // worry about this for max adj above, since max adj will always be used to 17073 // keep it out of the cached vaues. 17074 app.curAdj = app.modifyRawOomAdj(adj); 17075 app.curSchedGroup = schedGroup; 17076 app.curProcState = procState; 17077 app.foregroundActivities = foregroundActivities; 17078 17079 return app.curRawAdj; 17080 } 17081 17082 /** 17083 * Schedule PSS collection of a process. 17084 */ 17085 void requestPssLocked(ProcessRecord proc, int procState) { 17086 if (mPendingPssProcesses.contains(proc)) { 17087 return; 17088 } 17089 if (mPendingPssProcesses.size() == 0) { 17090 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17091 } 17092 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17093 proc.pssProcState = procState; 17094 mPendingPssProcesses.add(proc); 17095 } 17096 17097 /** 17098 * Schedule PSS collection of all processes. 17099 */ 17100 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17101 if (!always) { 17102 if (now < (mLastFullPssTime + 17103 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17104 return; 17105 } 17106 } 17107 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17108 mLastFullPssTime = now; 17109 mFullPssPending = true; 17110 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17111 mPendingPssProcesses.clear(); 17112 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17113 ProcessRecord app = mLruProcesses.get(i); 17114 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17115 app.pssProcState = app.setProcState; 17116 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17117 isSleeping(), now); 17118 mPendingPssProcesses.add(app); 17119 } 17120 } 17121 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17122 } 17123 17124 /** 17125 * Ask a given process to GC right now. 17126 */ 17127 final void performAppGcLocked(ProcessRecord app) { 17128 try { 17129 app.lastRequestedGc = SystemClock.uptimeMillis(); 17130 if (app.thread != null) { 17131 if (app.reportLowMemory) { 17132 app.reportLowMemory = false; 17133 app.thread.scheduleLowMemory(); 17134 } else { 17135 app.thread.processInBackground(); 17136 } 17137 } 17138 } catch (Exception e) { 17139 // whatever. 17140 } 17141 } 17142 17143 /** 17144 * Returns true if things are idle enough to perform GCs. 17145 */ 17146 private final boolean canGcNowLocked() { 17147 boolean processingBroadcasts = false; 17148 for (BroadcastQueue q : mBroadcastQueues) { 17149 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17150 processingBroadcasts = true; 17151 } 17152 } 17153 return !processingBroadcasts 17154 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17155 } 17156 17157 /** 17158 * Perform GCs on all processes that are waiting for it, but only 17159 * if things are idle. 17160 */ 17161 final void performAppGcsLocked() { 17162 final int N = mProcessesToGc.size(); 17163 if (N <= 0) { 17164 return; 17165 } 17166 if (canGcNowLocked()) { 17167 while (mProcessesToGc.size() > 0) { 17168 ProcessRecord proc = mProcessesToGc.remove(0); 17169 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17170 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17171 <= SystemClock.uptimeMillis()) { 17172 // To avoid spamming the system, we will GC processes one 17173 // at a time, waiting a few seconds between each. 17174 performAppGcLocked(proc); 17175 scheduleAppGcsLocked(); 17176 return; 17177 } else { 17178 // It hasn't been long enough since we last GCed this 17179 // process... put it in the list to wait for its time. 17180 addProcessToGcListLocked(proc); 17181 break; 17182 } 17183 } 17184 } 17185 17186 scheduleAppGcsLocked(); 17187 } 17188 } 17189 17190 /** 17191 * If all looks good, perform GCs on all processes waiting for them. 17192 */ 17193 final void performAppGcsIfAppropriateLocked() { 17194 if (canGcNowLocked()) { 17195 performAppGcsLocked(); 17196 return; 17197 } 17198 // Still not idle, wait some more. 17199 scheduleAppGcsLocked(); 17200 } 17201 17202 /** 17203 * Schedule the execution of all pending app GCs. 17204 */ 17205 final void scheduleAppGcsLocked() { 17206 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17207 17208 if (mProcessesToGc.size() > 0) { 17209 // Schedule a GC for the time to the next process. 17210 ProcessRecord proc = mProcessesToGc.get(0); 17211 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17212 17213 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17214 long now = SystemClock.uptimeMillis(); 17215 if (when < (now+GC_TIMEOUT)) { 17216 when = now + GC_TIMEOUT; 17217 } 17218 mHandler.sendMessageAtTime(msg, when); 17219 } 17220 } 17221 17222 /** 17223 * Add a process to the array of processes waiting to be GCed. Keeps the 17224 * list in sorted order by the last GC time. The process can't already be 17225 * on the list. 17226 */ 17227 final void addProcessToGcListLocked(ProcessRecord proc) { 17228 boolean added = false; 17229 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17230 if (mProcessesToGc.get(i).lastRequestedGc < 17231 proc.lastRequestedGc) { 17232 added = true; 17233 mProcessesToGc.add(i+1, proc); 17234 break; 17235 } 17236 } 17237 if (!added) { 17238 mProcessesToGc.add(0, proc); 17239 } 17240 } 17241 17242 /** 17243 * Set up to ask a process to GC itself. This will either do it 17244 * immediately, or put it on the list of processes to gc the next 17245 * time things are idle. 17246 */ 17247 final void scheduleAppGcLocked(ProcessRecord app) { 17248 long now = SystemClock.uptimeMillis(); 17249 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17250 return; 17251 } 17252 if (!mProcessesToGc.contains(app)) { 17253 addProcessToGcListLocked(app); 17254 scheduleAppGcsLocked(); 17255 } 17256 } 17257 17258 final void checkExcessivePowerUsageLocked(boolean doKills) { 17259 updateCpuStatsNow(); 17260 17261 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17262 boolean doWakeKills = doKills; 17263 boolean doCpuKills = doKills; 17264 if (mLastPowerCheckRealtime == 0) { 17265 doWakeKills = false; 17266 } 17267 if (mLastPowerCheckUptime == 0) { 17268 doCpuKills = false; 17269 } 17270 if (stats.isScreenOn()) { 17271 doWakeKills = false; 17272 } 17273 final long curRealtime = SystemClock.elapsedRealtime(); 17274 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17275 final long curUptime = SystemClock.uptimeMillis(); 17276 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17277 mLastPowerCheckRealtime = curRealtime; 17278 mLastPowerCheckUptime = curUptime; 17279 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17280 doWakeKills = false; 17281 } 17282 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17283 doCpuKills = false; 17284 } 17285 int i = mLruProcesses.size(); 17286 while (i > 0) { 17287 i--; 17288 ProcessRecord app = mLruProcesses.get(i); 17289 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17290 long wtime; 17291 synchronized (stats) { 17292 wtime = stats.getProcessWakeTime(app.info.uid, 17293 app.pid, curRealtime); 17294 } 17295 long wtimeUsed = wtime - app.lastWakeTime; 17296 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17297 if (DEBUG_POWER) { 17298 StringBuilder sb = new StringBuilder(128); 17299 sb.append("Wake for "); 17300 app.toShortString(sb); 17301 sb.append(": over "); 17302 TimeUtils.formatDuration(realtimeSince, sb); 17303 sb.append(" used "); 17304 TimeUtils.formatDuration(wtimeUsed, sb); 17305 sb.append(" ("); 17306 sb.append((wtimeUsed*100)/realtimeSince); 17307 sb.append("%)"); 17308 Slog.i(TAG, sb.toString()); 17309 sb.setLength(0); 17310 sb.append("CPU for "); 17311 app.toShortString(sb); 17312 sb.append(": over "); 17313 TimeUtils.formatDuration(uptimeSince, sb); 17314 sb.append(" used "); 17315 TimeUtils.formatDuration(cputimeUsed, sb); 17316 sb.append(" ("); 17317 sb.append((cputimeUsed*100)/uptimeSince); 17318 sb.append("%)"); 17319 Slog.i(TAG, sb.toString()); 17320 } 17321 // If a process has held a wake lock for more 17322 // than 50% of the time during this period, 17323 // that sounds bad. Kill! 17324 if (doWakeKills && realtimeSince > 0 17325 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17326 synchronized (stats) { 17327 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17328 realtimeSince, wtimeUsed); 17329 } 17330 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17331 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17332 } else if (doCpuKills && uptimeSince > 0 17333 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17334 synchronized (stats) { 17335 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17336 uptimeSince, cputimeUsed); 17337 } 17338 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17339 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17340 } else { 17341 app.lastWakeTime = wtime; 17342 app.lastCpuTime = app.curCpuTime; 17343 } 17344 } 17345 } 17346 } 17347 17348 private final boolean applyOomAdjLocked(ProcessRecord app, 17349 ProcessRecord TOP_APP, boolean doingAll, long now) { 17350 boolean success = true; 17351 17352 if (app.curRawAdj != app.setRawAdj) { 17353 app.setRawAdj = app.curRawAdj; 17354 } 17355 17356 int changes = 0; 17357 17358 if (app.curAdj != app.setAdj) { 17359 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17360 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17361 TAG, "Set " + app.pid + " " + app.processName + 17362 " adj " + app.curAdj + ": " + app.adjType); 17363 app.setAdj = app.curAdj; 17364 } 17365 17366 if (app.setSchedGroup != app.curSchedGroup) { 17367 app.setSchedGroup = app.curSchedGroup; 17368 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17369 "Setting process group of " + app.processName 17370 + " to " + app.curSchedGroup); 17371 if (app.waitingToKill != null && 17372 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17373 app.kill(app.waitingToKill, true); 17374 success = false; 17375 } else { 17376 if (true) { 17377 long oldId = Binder.clearCallingIdentity(); 17378 try { 17379 Process.setProcessGroup(app.pid, app.curSchedGroup); 17380 } catch (Exception e) { 17381 Slog.w(TAG, "Failed setting process group of " + app.pid 17382 + " to " + app.curSchedGroup); 17383 e.printStackTrace(); 17384 } finally { 17385 Binder.restoreCallingIdentity(oldId); 17386 } 17387 } else { 17388 if (app.thread != null) { 17389 try { 17390 app.thread.setSchedulingGroup(app.curSchedGroup); 17391 } catch (RemoteException e) { 17392 } 17393 } 17394 } 17395 Process.setSwappiness(app.pid, 17396 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17397 } 17398 } 17399 if (app.repForegroundActivities != app.foregroundActivities) { 17400 app.repForegroundActivities = app.foregroundActivities; 17401 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17402 } 17403 if (app.repProcState != app.curProcState) { 17404 app.repProcState = app.curProcState; 17405 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17406 if (app.thread != null) { 17407 try { 17408 if (false) { 17409 //RuntimeException h = new RuntimeException("here"); 17410 Slog.i(TAG, "Sending new process state " + app.repProcState 17411 + " to " + app /*, h*/); 17412 } 17413 app.thread.setProcessState(app.repProcState); 17414 } catch (RemoteException e) { 17415 } 17416 } 17417 } 17418 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17419 app.setProcState)) { 17420 app.lastStateTime = now; 17421 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17422 isSleeping(), now); 17423 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17424 + ProcessList.makeProcStateString(app.setProcState) + " to " 17425 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17426 + (app.nextPssTime-now) + ": " + app); 17427 } else { 17428 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17429 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17430 requestPssLocked(app, app.setProcState); 17431 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17432 isSleeping(), now); 17433 } else if (false && DEBUG_PSS) { 17434 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17435 } 17436 } 17437 if (app.setProcState != app.curProcState) { 17438 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17439 "Proc state change of " + app.processName 17440 + " to " + app.curProcState); 17441 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17442 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17443 if (setImportant && !curImportant) { 17444 // This app is no longer something we consider important enough to allow to 17445 // use arbitrary amounts of battery power. Note 17446 // its current wake lock time to later know to kill it if 17447 // it is not behaving well. 17448 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17449 synchronized (stats) { 17450 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17451 app.pid, SystemClock.elapsedRealtime()); 17452 } 17453 app.lastCpuTime = app.curCpuTime; 17454 17455 } 17456 app.setProcState = app.curProcState; 17457 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17458 app.notCachedSinceIdle = false; 17459 } 17460 if (!doingAll) { 17461 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17462 } else { 17463 app.procStateChanged = true; 17464 } 17465 } 17466 17467 if (changes != 0) { 17468 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17469 int i = mPendingProcessChanges.size()-1; 17470 ProcessChangeItem item = null; 17471 while (i >= 0) { 17472 item = mPendingProcessChanges.get(i); 17473 if (item.pid == app.pid) { 17474 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17475 break; 17476 } 17477 i--; 17478 } 17479 if (i < 0) { 17480 // No existing item in pending changes; need a new one. 17481 final int NA = mAvailProcessChanges.size(); 17482 if (NA > 0) { 17483 item = mAvailProcessChanges.remove(NA-1); 17484 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17485 } else { 17486 item = new ProcessChangeItem(); 17487 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17488 } 17489 item.changes = 0; 17490 item.pid = app.pid; 17491 item.uid = app.info.uid; 17492 if (mPendingProcessChanges.size() == 0) { 17493 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17494 "*** Enqueueing dispatch processes changed!"); 17495 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17496 } 17497 mPendingProcessChanges.add(item); 17498 } 17499 item.changes |= changes; 17500 item.processState = app.repProcState; 17501 item.foregroundActivities = app.repForegroundActivities; 17502 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17503 + Integer.toHexString(System.identityHashCode(item)) 17504 + " " + app.toShortString() + ": changes=" + item.changes 17505 + " procState=" + item.processState 17506 + " foreground=" + item.foregroundActivities 17507 + " type=" + app.adjType + " source=" + app.adjSource 17508 + " target=" + app.adjTarget); 17509 } 17510 17511 return success; 17512 } 17513 17514 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17515 if (proc.thread != null) { 17516 if (proc.baseProcessTracker != null) { 17517 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17518 } 17519 if (proc.repProcState >= 0) { 17520 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17521 proc.repProcState); 17522 } 17523 } 17524 } 17525 17526 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17527 ProcessRecord TOP_APP, boolean doingAll, long now) { 17528 if (app.thread == null) { 17529 return false; 17530 } 17531 17532 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17533 17534 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17535 } 17536 17537 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17538 boolean oomAdj) { 17539 if (isForeground != proc.foregroundServices) { 17540 proc.foregroundServices = isForeground; 17541 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17542 proc.info.uid); 17543 if (isForeground) { 17544 if (curProcs == null) { 17545 curProcs = new ArrayList<ProcessRecord>(); 17546 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17547 } 17548 if (!curProcs.contains(proc)) { 17549 curProcs.add(proc); 17550 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17551 proc.info.packageName, proc.info.uid); 17552 } 17553 } else { 17554 if (curProcs != null) { 17555 if (curProcs.remove(proc)) { 17556 mBatteryStatsService.noteEvent( 17557 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17558 proc.info.packageName, proc.info.uid); 17559 if (curProcs.size() <= 0) { 17560 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17561 } 17562 } 17563 } 17564 } 17565 if (oomAdj) { 17566 updateOomAdjLocked(); 17567 } 17568 } 17569 } 17570 17571 private final ActivityRecord resumedAppLocked() { 17572 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17573 String pkg; 17574 int uid; 17575 if (act != null) { 17576 pkg = act.packageName; 17577 uid = act.info.applicationInfo.uid; 17578 } else { 17579 pkg = null; 17580 uid = -1; 17581 } 17582 // Has the UID or resumed package name changed? 17583 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17584 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17585 if (mCurResumedPackage != null) { 17586 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17587 mCurResumedPackage, mCurResumedUid); 17588 } 17589 mCurResumedPackage = pkg; 17590 mCurResumedUid = uid; 17591 if (mCurResumedPackage != null) { 17592 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17593 mCurResumedPackage, mCurResumedUid); 17594 } 17595 } 17596 return act; 17597 } 17598 17599 final boolean updateOomAdjLocked(ProcessRecord app) { 17600 final ActivityRecord TOP_ACT = resumedAppLocked(); 17601 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17602 final boolean wasCached = app.cached; 17603 17604 mAdjSeq++; 17605 17606 // This is the desired cached adjusment we want to tell it to use. 17607 // If our app is currently cached, we know it, and that is it. Otherwise, 17608 // we don't know it yet, and it needs to now be cached we will then 17609 // need to do a complete oom adj. 17610 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17611 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17612 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17613 SystemClock.uptimeMillis()); 17614 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17615 // Changed to/from cached state, so apps after it in the LRU 17616 // list may also be changed. 17617 updateOomAdjLocked(); 17618 } 17619 return success; 17620 } 17621 17622 final void updateOomAdjLocked() { 17623 final ActivityRecord TOP_ACT = resumedAppLocked(); 17624 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17625 final long now = SystemClock.uptimeMillis(); 17626 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17627 final int N = mLruProcesses.size(); 17628 17629 if (false) { 17630 RuntimeException e = new RuntimeException(); 17631 e.fillInStackTrace(); 17632 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17633 } 17634 17635 mAdjSeq++; 17636 mNewNumServiceProcs = 0; 17637 mNewNumAServiceProcs = 0; 17638 17639 final int emptyProcessLimit; 17640 final int cachedProcessLimit; 17641 if (mProcessLimit <= 0) { 17642 emptyProcessLimit = cachedProcessLimit = 0; 17643 } else if (mProcessLimit == 1) { 17644 emptyProcessLimit = 1; 17645 cachedProcessLimit = 0; 17646 } else { 17647 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17648 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17649 } 17650 17651 // Let's determine how many processes we have running vs. 17652 // how many slots we have for background processes; we may want 17653 // to put multiple processes in a slot of there are enough of 17654 // them. 17655 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17656 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17657 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17658 if (numEmptyProcs > cachedProcessLimit) { 17659 // If there are more empty processes than our limit on cached 17660 // processes, then use the cached process limit for the factor. 17661 // This ensures that the really old empty processes get pushed 17662 // down to the bottom, so if we are running low on memory we will 17663 // have a better chance at keeping around more cached processes 17664 // instead of a gazillion empty processes. 17665 numEmptyProcs = cachedProcessLimit; 17666 } 17667 int emptyFactor = numEmptyProcs/numSlots; 17668 if (emptyFactor < 1) emptyFactor = 1; 17669 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17670 if (cachedFactor < 1) cachedFactor = 1; 17671 int stepCached = 0; 17672 int stepEmpty = 0; 17673 int numCached = 0; 17674 int numEmpty = 0; 17675 int numTrimming = 0; 17676 17677 mNumNonCachedProcs = 0; 17678 mNumCachedHiddenProcs = 0; 17679 17680 // First update the OOM adjustment for each of the 17681 // application processes based on their current state. 17682 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17683 int nextCachedAdj = curCachedAdj+1; 17684 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17685 int nextEmptyAdj = curEmptyAdj+2; 17686 for (int i=N-1; i>=0; i--) { 17687 ProcessRecord app = mLruProcesses.get(i); 17688 if (!app.killedByAm && app.thread != null) { 17689 app.procStateChanged = false; 17690 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17691 17692 // If we haven't yet assigned the final cached adj 17693 // to the process, do that now. 17694 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17695 switch (app.curProcState) { 17696 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17697 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17698 // This process is a cached process holding activities... 17699 // assign it the next cached value for that type, and then 17700 // step that cached level. 17701 app.curRawAdj = curCachedAdj; 17702 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17703 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17704 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17705 + ")"); 17706 if (curCachedAdj != nextCachedAdj) { 17707 stepCached++; 17708 if (stepCached >= cachedFactor) { 17709 stepCached = 0; 17710 curCachedAdj = nextCachedAdj; 17711 nextCachedAdj += 2; 17712 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17713 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17714 } 17715 } 17716 } 17717 break; 17718 default: 17719 // For everything else, assign next empty cached process 17720 // level and bump that up. Note that this means that 17721 // long-running services that have dropped down to the 17722 // cached level will be treated as empty (since their process 17723 // state is still as a service), which is what we want. 17724 app.curRawAdj = curEmptyAdj; 17725 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17726 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17727 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17728 + ")"); 17729 if (curEmptyAdj != nextEmptyAdj) { 17730 stepEmpty++; 17731 if (stepEmpty >= emptyFactor) { 17732 stepEmpty = 0; 17733 curEmptyAdj = nextEmptyAdj; 17734 nextEmptyAdj += 2; 17735 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17736 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17737 } 17738 } 17739 } 17740 break; 17741 } 17742 } 17743 17744 applyOomAdjLocked(app, TOP_APP, true, now); 17745 17746 // Count the number of process types. 17747 switch (app.curProcState) { 17748 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17749 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17750 mNumCachedHiddenProcs++; 17751 numCached++; 17752 if (numCached > cachedProcessLimit) { 17753 app.kill("cached #" + numCached, true); 17754 } 17755 break; 17756 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17757 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17758 && app.lastActivityTime < oldTime) { 17759 app.kill("empty for " 17760 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17761 / 1000) + "s", true); 17762 } else { 17763 numEmpty++; 17764 if (numEmpty > emptyProcessLimit) { 17765 app.kill("empty #" + numEmpty, true); 17766 } 17767 } 17768 break; 17769 default: 17770 mNumNonCachedProcs++; 17771 break; 17772 } 17773 17774 if (app.isolated && app.services.size() <= 0) { 17775 // If this is an isolated process, and there are no 17776 // services running in it, then the process is no longer 17777 // needed. We agressively kill these because we can by 17778 // definition not re-use the same process again, and it is 17779 // good to avoid having whatever code was running in them 17780 // left sitting around after no longer needed. 17781 app.kill("isolated not needed", true); 17782 } 17783 17784 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17785 && !app.killedByAm) { 17786 numTrimming++; 17787 } 17788 } 17789 } 17790 17791 mNumServiceProcs = mNewNumServiceProcs; 17792 17793 // Now determine the memory trimming level of background processes. 17794 // Unfortunately we need to start at the back of the list to do this 17795 // properly. We only do this if the number of background apps we 17796 // are managing to keep around is less than half the maximum we desire; 17797 // if we are keeping a good number around, we'll let them use whatever 17798 // memory they want. 17799 final int numCachedAndEmpty = numCached + numEmpty; 17800 int memFactor; 17801 if (numCached <= ProcessList.TRIM_CACHED_APPS 17802 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17803 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17804 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17805 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17806 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17807 } else { 17808 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17809 } 17810 } else { 17811 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17812 } 17813 // We always allow the memory level to go up (better). We only allow it to go 17814 // down if we are in a state where that is allowed, *and* the total number of processes 17815 // has gone down since last time. 17816 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17817 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17818 + " last=" + mLastNumProcesses); 17819 if (memFactor > mLastMemoryLevel) { 17820 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17821 memFactor = mLastMemoryLevel; 17822 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17823 } 17824 } 17825 mLastMemoryLevel = memFactor; 17826 mLastNumProcesses = mLruProcesses.size(); 17827 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17828 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17829 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17830 if (mLowRamStartTime == 0) { 17831 mLowRamStartTime = now; 17832 } 17833 int step = 0; 17834 int fgTrimLevel; 17835 switch (memFactor) { 17836 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17837 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17838 break; 17839 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17840 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17841 break; 17842 default: 17843 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17844 break; 17845 } 17846 int factor = numTrimming/3; 17847 int minFactor = 2; 17848 if (mHomeProcess != null) minFactor++; 17849 if (mPreviousProcess != null) minFactor++; 17850 if (factor < minFactor) factor = minFactor; 17851 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17852 for (int i=N-1; i>=0; i--) { 17853 ProcessRecord app = mLruProcesses.get(i); 17854 if (allChanged || app.procStateChanged) { 17855 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17856 app.procStateChanged = false; 17857 } 17858 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17859 && !app.killedByAm) { 17860 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17861 try { 17862 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17863 "Trimming memory of " + app.processName 17864 + " to " + curLevel); 17865 app.thread.scheduleTrimMemory(curLevel); 17866 } catch (RemoteException e) { 17867 } 17868 if (false) { 17869 // For now we won't do this; our memory trimming seems 17870 // to be good enough at this point that destroying 17871 // activities causes more harm than good. 17872 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17873 && app != mHomeProcess && app != mPreviousProcess) { 17874 // Need to do this on its own message because the stack may not 17875 // be in a consistent state at this point. 17876 // For these apps we will also finish their activities 17877 // to help them free memory. 17878 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17879 } 17880 } 17881 } 17882 app.trimMemoryLevel = curLevel; 17883 step++; 17884 if (step >= factor) { 17885 step = 0; 17886 switch (curLevel) { 17887 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17888 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17889 break; 17890 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17891 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17892 break; 17893 } 17894 } 17895 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17896 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17897 && app.thread != null) { 17898 try { 17899 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17900 "Trimming memory of heavy-weight " + app.processName 17901 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17902 app.thread.scheduleTrimMemory( 17903 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17904 } catch (RemoteException e) { 17905 } 17906 } 17907 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17908 } else { 17909 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17910 || app.systemNoUi) && app.pendingUiClean) { 17911 // If this application is now in the background and it 17912 // had done UI, then give it the special trim level to 17913 // have it free UI resources. 17914 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17915 if (app.trimMemoryLevel < level && app.thread != null) { 17916 try { 17917 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17918 "Trimming memory of bg-ui " + app.processName 17919 + " to " + level); 17920 app.thread.scheduleTrimMemory(level); 17921 } catch (RemoteException e) { 17922 } 17923 } 17924 app.pendingUiClean = false; 17925 } 17926 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17927 try { 17928 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17929 "Trimming memory of fg " + app.processName 17930 + " to " + fgTrimLevel); 17931 app.thread.scheduleTrimMemory(fgTrimLevel); 17932 } catch (RemoteException e) { 17933 } 17934 } 17935 app.trimMemoryLevel = fgTrimLevel; 17936 } 17937 } 17938 } else { 17939 if (mLowRamStartTime != 0) { 17940 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17941 mLowRamStartTime = 0; 17942 } 17943 for (int i=N-1; i>=0; i--) { 17944 ProcessRecord app = mLruProcesses.get(i); 17945 if (allChanged || app.procStateChanged) { 17946 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17947 app.procStateChanged = false; 17948 } 17949 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17950 || app.systemNoUi) && app.pendingUiClean) { 17951 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17952 && app.thread != null) { 17953 try { 17954 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17955 "Trimming memory of ui hidden " + app.processName 17956 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17957 app.thread.scheduleTrimMemory( 17958 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17959 } catch (RemoteException e) { 17960 } 17961 } 17962 app.pendingUiClean = false; 17963 } 17964 app.trimMemoryLevel = 0; 17965 } 17966 } 17967 17968 if (mAlwaysFinishActivities) { 17969 // Need to do this on its own message because the stack may not 17970 // be in a consistent state at this point. 17971 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17972 } 17973 17974 if (allChanged) { 17975 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17976 } 17977 17978 if (mProcessStats.shouldWriteNowLocked(now)) { 17979 mHandler.post(new Runnable() { 17980 @Override public void run() { 17981 synchronized (ActivityManagerService.this) { 17982 mProcessStats.writeStateAsyncLocked(); 17983 } 17984 } 17985 }); 17986 } 17987 17988 if (DEBUG_OOM_ADJ) { 17989 if (false) { 17990 RuntimeException here = new RuntimeException("here"); 17991 here.fillInStackTrace(); 17992 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17993 } else { 17994 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17995 } 17996 } 17997 } 17998 17999 final void trimApplications() { 18000 synchronized (this) { 18001 int i; 18002 18003 // First remove any unused application processes whose package 18004 // has been removed. 18005 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18006 final ProcessRecord app = mRemovedProcesses.get(i); 18007 if (app.activities.size() == 0 18008 && app.curReceiver == null && app.services.size() == 0) { 18009 Slog.i( 18010 TAG, "Exiting empty application process " 18011 + app.processName + " (" 18012 + (app.thread != null ? app.thread.asBinder() : null) 18013 + ")\n"); 18014 if (app.pid > 0 && app.pid != MY_PID) { 18015 app.kill("empty", false); 18016 } else { 18017 try { 18018 app.thread.scheduleExit(); 18019 } catch (Exception e) { 18020 // Ignore exceptions. 18021 } 18022 } 18023 cleanUpApplicationRecordLocked(app, false, true, -1); 18024 mRemovedProcesses.remove(i); 18025 18026 if (app.persistent) { 18027 addAppLocked(app.info, false, null /* ABI override */); 18028 } 18029 } 18030 } 18031 18032 // Now update the oom adj for all processes. 18033 updateOomAdjLocked(); 18034 } 18035 } 18036 18037 /** This method sends the specified signal to each of the persistent apps */ 18038 public void signalPersistentProcesses(int sig) throws RemoteException { 18039 if (sig != Process.SIGNAL_USR1) { 18040 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18041 } 18042 18043 synchronized (this) { 18044 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18045 != PackageManager.PERMISSION_GRANTED) { 18046 throw new SecurityException("Requires permission " 18047 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18048 } 18049 18050 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18051 ProcessRecord r = mLruProcesses.get(i); 18052 if (r.thread != null && r.persistent) { 18053 Process.sendSignal(r.pid, sig); 18054 } 18055 } 18056 } 18057 } 18058 18059 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18060 if (proc == null || proc == mProfileProc) { 18061 proc = mProfileProc; 18062 profileType = mProfileType; 18063 clearProfilerLocked(); 18064 } 18065 if (proc == null) { 18066 return; 18067 } 18068 try { 18069 proc.thread.profilerControl(false, null, profileType); 18070 } catch (RemoteException e) { 18071 throw new IllegalStateException("Process disappeared"); 18072 } 18073 } 18074 18075 private void clearProfilerLocked() { 18076 if (mProfileFd != null) { 18077 try { 18078 mProfileFd.close(); 18079 } catch (IOException e) { 18080 } 18081 } 18082 mProfileApp = null; 18083 mProfileProc = null; 18084 mProfileFile = null; 18085 mProfileType = 0; 18086 mAutoStopProfiler = false; 18087 mSamplingInterval = 0; 18088 } 18089 18090 public boolean profileControl(String process, int userId, boolean start, 18091 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18092 18093 try { 18094 synchronized (this) { 18095 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18096 // its own permission. 18097 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18098 != PackageManager.PERMISSION_GRANTED) { 18099 throw new SecurityException("Requires permission " 18100 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18101 } 18102 18103 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18104 throw new IllegalArgumentException("null profile info or fd"); 18105 } 18106 18107 ProcessRecord proc = null; 18108 if (process != null) { 18109 proc = findProcessLocked(process, userId, "profileControl"); 18110 } 18111 18112 if (start && (proc == null || proc.thread == null)) { 18113 throw new IllegalArgumentException("Unknown process: " + process); 18114 } 18115 18116 if (start) { 18117 stopProfilerLocked(null, 0); 18118 setProfileApp(proc.info, proc.processName, profilerInfo); 18119 mProfileProc = proc; 18120 mProfileType = profileType; 18121 ParcelFileDescriptor fd = profilerInfo.profileFd; 18122 try { 18123 fd = fd.dup(); 18124 } catch (IOException e) { 18125 fd = null; 18126 } 18127 profilerInfo.profileFd = fd; 18128 proc.thread.profilerControl(start, profilerInfo, profileType); 18129 fd = null; 18130 mProfileFd = null; 18131 } else { 18132 stopProfilerLocked(proc, profileType); 18133 if (profilerInfo != null && profilerInfo.profileFd != null) { 18134 try { 18135 profilerInfo.profileFd.close(); 18136 } catch (IOException e) { 18137 } 18138 } 18139 } 18140 18141 return true; 18142 } 18143 } catch (RemoteException e) { 18144 throw new IllegalStateException("Process disappeared"); 18145 } finally { 18146 if (profilerInfo != null && profilerInfo.profileFd != null) { 18147 try { 18148 profilerInfo.profileFd.close(); 18149 } catch (IOException e) { 18150 } 18151 } 18152 } 18153 } 18154 18155 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18156 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18157 userId, true, ALLOW_FULL_ONLY, callName, null); 18158 ProcessRecord proc = null; 18159 try { 18160 int pid = Integer.parseInt(process); 18161 synchronized (mPidsSelfLocked) { 18162 proc = mPidsSelfLocked.get(pid); 18163 } 18164 } catch (NumberFormatException e) { 18165 } 18166 18167 if (proc == null) { 18168 ArrayMap<String, SparseArray<ProcessRecord>> all 18169 = mProcessNames.getMap(); 18170 SparseArray<ProcessRecord> procs = all.get(process); 18171 if (procs != null && procs.size() > 0) { 18172 proc = procs.valueAt(0); 18173 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18174 for (int i=1; i<procs.size(); i++) { 18175 ProcessRecord thisProc = procs.valueAt(i); 18176 if (thisProc.userId == userId) { 18177 proc = thisProc; 18178 break; 18179 } 18180 } 18181 } 18182 } 18183 } 18184 18185 return proc; 18186 } 18187 18188 public boolean dumpHeap(String process, int userId, boolean managed, 18189 String path, ParcelFileDescriptor fd) throws RemoteException { 18190 18191 try { 18192 synchronized (this) { 18193 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18194 // its own permission (same as profileControl). 18195 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18196 != PackageManager.PERMISSION_GRANTED) { 18197 throw new SecurityException("Requires permission " 18198 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18199 } 18200 18201 if (fd == null) { 18202 throw new IllegalArgumentException("null fd"); 18203 } 18204 18205 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18206 if (proc == null || proc.thread == null) { 18207 throw new IllegalArgumentException("Unknown process: " + process); 18208 } 18209 18210 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18211 if (!isDebuggable) { 18212 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18213 throw new SecurityException("Process not debuggable: " + proc); 18214 } 18215 } 18216 18217 proc.thread.dumpHeap(managed, path, fd); 18218 fd = null; 18219 return true; 18220 } 18221 } catch (RemoteException e) { 18222 throw new IllegalStateException("Process disappeared"); 18223 } finally { 18224 if (fd != null) { 18225 try { 18226 fd.close(); 18227 } catch (IOException e) { 18228 } 18229 } 18230 } 18231 } 18232 18233 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18234 public void monitor() { 18235 synchronized (this) { } 18236 } 18237 18238 void onCoreSettingsChange(Bundle settings) { 18239 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18240 ProcessRecord processRecord = mLruProcesses.get(i); 18241 try { 18242 if (processRecord.thread != null) { 18243 processRecord.thread.setCoreSettings(settings); 18244 } 18245 } catch (RemoteException re) { 18246 /* ignore */ 18247 } 18248 } 18249 } 18250 18251 // Multi-user methods 18252 18253 /** 18254 * Start user, if its not already running, but don't bring it to foreground. 18255 */ 18256 @Override 18257 public boolean startUserInBackground(final int userId) { 18258 return startUser(userId, /* foreground */ false); 18259 } 18260 18261 /** 18262 * Start user, if its not already running, and bring it to foreground. 18263 */ 18264 boolean startUserInForeground(final int userId, Dialog dlg) { 18265 boolean result = startUser(userId, /* foreground */ true); 18266 dlg.dismiss(); 18267 return result; 18268 } 18269 18270 /** 18271 * Refreshes the list of users related to the current user when either a 18272 * user switch happens or when a new related user is started in the 18273 * background. 18274 */ 18275 private void updateCurrentProfileIdsLocked() { 18276 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18277 mCurrentUserId, false /* enabledOnly */); 18278 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18279 for (int i = 0; i < currentProfileIds.length; i++) { 18280 currentProfileIds[i] = profiles.get(i).id; 18281 } 18282 mCurrentProfileIds = currentProfileIds; 18283 18284 synchronized (mUserProfileGroupIdsSelfLocked) { 18285 mUserProfileGroupIdsSelfLocked.clear(); 18286 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18287 for (int i = 0; i < users.size(); i++) { 18288 UserInfo user = users.get(i); 18289 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18290 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18291 } 18292 } 18293 } 18294 } 18295 18296 private Set getProfileIdsLocked(int userId) { 18297 Set userIds = new HashSet<Integer>(); 18298 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18299 userId, false /* enabledOnly */); 18300 for (UserInfo user : profiles) { 18301 userIds.add(Integer.valueOf(user.id)); 18302 } 18303 return userIds; 18304 } 18305 18306 @Override 18307 public boolean switchUser(final int userId) { 18308 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18309 String userName; 18310 synchronized (this) { 18311 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18312 if (userInfo == null) { 18313 Slog.w(TAG, "No user info for user #" + userId); 18314 return false; 18315 } 18316 if (userInfo.isManagedProfile()) { 18317 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18318 return false; 18319 } 18320 userName = userInfo.name; 18321 mTargetUserId = userId; 18322 } 18323 mHandler.removeMessages(START_USER_SWITCH_MSG); 18324 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18325 return true; 18326 } 18327 18328 private void showUserSwitchDialog(int userId, String userName) { 18329 // The dialog will show and then initiate the user switch by calling startUserInForeground 18330 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18331 true /* above system */); 18332 d.show(); 18333 } 18334 18335 private boolean startUser(final int userId, final boolean foreground) { 18336 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18337 != PackageManager.PERMISSION_GRANTED) { 18338 String msg = "Permission Denial: switchUser() from pid=" 18339 + Binder.getCallingPid() 18340 + ", uid=" + Binder.getCallingUid() 18341 + " requires " + INTERACT_ACROSS_USERS_FULL; 18342 Slog.w(TAG, msg); 18343 throw new SecurityException(msg); 18344 } 18345 18346 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18347 18348 final long ident = Binder.clearCallingIdentity(); 18349 try { 18350 synchronized (this) { 18351 final int oldUserId = mCurrentUserId; 18352 if (oldUserId == userId) { 18353 return true; 18354 } 18355 18356 mStackSupervisor.setLockTaskModeLocked(null, false); 18357 18358 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18359 if (userInfo == null) { 18360 Slog.w(TAG, "No user info for user #" + userId); 18361 return false; 18362 } 18363 if (foreground && userInfo.isManagedProfile()) { 18364 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18365 return false; 18366 } 18367 18368 if (foreground) { 18369 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18370 R.anim.screen_user_enter); 18371 } 18372 18373 boolean needStart = false; 18374 18375 // If the user we are switching to is not currently started, then 18376 // we need to start it now. 18377 if (mStartedUsers.get(userId) == null) { 18378 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18379 updateStartedUserArrayLocked(); 18380 needStart = true; 18381 } 18382 18383 final Integer userIdInt = Integer.valueOf(userId); 18384 mUserLru.remove(userIdInt); 18385 mUserLru.add(userIdInt); 18386 18387 if (foreground) { 18388 mCurrentUserId = userId; 18389 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18390 updateCurrentProfileIdsLocked(); 18391 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18392 // Once the internal notion of the active user has switched, we lock the device 18393 // with the option to show the user switcher on the keyguard. 18394 mWindowManager.lockNow(null); 18395 } else { 18396 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18397 updateCurrentProfileIdsLocked(); 18398 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18399 mUserLru.remove(currentUserIdInt); 18400 mUserLru.add(currentUserIdInt); 18401 } 18402 18403 final UserStartedState uss = mStartedUsers.get(userId); 18404 18405 // Make sure user is in the started state. If it is currently 18406 // stopping, we need to knock that off. 18407 if (uss.mState == UserStartedState.STATE_STOPPING) { 18408 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18409 // so we can just fairly silently bring the user back from 18410 // the almost-dead. 18411 uss.mState = UserStartedState.STATE_RUNNING; 18412 updateStartedUserArrayLocked(); 18413 needStart = true; 18414 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18415 // This means ACTION_SHUTDOWN has been sent, so we will 18416 // need to treat this as a new boot of the user. 18417 uss.mState = UserStartedState.STATE_BOOTING; 18418 updateStartedUserArrayLocked(); 18419 needStart = true; 18420 } 18421 18422 if (uss.mState == UserStartedState.STATE_BOOTING) { 18423 // Booting up a new user, need to tell system services about it. 18424 // Note that this is on the same handler as scheduling of broadcasts, 18425 // which is important because it needs to go first. 18426 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18427 } 18428 18429 if (foreground) { 18430 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18431 oldUserId)); 18432 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18433 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18434 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18435 oldUserId, userId, uss)); 18436 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18437 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18438 } 18439 18440 if (needStart) { 18441 // Send USER_STARTED broadcast 18442 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18443 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18444 | Intent.FLAG_RECEIVER_FOREGROUND); 18445 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18446 broadcastIntentLocked(null, null, intent, 18447 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18448 false, false, MY_PID, Process.SYSTEM_UID, userId); 18449 } 18450 18451 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18452 if (userId != UserHandle.USER_OWNER) { 18453 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18454 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18455 broadcastIntentLocked(null, null, intent, null, 18456 new IIntentReceiver.Stub() { 18457 public void performReceive(Intent intent, int resultCode, 18458 String data, Bundle extras, boolean ordered, 18459 boolean sticky, int sendingUser) { 18460 onUserInitialized(uss, foreground, oldUserId, userId); 18461 } 18462 }, 0, null, null, null, AppOpsManager.OP_NONE, 18463 true, false, MY_PID, Process.SYSTEM_UID, 18464 userId); 18465 uss.initializing = true; 18466 } else { 18467 getUserManagerLocked().makeInitialized(userInfo.id); 18468 } 18469 } 18470 18471 if (foreground) { 18472 if (!uss.initializing) { 18473 moveUserToForeground(uss, oldUserId, userId); 18474 } 18475 } else { 18476 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18477 } 18478 18479 if (needStart) { 18480 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18481 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18482 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18483 broadcastIntentLocked(null, null, intent, 18484 null, new IIntentReceiver.Stub() { 18485 @Override 18486 public void performReceive(Intent intent, int resultCode, String data, 18487 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18488 throws RemoteException { 18489 } 18490 }, 0, null, null, 18491 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18492 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18493 } 18494 } 18495 } finally { 18496 Binder.restoreCallingIdentity(ident); 18497 } 18498 18499 return true; 18500 } 18501 18502 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18503 long ident = Binder.clearCallingIdentity(); 18504 try { 18505 Intent intent; 18506 if (oldUserId >= 0) { 18507 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18508 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18509 int count = profiles.size(); 18510 for (int i = 0; i < count; i++) { 18511 int profileUserId = profiles.get(i).id; 18512 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18513 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18514 | Intent.FLAG_RECEIVER_FOREGROUND); 18515 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18516 broadcastIntentLocked(null, null, intent, 18517 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18518 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18519 } 18520 } 18521 if (newUserId >= 0) { 18522 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18523 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18524 int count = profiles.size(); 18525 for (int i = 0; i < count; i++) { 18526 int profileUserId = profiles.get(i).id; 18527 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18528 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18529 | Intent.FLAG_RECEIVER_FOREGROUND); 18530 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18531 broadcastIntentLocked(null, null, intent, 18532 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18533 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18534 } 18535 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18536 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18537 | Intent.FLAG_RECEIVER_FOREGROUND); 18538 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18539 broadcastIntentLocked(null, null, intent, 18540 null, null, 0, null, null, 18541 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18542 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18543 } 18544 } finally { 18545 Binder.restoreCallingIdentity(ident); 18546 } 18547 } 18548 18549 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18550 final int newUserId) { 18551 final int N = mUserSwitchObservers.beginBroadcast(); 18552 if (N > 0) { 18553 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18554 int mCount = 0; 18555 @Override 18556 public void sendResult(Bundle data) throws RemoteException { 18557 synchronized (ActivityManagerService.this) { 18558 if (mCurUserSwitchCallback == this) { 18559 mCount++; 18560 if (mCount == N) { 18561 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18562 } 18563 } 18564 } 18565 } 18566 }; 18567 synchronized (this) { 18568 uss.switching = true; 18569 mCurUserSwitchCallback = callback; 18570 } 18571 for (int i=0; i<N; i++) { 18572 try { 18573 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18574 newUserId, callback); 18575 } catch (RemoteException e) { 18576 } 18577 } 18578 } else { 18579 synchronized (this) { 18580 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18581 } 18582 } 18583 mUserSwitchObservers.finishBroadcast(); 18584 } 18585 18586 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18587 synchronized (this) { 18588 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18589 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18590 } 18591 } 18592 18593 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18594 mCurUserSwitchCallback = null; 18595 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18596 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18597 oldUserId, newUserId, uss)); 18598 } 18599 18600 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18601 synchronized (this) { 18602 if (foreground) { 18603 moveUserToForeground(uss, oldUserId, newUserId); 18604 } 18605 } 18606 18607 completeSwitchAndInitalize(uss, newUserId, true, false); 18608 } 18609 18610 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18611 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18612 if (homeInFront) { 18613 startHomeActivityLocked(newUserId); 18614 } else { 18615 mStackSupervisor.resumeTopActivitiesLocked(); 18616 } 18617 EventLogTags.writeAmSwitchUser(newUserId); 18618 getUserManagerLocked().userForeground(newUserId); 18619 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18620 } 18621 18622 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18623 completeSwitchAndInitalize(uss, newUserId, false, true); 18624 } 18625 18626 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18627 boolean clearInitializing, boolean clearSwitching) { 18628 boolean unfrozen = false; 18629 synchronized (this) { 18630 if (clearInitializing) { 18631 uss.initializing = false; 18632 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18633 } 18634 if (clearSwitching) { 18635 uss.switching = false; 18636 } 18637 if (!uss.switching && !uss.initializing) { 18638 mWindowManager.stopFreezingScreen(); 18639 unfrozen = true; 18640 } 18641 } 18642 if (unfrozen) { 18643 final int N = mUserSwitchObservers.beginBroadcast(); 18644 for (int i=0; i<N; i++) { 18645 try { 18646 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18647 } catch (RemoteException e) { 18648 } 18649 } 18650 mUserSwitchObservers.finishBroadcast(); 18651 } 18652 } 18653 18654 void scheduleStartProfilesLocked() { 18655 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18656 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18657 DateUtils.SECOND_IN_MILLIS); 18658 } 18659 } 18660 18661 void startProfilesLocked() { 18662 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18663 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18664 mCurrentUserId, false /* enabledOnly */); 18665 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18666 for (UserInfo user : profiles) { 18667 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18668 && user.id != mCurrentUserId) { 18669 toStart.add(user); 18670 } 18671 } 18672 final int n = toStart.size(); 18673 int i = 0; 18674 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18675 startUserInBackground(toStart.get(i).id); 18676 } 18677 if (i < n) { 18678 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18679 } 18680 } 18681 18682 void finishUserBoot(UserStartedState uss) { 18683 synchronized (this) { 18684 if (uss.mState == UserStartedState.STATE_BOOTING 18685 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18686 uss.mState = UserStartedState.STATE_RUNNING; 18687 final int userId = uss.mHandle.getIdentifier(); 18688 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18689 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18690 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18691 broadcastIntentLocked(null, null, intent, 18692 null, null, 0, null, null, 18693 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18694 true, false, MY_PID, Process.SYSTEM_UID, userId); 18695 } 18696 } 18697 } 18698 18699 void finishUserSwitch(UserStartedState uss) { 18700 synchronized (this) { 18701 finishUserBoot(uss); 18702 18703 startProfilesLocked(); 18704 18705 int num = mUserLru.size(); 18706 int i = 0; 18707 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18708 Integer oldUserId = mUserLru.get(i); 18709 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18710 if (oldUss == null) { 18711 // Shouldn't happen, but be sane if it does. 18712 mUserLru.remove(i); 18713 num--; 18714 continue; 18715 } 18716 if (oldUss.mState == UserStartedState.STATE_STOPPING 18717 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18718 // This user is already stopping, doesn't count. 18719 num--; 18720 i++; 18721 continue; 18722 } 18723 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18724 // Owner and current can't be stopped, but count as running. 18725 i++; 18726 continue; 18727 } 18728 // This is a user to be stopped. 18729 stopUserLocked(oldUserId, null); 18730 num--; 18731 i++; 18732 } 18733 } 18734 } 18735 18736 @Override 18737 public int stopUser(final int userId, final IStopUserCallback callback) { 18738 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18739 != PackageManager.PERMISSION_GRANTED) { 18740 String msg = "Permission Denial: switchUser() from pid=" 18741 + Binder.getCallingPid() 18742 + ", uid=" + Binder.getCallingUid() 18743 + " requires " + INTERACT_ACROSS_USERS_FULL; 18744 Slog.w(TAG, msg); 18745 throw new SecurityException(msg); 18746 } 18747 if (userId <= 0) { 18748 throw new IllegalArgumentException("Can't stop primary user " + userId); 18749 } 18750 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18751 synchronized (this) { 18752 return stopUserLocked(userId, callback); 18753 } 18754 } 18755 18756 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18757 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18758 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18759 return ActivityManager.USER_OP_IS_CURRENT; 18760 } 18761 18762 final UserStartedState uss = mStartedUsers.get(userId); 18763 if (uss == null) { 18764 // User is not started, nothing to do... but we do need to 18765 // callback if requested. 18766 if (callback != null) { 18767 mHandler.post(new Runnable() { 18768 @Override 18769 public void run() { 18770 try { 18771 callback.userStopped(userId); 18772 } catch (RemoteException e) { 18773 } 18774 } 18775 }); 18776 } 18777 return ActivityManager.USER_OP_SUCCESS; 18778 } 18779 18780 if (callback != null) { 18781 uss.mStopCallbacks.add(callback); 18782 } 18783 18784 if (uss.mState != UserStartedState.STATE_STOPPING 18785 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18786 uss.mState = UserStartedState.STATE_STOPPING; 18787 updateStartedUserArrayLocked(); 18788 18789 long ident = Binder.clearCallingIdentity(); 18790 try { 18791 // We are going to broadcast ACTION_USER_STOPPING and then 18792 // once that is done send a final ACTION_SHUTDOWN and then 18793 // stop the user. 18794 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18795 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18796 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18797 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18798 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18799 // This is the result receiver for the final shutdown broadcast. 18800 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18801 @Override 18802 public void performReceive(Intent intent, int resultCode, String data, 18803 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18804 finishUserStop(uss); 18805 } 18806 }; 18807 // This is the result receiver for the initial stopping broadcast. 18808 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18809 @Override 18810 public void performReceive(Intent intent, int resultCode, String data, 18811 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18812 // On to the next. 18813 synchronized (ActivityManagerService.this) { 18814 if (uss.mState != UserStartedState.STATE_STOPPING) { 18815 // Whoops, we are being started back up. Abort, abort! 18816 return; 18817 } 18818 uss.mState = UserStartedState.STATE_SHUTDOWN; 18819 } 18820 mBatteryStatsService.noteEvent( 18821 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18822 Integer.toString(userId), userId); 18823 mSystemServiceManager.stopUser(userId); 18824 broadcastIntentLocked(null, null, shutdownIntent, 18825 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18826 true, false, MY_PID, Process.SYSTEM_UID, userId); 18827 } 18828 }; 18829 // Kick things off. 18830 broadcastIntentLocked(null, null, stoppingIntent, 18831 null, stoppingReceiver, 0, null, null, 18832 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18833 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18834 } finally { 18835 Binder.restoreCallingIdentity(ident); 18836 } 18837 } 18838 18839 return ActivityManager.USER_OP_SUCCESS; 18840 } 18841 18842 void finishUserStop(UserStartedState uss) { 18843 final int userId = uss.mHandle.getIdentifier(); 18844 boolean stopped; 18845 ArrayList<IStopUserCallback> callbacks; 18846 synchronized (this) { 18847 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18848 if (mStartedUsers.get(userId) != uss) { 18849 stopped = false; 18850 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18851 stopped = false; 18852 } else { 18853 stopped = true; 18854 // User can no longer run. 18855 mStartedUsers.remove(userId); 18856 mUserLru.remove(Integer.valueOf(userId)); 18857 updateStartedUserArrayLocked(); 18858 18859 // Clean up all state and processes associated with the user. 18860 // Kill all the processes for the user. 18861 forceStopUserLocked(userId, "finish user"); 18862 } 18863 18864 // Explicitly remove the old information in mRecentTasks. 18865 removeRecentTasksForUserLocked(userId); 18866 } 18867 18868 for (int i=0; i<callbacks.size(); i++) { 18869 try { 18870 if (stopped) callbacks.get(i).userStopped(userId); 18871 else callbacks.get(i).userStopAborted(userId); 18872 } catch (RemoteException e) { 18873 } 18874 } 18875 18876 if (stopped) { 18877 mSystemServiceManager.cleanupUser(userId); 18878 synchronized (this) { 18879 mStackSupervisor.removeUserLocked(userId); 18880 } 18881 } 18882 } 18883 18884 @Override 18885 public UserInfo getCurrentUser() { 18886 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18887 != PackageManager.PERMISSION_GRANTED) && ( 18888 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18889 != PackageManager.PERMISSION_GRANTED)) { 18890 String msg = "Permission Denial: getCurrentUser() from pid=" 18891 + Binder.getCallingPid() 18892 + ", uid=" + Binder.getCallingUid() 18893 + " requires " + INTERACT_ACROSS_USERS; 18894 Slog.w(TAG, msg); 18895 throw new SecurityException(msg); 18896 } 18897 synchronized (this) { 18898 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18899 return getUserManagerLocked().getUserInfo(userId); 18900 } 18901 } 18902 18903 int getCurrentUserIdLocked() { 18904 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18905 } 18906 18907 @Override 18908 public boolean isUserRunning(int userId, boolean orStopped) { 18909 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18910 != PackageManager.PERMISSION_GRANTED) { 18911 String msg = "Permission Denial: isUserRunning() from pid=" 18912 + Binder.getCallingPid() 18913 + ", uid=" + Binder.getCallingUid() 18914 + " requires " + INTERACT_ACROSS_USERS; 18915 Slog.w(TAG, msg); 18916 throw new SecurityException(msg); 18917 } 18918 synchronized (this) { 18919 return isUserRunningLocked(userId, orStopped); 18920 } 18921 } 18922 18923 boolean isUserRunningLocked(int userId, boolean orStopped) { 18924 UserStartedState state = mStartedUsers.get(userId); 18925 if (state == null) { 18926 return false; 18927 } 18928 if (orStopped) { 18929 return true; 18930 } 18931 return state.mState != UserStartedState.STATE_STOPPING 18932 && state.mState != UserStartedState.STATE_SHUTDOWN; 18933 } 18934 18935 @Override 18936 public int[] getRunningUserIds() { 18937 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18938 != PackageManager.PERMISSION_GRANTED) { 18939 String msg = "Permission Denial: isUserRunning() from pid=" 18940 + Binder.getCallingPid() 18941 + ", uid=" + Binder.getCallingUid() 18942 + " requires " + INTERACT_ACROSS_USERS; 18943 Slog.w(TAG, msg); 18944 throw new SecurityException(msg); 18945 } 18946 synchronized (this) { 18947 return mStartedUserArray; 18948 } 18949 } 18950 18951 private void updateStartedUserArrayLocked() { 18952 int num = 0; 18953 for (int i=0; i<mStartedUsers.size(); i++) { 18954 UserStartedState uss = mStartedUsers.valueAt(i); 18955 // This list does not include stopping users. 18956 if (uss.mState != UserStartedState.STATE_STOPPING 18957 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18958 num++; 18959 } 18960 } 18961 mStartedUserArray = new int[num]; 18962 num = 0; 18963 for (int i=0; i<mStartedUsers.size(); i++) { 18964 UserStartedState uss = mStartedUsers.valueAt(i); 18965 if (uss.mState != UserStartedState.STATE_STOPPING 18966 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18967 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18968 num++; 18969 } 18970 } 18971 } 18972 18973 @Override 18974 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18975 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18976 != PackageManager.PERMISSION_GRANTED) { 18977 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18978 + Binder.getCallingPid() 18979 + ", uid=" + Binder.getCallingUid() 18980 + " requires " + INTERACT_ACROSS_USERS_FULL; 18981 Slog.w(TAG, msg); 18982 throw new SecurityException(msg); 18983 } 18984 18985 mUserSwitchObservers.register(observer); 18986 } 18987 18988 @Override 18989 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18990 mUserSwitchObservers.unregister(observer); 18991 } 18992 18993 private boolean userExists(int userId) { 18994 if (userId == 0) { 18995 return true; 18996 } 18997 UserManagerService ums = getUserManagerLocked(); 18998 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18999 } 19000 19001 int[] getUsersLocked() { 19002 UserManagerService ums = getUserManagerLocked(); 19003 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19004 } 19005 19006 UserManagerService getUserManagerLocked() { 19007 if (mUserManager == null) { 19008 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19009 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19010 } 19011 return mUserManager; 19012 } 19013 19014 private int applyUserId(int uid, int userId) { 19015 return UserHandle.getUid(userId, uid); 19016 } 19017 19018 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19019 if (info == null) return null; 19020 ApplicationInfo newInfo = new ApplicationInfo(info); 19021 newInfo.uid = applyUserId(info.uid, userId); 19022 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19023 + info.packageName; 19024 return newInfo; 19025 } 19026 19027 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19028 if (aInfo == null 19029 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19030 return aInfo; 19031 } 19032 19033 ActivityInfo info = new ActivityInfo(aInfo); 19034 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19035 return info; 19036 } 19037 19038 private final class LocalService extends ActivityManagerInternal { 19039 @Override 19040 public void goingToSleep() { 19041 ActivityManagerService.this.goingToSleep(); 19042 } 19043 19044 @Override 19045 public void wakingUp() { 19046 ActivityManagerService.this.wakingUp(); 19047 } 19048 19049 @Override 19050 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19051 String processName, String abiOverride, int uid, Runnable crashHandler) { 19052 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19053 processName, abiOverride, uid, crashHandler); 19054 } 19055 } 19056 19057 /** 19058 * An implementation of IAppTask, that allows an app to manage its own tasks via 19059 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19060 * only the process that calls getAppTasks() can call the AppTask methods. 19061 */ 19062 class AppTaskImpl extends IAppTask.Stub { 19063 private int mTaskId; 19064 private int mCallingUid; 19065 19066 public AppTaskImpl(int taskId, int callingUid) { 19067 mTaskId = taskId; 19068 mCallingUid = callingUid; 19069 } 19070 19071 private void checkCaller() { 19072 if (mCallingUid != Binder.getCallingUid()) { 19073 throw new SecurityException("Caller " + mCallingUid 19074 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19075 } 19076 } 19077 19078 @Override 19079 public void finishAndRemoveTask() { 19080 checkCaller(); 19081 19082 synchronized (ActivityManagerService.this) { 19083 long origId = Binder.clearCallingIdentity(); 19084 try { 19085 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19086 if (tr == null) { 19087 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19088 } 19089 // Only kill the process if we are not a new document 19090 int flags = tr.getBaseIntent().getFlags(); 19091 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19092 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19093 removeTaskByIdLocked(mTaskId, 19094 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19095 } finally { 19096 Binder.restoreCallingIdentity(origId); 19097 } 19098 } 19099 } 19100 19101 @Override 19102 public ActivityManager.RecentTaskInfo getTaskInfo() { 19103 checkCaller(); 19104 19105 synchronized (ActivityManagerService.this) { 19106 long origId = Binder.clearCallingIdentity(); 19107 try { 19108 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19109 if (tr == null) { 19110 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19111 } 19112 return createRecentTaskInfoFromTaskRecord(tr); 19113 } finally { 19114 Binder.restoreCallingIdentity(origId); 19115 } 19116 } 19117 } 19118 19119 @Override 19120 public void moveToFront() { 19121 checkCaller(); 19122 19123 final TaskRecord tr; 19124 synchronized (ActivityManagerService.this) { 19125 tr = recentTaskForIdLocked(mTaskId); 19126 if (tr == null) { 19127 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19128 } 19129 if (tr.getRootActivity() != null) { 19130 moveTaskToFrontLocked(tr.taskId, 0, null); 19131 return; 19132 } 19133 } 19134 19135 startActivityFromRecentsInner(tr.taskId, null); 19136 } 19137 19138 @Override 19139 public int startActivity(IBinder whoThread, String callingPackage, 19140 Intent intent, String resolvedType, Bundle options) { 19141 checkCaller(); 19142 19143 int callingUser = UserHandle.getCallingUserId(); 19144 TaskRecord tr; 19145 IApplicationThread appThread; 19146 synchronized (ActivityManagerService.this) { 19147 tr = recentTaskForIdLocked(mTaskId); 19148 if (tr == null) { 19149 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19150 } 19151 appThread = ApplicationThreadNative.asInterface(whoThread); 19152 if (appThread == null) { 19153 throw new IllegalArgumentException("Bad app thread " + appThread); 19154 } 19155 } 19156 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19157 resolvedType, null, null, null, null, 0, 0, null, null, 19158 null, options, callingUser, null, tr); 19159 } 19160 19161 @Override 19162 public void setExcludeFromRecents(boolean exclude) { 19163 checkCaller(); 19164 19165 synchronized (ActivityManagerService.this) { 19166 long origId = Binder.clearCallingIdentity(); 19167 try { 19168 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19169 if (tr == null) { 19170 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19171 } 19172 Intent intent = tr.getBaseIntent(); 19173 if (exclude) { 19174 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19175 } else { 19176 intent.setFlags(intent.getFlags() 19177 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19178 } 19179 } finally { 19180 Binder.restoreCallingIdentity(origId); 19181 } 19182 } 19183 } 19184 } 19185} 19186