ActivityManagerService.java revision b3d4cb369e37b1b7e85832cc035226dc7cc8f380
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; 33import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35import android.Manifest; 36import android.app.AppOpsManager; 37import android.app.ApplicationThreadNative; 38import android.app.IActivityContainer; 39import android.app.IActivityContainerCallback; 40import android.app.IAppTask; 41import android.app.ITaskStackListener; 42import android.app.ProfilerInfo; 43import android.app.admin.DevicePolicyManager; 44import android.app.usage.UsageEvents; 45import android.app.usage.UsageStatsManagerInternal; 46import android.appwidget.AppWidgetManager; 47import android.content.res.Resources; 48import android.graphics.Bitmap; 49import android.graphics.Point; 50import android.graphics.Rect; 51import android.os.BatteryStats; 52import android.os.PersistableBundle; 53import android.os.storage.IMountService; 54import android.os.storage.StorageManager; 55import android.service.voice.IVoiceInteractionSession; 56import android.util.ArrayMap; 57import android.util.ArraySet; 58import android.util.SparseIntArray; 59 60import com.android.internal.R; 61import com.android.internal.annotations.GuardedBy; 62import com.android.internal.app.IAppOpsService; 63import com.android.internal.app.IVoiceInteractor; 64import com.android.internal.app.ProcessMap; 65import com.android.internal.app.ProcessStats; 66import com.android.internal.os.BackgroundThread; 67import com.android.internal.os.BatteryStatsImpl; 68import com.android.internal.os.ProcessCpuTracker; 69import com.android.internal.os.TransferPipe; 70import com.android.internal.os.Zygote; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.MemInfoReader; 74import com.android.internal.util.Preconditions; 75import com.android.server.AppOpsService; 76import com.android.server.AttributeCache; 77import com.android.server.IntentResolver; 78import com.android.server.LocalServices; 79import com.android.server.ServiceThread; 80import com.android.server.SystemService; 81import com.android.server.SystemServiceManager; 82import com.android.server.Watchdog; 83import com.android.server.am.ActivityStack.ActivityState; 84import com.android.server.firewall.IntentFirewall; 85import com.android.server.pm.Installer; 86import com.android.server.pm.UserManagerService; 87import com.android.server.statusbar.StatusBarManagerInternal; 88import com.android.server.wm.AppTransition; 89import com.android.server.wm.WindowManagerService; 90import com.google.android.collect.Lists; 91import com.google.android.collect.Maps; 92 93import libcore.io.IoUtils; 94 95import org.xmlpull.v1.XmlPullParser; 96import org.xmlpull.v1.XmlPullParserException; 97import org.xmlpull.v1.XmlSerializer; 98 99import android.app.Activity; 100import android.app.ActivityManager; 101import android.app.ActivityManager.RunningTaskInfo; 102import android.app.ActivityManager.StackInfo; 103import android.app.ActivityManagerInternal; 104import android.app.ActivityManagerNative; 105import android.app.ActivityOptions; 106import android.app.ActivityThread; 107import android.app.AlertDialog; 108import android.app.AppGlobals; 109import android.app.ApplicationErrorReport; 110import android.app.Dialog; 111import android.app.IActivityController; 112import android.app.IApplicationThread; 113import android.app.IInstrumentationWatcher; 114import android.app.INotificationManager; 115import android.app.IProcessObserver; 116import android.app.IServiceConnection; 117import android.app.IStopUserCallback; 118import android.app.IUiAutomationConnection; 119import android.app.IUserSwitchObserver; 120import android.app.Instrumentation; 121import android.app.Notification; 122import android.app.NotificationManager; 123import android.app.PendingIntent; 124import android.app.backup.IBackupManager; 125import android.content.ActivityNotFoundException; 126import android.content.BroadcastReceiver; 127import android.content.ClipData; 128import android.content.ComponentCallbacks2; 129import android.content.ComponentName; 130import android.content.ContentProvider; 131import android.content.ContentResolver; 132import android.content.Context; 133import android.content.DialogInterface; 134import android.content.IContentProvider; 135import android.content.IIntentReceiver; 136import android.content.IIntentSender; 137import android.content.Intent; 138import android.content.IntentFilter; 139import android.content.IntentSender; 140import android.content.pm.ActivityInfo; 141import android.content.pm.ApplicationInfo; 142import android.content.pm.ConfigurationInfo; 143import android.content.pm.IPackageDataObserver; 144import android.content.pm.IPackageManager; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.PackageInfo; 147import android.content.pm.PackageManager; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.UserInfo; 150import android.content.pm.PackageManager.NameNotFoundException; 151import android.content.pm.PathPermission; 152import android.content.pm.ProviderInfo; 153import android.content.pm.ResolveInfo; 154import android.content.pm.ServiceInfo; 155import android.content.res.CompatibilityInfo; 156import android.content.res.Configuration; 157import android.net.Proxy; 158import android.net.ProxyInfo; 159import android.net.Uri; 160import android.os.Binder; 161import android.os.Build; 162import android.os.Bundle; 163import android.os.Debug; 164import android.os.DropBoxManager; 165import android.os.Environment; 166import android.os.FactoryTest; 167import android.os.FileObserver; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.IPermissionController; 172import android.os.IRemoteCallback; 173import android.os.IUserManager; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.PowerManagerInternal; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.SELinux; 183import android.os.ServiceManager; 184import android.os.StrictMode; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.UpdateLock; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.provider.Settings; 191import android.text.format.DateUtils; 192import android.text.format.Time; 193import android.util.AtomicFile; 194import android.util.EventLog; 195import android.util.Log; 196import android.util.Pair; 197import android.util.PrintWriterPrinter; 198import android.util.Slog; 199import android.util.SparseArray; 200import android.util.TimeUtils; 201import android.util.Xml; 202import android.view.Gravity; 203import android.view.LayoutInflater; 204import android.view.View; 205import android.view.WindowManager; 206 207import dalvik.system.VMRuntime; 208 209import java.io.BufferedInputStream; 210import java.io.BufferedOutputStream; 211import java.io.DataInputStream; 212import java.io.DataOutputStream; 213import java.io.File; 214import java.io.FileDescriptor; 215import java.io.FileInputStream; 216import java.io.FileNotFoundException; 217import java.io.FileOutputStream; 218import java.io.IOException; 219import java.io.InputStreamReader; 220import java.io.PrintWriter; 221import java.io.StringWriter; 222import java.lang.ref.WeakReference; 223import java.util.ArrayList; 224import java.util.Arrays; 225import java.util.Collections; 226import java.util.Comparator; 227import java.util.HashMap; 228import java.util.HashSet; 229import java.util.Iterator; 230import java.util.List; 231import java.util.Locale; 232import java.util.Map; 233import java.util.Set; 234import java.util.concurrent.atomic.AtomicBoolean; 235import java.util.concurrent.atomic.AtomicLong; 236 237public final class ActivityManagerService extends ActivityManagerNative 238 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 239 240 private static final String USER_DATA_DIR = "/data/user/"; 241 // File that stores last updated system version and called preboot receivers 242 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 243 244 static final String TAG = "ActivityManager"; 245 static final String TAG_MU = "ActivityManagerServiceMU"; 246 static final boolean DEBUG = false; 247 static final boolean localLOGV = DEBUG; 248 static final boolean DEBUG_BACKUP = localLOGV || false; 249 static final boolean DEBUG_BROADCAST = localLOGV || false; 250 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_CLEANUP = localLOGV || false; 253 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 254 static final boolean DEBUG_FOCUS = false; 255 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 256 static final boolean DEBUG_MU = localLOGV || false; 257 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 258 static final boolean DEBUG_LRU = localLOGV || false; 259 static final boolean DEBUG_PAUSE = localLOGV || false; 260 static final boolean DEBUG_POWER = localLOGV || false; 261 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 262 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 263 static final boolean DEBUG_PROCESSES = localLOGV || false; 264 static final boolean DEBUG_PROVIDER = localLOGV || false; 265 static final boolean DEBUG_RESULTS = localLOGV || false; 266 static final boolean DEBUG_SERVICE = localLOGV || false; 267 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 268 static final boolean DEBUG_STACK = localLOGV || false; 269 static final boolean DEBUG_SWITCH = localLOGV || false; 270 static final boolean DEBUG_TASKS = localLOGV || false; 271 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 272 static final boolean DEBUG_TRANSITION = localLOGV || false; 273 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 274 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 275 static final boolean DEBUG_VISBILITY = localLOGV || false; 276 static final boolean DEBUG_PSS = localLOGV || false; 277 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 278 static final boolean DEBUG_RECENTS = localLOGV || false; 279 static final boolean VALIDATE_TOKENS = false; 280 static final boolean SHOW_ACTIVITY_START_TIME = true; 281 282 // Control over CPU and battery monitoring. 283 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 284 static final boolean MONITOR_CPU_USAGE = true; 285 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 286 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 287 static final boolean MONITOR_THREAD_CPU_USAGE = false; 288 289 // The flags that are set for all calls we make to the package manager. 290 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 291 292 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 293 294 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 295 296 // Maximum number recent bitmaps to keep in memory. 297 static final int MAX_RECENT_BITMAPS = 3; 298 299 // Amount of time after a call to stopAppSwitches() during which we will 300 // prevent further untrusted switches from happening. 301 static final long APP_SWITCH_DELAY_TIME = 5*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real. 305 static final int PROC_START_TIMEOUT = 10*1000; 306 307 // How long we wait for a launched process to attach to the activity manager 308 // before we decide it's never going to come up for real, when the process was 309 // started with a wrapper for instrumentation (such as Valgrind) because it 310 // could take much longer than usual. 311 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 312 313 // How long to wait after going idle before forcing apps to GC. 314 static final int GC_TIMEOUT = 5*1000; 315 316 // The minimum amount of time between successive GC requests for a process. 317 static final int GC_MIN_INTERVAL = 60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process. 320 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 321 322 // The minimum amount of time between successive PSS requests for a process 323 // when the request is due to the memory state being lowered. 324 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 325 326 // The rate at which we check for apps using excessive power -- 15 mins. 327 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on wake locks to start killing things. 331 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // The minimum sample duration we will allow before deciding we have 334 // enough data on CPU usage to start killing things. 335 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 336 337 // How long we allow a receiver to run before giving up on it. 338 static final int BROADCAST_FG_TIMEOUT = 10*1000; 339 static final int BROADCAST_BG_TIMEOUT = 60*1000; 340 341 // How long we wait until we timeout on key dispatching. 342 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 343 344 // How long we wait until we timeout on key dispatching during instrumentation. 345 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 346 347 // Amount of time we wait for observers to handle a user switch before 348 // giving up on them and unfreezing the screen. 349 static final int USER_SWITCH_TIMEOUT = 2*1000; 350 351 // Maximum number of users we allow to be running at a time. 352 static final int MAX_RUNNING_USERS = 3; 353 354 // How long to wait in getAssistContextExtras for the activity and foreground services 355 // to respond with the result. 356 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 357 358 // Maximum number of persisted Uri grants a package is allowed 359 static final int MAX_PERSISTED_URI_GRANTS = 128; 360 361 static final int MY_PID = Process.myPid(); 362 363 static final String[] EMPTY_STRING_ARRAY = new String[0]; 364 365 // How many bytes to write into the dropbox log before truncating 366 static final int DROPBOX_MAX_SIZE = 256 * 1024; 367 368 // Access modes for handleIncomingUser. 369 static final int ALLOW_NON_FULL = 0; 370 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 371 static final int ALLOW_FULL_ONLY = 2; 372 373 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 374 375 // Delay in notifying task stack change listeners (in millis) 376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 377 378 /** All system services */ 379 SystemServiceManager mSystemServiceManager; 380 381 private Installer mInstaller; 382 383 /** Run all ActivityStacks through this */ 384 ActivityStackSupervisor mStackSupervisor; 385 386 /** Task stack change listeners. */ 387 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 388 new RemoteCallbackList<ITaskStackListener>(); 389 390 public IntentFirewall mIntentFirewall; 391 392 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 393 // default actuion automatically. Important for devices without direct input 394 // devices. 395 private boolean mShowDialogs = true; 396 397 BroadcastQueue mFgBroadcastQueue; 398 BroadcastQueue mBgBroadcastQueue; 399 // Convenient for easy iteration over the queues. Foreground is first 400 // so that dispatch of foreground broadcasts gets precedence. 401 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 402 403 BroadcastQueue broadcastQueueForIntent(Intent intent) { 404 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 405 if (DEBUG_BACKGROUND_BROADCAST) { 406 Slog.i(TAG, "Broadcast intent " + intent + " on " 407 + (isFg ? "foreground" : "background") 408 + " queue"); 409 } 410 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 411 } 412 413 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 414 for (BroadcastQueue queue : mBroadcastQueues) { 415 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 416 if (r != null) { 417 return r; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Activity we have told the window manager to have key focus. 425 */ 426 ActivityRecord mFocusedActivity = null; 427 428 /** 429 * List of intents that were used to start the most recent tasks. 430 */ 431 ArrayList<TaskRecord> mRecentTasks; 432 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 433 434 /** 435 * For addAppTask: cached of the last activity component that was added. 436 */ 437 ComponentName mLastAddedTaskComponent; 438 439 /** 440 * For addAppTask: cached of the last activity uid that was added. 441 */ 442 int mLastAddedTaskUid; 443 444 /** 445 * For addAppTask: cached of the last ActivityInfo that was added. 446 */ 447 ActivityInfo mLastAddedTaskActivity; 448 449 public class PendingAssistExtras extends Binder implements Runnable { 450 public final ActivityRecord activity; 451 public final Bundle extras; 452 public final Intent intent; 453 public final String hint; 454 public final int userHandle; 455 public boolean haveResult = false; 456 public Bundle result = null; 457 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 458 String _hint, int _userHandle) { 459 activity = _activity; 460 extras = _extras; 461 intent = _intent; 462 hint = _hint; 463 userHandle = _userHandle; 464 } 465 @Override 466 public void run() { 467 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 468 synchronized (this) { 469 haveResult = true; 470 notifyAll(); 471 } 472 } 473 } 474 475 final ArrayList<PendingAssistExtras> mPendingAssistExtras 476 = new ArrayList<PendingAssistExtras>(); 477 478 /** 479 * Process management. 480 */ 481 final ProcessList mProcessList = new ProcessList(); 482 483 /** 484 * All of the applications we currently have running organized by name. 485 * The keys are strings of the application package name (as 486 * returned by the package manager), and the keys are ApplicationRecord 487 * objects. 488 */ 489 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 490 491 /** 492 * Tracking long-term execution of processes to look for abuse and other 493 * bad app behavior. 494 */ 495 final ProcessStatsService mProcessStats; 496 497 /** 498 * The currently running isolated processes. 499 */ 500 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 501 502 /** 503 * Counter for assigning isolated process uids, to avoid frequently reusing the 504 * same ones. 505 */ 506 int mNextIsolatedProcessUid = 0; 507 508 /** 509 * The currently running heavy-weight process, if any. 510 */ 511 ProcessRecord mHeavyWeightProcess = null; 512 513 /** 514 * The last time that various processes have crashed. 515 */ 516 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 517 518 /** 519 * Information about a process that is currently marked as bad. 520 */ 521 static final class BadProcessInfo { 522 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 523 this.time = time; 524 this.shortMsg = shortMsg; 525 this.longMsg = longMsg; 526 this.stack = stack; 527 } 528 529 final long time; 530 final String shortMsg; 531 final String longMsg; 532 final String stack; 533 } 534 535 /** 536 * Set of applications that we consider to be bad, and will reject 537 * incoming broadcasts from (which the user has no control over). 538 * Processes are added to this set when they have crashed twice within 539 * a minimum amount of time; they are removed from it when they are 540 * later restarted (hopefully due to some user action). The value is the 541 * time it was added to the list. 542 */ 543 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 544 545 /** 546 * All of the processes we currently have running organized by pid. 547 * The keys are the pid running the application. 548 * 549 * <p>NOTE: This object is protected by its own lock, NOT the global 550 * activity manager lock! 551 */ 552 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 553 554 /** 555 * All of the processes that have been forced to be foreground. The key 556 * is the pid of the caller who requested it (we hold a death 557 * link on it). 558 */ 559 abstract class ForegroundToken implements IBinder.DeathRecipient { 560 int pid; 561 IBinder token; 562 } 563 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 564 565 /** 566 * List of records for processes that someone had tried to start before the 567 * system was ready. We don't start them at that point, but ensure they 568 * are started by the time booting is complete. 569 */ 570 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of persistent applications that are in the process 574 * of being started. 575 */ 576 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes that are being forcibly torn down. 580 */ 581 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * List of running applications, sorted by recent usage. 585 * The first entry in the list is the least recently used. 586 */ 587 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Where in mLruProcesses that the processes hosting activities start. 591 */ 592 int mLruProcessActivityStart = 0; 593 594 /** 595 * Where in mLruProcesses that the processes hosting services start. 596 * This is after (lower index) than mLruProcessesActivityStart. 597 */ 598 int mLruProcessServiceStart = 0; 599 600 /** 601 * List of processes that should gc as soon as things are idle. 602 */ 603 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 604 605 /** 606 * Processes we want to collect PSS data from. 607 */ 608 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 609 610 /** 611 * Last time we requested PSS data of all processes. 612 */ 613 long mLastFullPssTime = SystemClock.uptimeMillis(); 614 615 /** 616 * If set, the next time we collect PSS data we should do a full collection 617 * with data from native processes and the kernel. 618 */ 619 boolean mFullPssPending = false; 620 621 /** 622 * This is the process holding what we currently consider to be 623 * the "home" activity. 624 */ 625 ProcessRecord mHomeProcess; 626 627 /** 628 * This is the process holding the activity the user last visited that 629 * is in a different process from the one they are currently in. 630 */ 631 ProcessRecord mPreviousProcess; 632 633 /** 634 * The time at which the previous process was last visible. 635 */ 636 long mPreviousProcessVisibleTime; 637 638 /** 639 * Which uses have been started, so are allowed to run code. 640 */ 641 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 642 643 /** 644 * LRU list of history of current users. Most recently current is at the end. 645 */ 646 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 647 648 /** 649 * Constant array of the users that are currently started. 650 */ 651 int[] mStartedUserArray = new int[] { 0 }; 652 653 /** 654 * Registered observers of the user switching mechanics. 655 */ 656 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 657 = new RemoteCallbackList<IUserSwitchObserver>(); 658 659 /** 660 * Currently active user switch. 661 */ 662 Object mCurUserSwitchCallback; 663 664 /** 665 * Packages that the user has asked to have run in screen size 666 * compatibility mode instead of filling the screen. 667 */ 668 final CompatModePackages mCompatModePackages; 669 670 /** 671 * Set of IntentSenderRecord objects that are currently active. 672 */ 673 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 674 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 675 676 /** 677 * Fingerprints (hashCode()) of stack traces that we've 678 * already logged DropBox entries for. Guarded by itself. If 679 * something (rogue user app) forces this over 680 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 681 */ 682 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 683 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 684 685 /** 686 * Strict Mode background batched logging state. 687 * 688 * The string buffer is guarded by itself, and its lock is also 689 * used to determine if another batched write is already 690 * in-flight. 691 */ 692 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 693 694 /** 695 * Keeps track of all IIntentReceivers that have been registered for 696 * broadcasts. Hash keys are the receiver IBinder, hash value is 697 * a ReceiverList. 698 */ 699 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 700 new HashMap<IBinder, ReceiverList>(); 701 702 /** 703 * Resolver for broadcast intents to registered receivers. 704 * Holds BroadcastFilter (subclass of IntentFilter). 705 */ 706 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 707 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 708 @Override 709 protected boolean allowFilterResult( 710 BroadcastFilter filter, List<BroadcastFilter> dest) { 711 IBinder target = filter.receiverList.receiver.asBinder(); 712 for (int i=dest.size()-1; i>=0; i--) { 713 if (dest.get(i).receiverList.receiver.asBinder() == target) { 714 return false; 715 } 716 } 717 return true; 718 } 719 720 @Override 721 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 722 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 723 || userId == filter.owningUserId) { 724 return super.newResult(filter, match, userId); 725 } 726 return null; 727 } 728 729 @Override 730 protected BroadcastFilter[] newArray(int size) { 731 return new BroadcastFilter[size]; 732 } 733 734 @Override 735 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 736 return packageName.equals(filter.packageName); 737 } 738 }; 739 740 /** 741 * State of all active sticky broadcasts per user. Keys are the action of the 742 * sticky Intent, values are an ArrayList of all broadcasted intents with 743 * that action (which should usually be one). The SparseArray is keyed 744 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 745 * for stickies that are sent to all users. 746 */ 747 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 748 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 749 750 final ActiveServices mServices; 751 752 final static class Association { 753 final int mSourceUid; 754 final String mSourceProcess; 755 final int mTargetUid; 756 final ComponentName mTargetComponent; 757 final String mTargetProcess; 758 759 int mCount; 760 long mTime; 761 762 int mNesting; 763 long mStartTime; 764 765 Association(int sourceUid, String sourceProcess, int targetUid, 766 ComponentName targetComponent, String targetProcess) { 767 mSourceUid = sourceUid; 768 mSourceProcess = sourceProcess; 769 mTargetUid = targetUid; 770 mTargetComponent = targetComponent; 771 mTargetProcess = targetProcess; 772 } 773 } 774 775 /** 776 * When service association tracking is enabled, this is all of the associations we 777 * have seen. Mapping is target uid -> target component -> source uid -> source process name 778 * -> association data. 779 */ 780 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 781 mAssociations = new SparseArray<>(); 782 boolean mTrackingAssociations; 783 784 /** 785 * Backup/restore process management 786 */ 787 String mBackupAppName = null; 788 BackupRecord mBackupTarget = null; 789 790 final ProviderMap mProviderMap; 791 792 /** 793 * List of content providers who have clients waiting for them. The 794 * application is currently being launched and the provider will be 795 * removed from this list once it is published. 796 */ 797 final ArrayList<ContentProviderRecord> mLaunchingProviders 798 = new ArrayList<ContentProviderRecord>(); 799 800 /** 801 * File storing persisted {@link #mGrantedUriPermissions}. 802 */ 803 private final AtomicFile mGrantFile; 804 805 /** XML constants used in {@link #mGrantFile} */ 806 private static final String TAG_URI_GRANTS = "uri-grants"; 807 private static final String TAG_URI_GRANT = "uri-grant"; 808 private static final String ATTR_USER_HANDLE = "userHandle"; 809 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 810 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 811 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 812 private static final String ATTR_TARGET_PKG = "targetPkg"; 813 private static final String ATTR_URI = "uri"; 814 private static final String ATTR_MODE_FLAGS = "modeFlags"; 815 private static final String ATTR_CREATED_TIME = "createdTime"; 816 private static final String ATTR_PREFIX = "prefix"; 817 818 /** 819 * Global set of specific {@link Uri} permissions that have been granted. 820 * This optimized lookup structure maps from {@link UriPermission#targetUid} 821 * to {@link UriPermission#uri} to {@link UriPermission}. 822 */ 823 @GuardedBy("this") 824 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 825 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 826 827 public static class GrantUri { 828 public final int sourceUserId; 829 public final Uri uri; 830 public boolean prefix; 831 832 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 833 this.sourceUserId = sourceUserId; 834 this.uri = uri; 835 this.prefix = prefix; 836 } 837 838 @Override 839 public int hashCode() { 840 int hashCode = 1; 841 hashCode = 31 * hashCode + sourceUserId; 842 hashCode = 31 * hashCode + uri.hashCode(); 843 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 844 return hashCode; 845 } 846 847 @Override 848 public boolean equals(Object o) { 849 if (o instanceof GrantUri) { 850 GrantUri other = (GrantUri) o; 851 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 852 && prefix == other.prefix; 853 } 854 return false; 855 } 856 857 @Override 858 public String toString() { 859 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 860 if (prefix) result += " [prefix]"; 861 return result; 862 } 863 864 public String toSafeString() { 865 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 866 if (prefix) result += " [prefix]"; 867 return result; 868 } 869 870 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 871 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 872 ContentProvider.getUriWithoutUserId(uri), false); 873 } 874 } 875 876 CoreSettingsObserver mCoreSettingsObserver; 877 878 /** 879 * Thread-local storage used to carry caller permissions over through 880 * indirect content-provider access. 881 */ 882 private class Identity { 883 public final IBinder token; 884 public final int pid; 885 public final int uid; 886 887 Identity(IBinder _token, int _pid, int _uid) { 888 token = _token; 889 pid = _pid; 890 uid = _uid; 891 } 892 } 893 894 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 895 896 /** 897 * All information we have collected about the runtime performance of 898 * any user id that can impact battery performance. 899 */ 900 final BatteryStatsService mBatteryStatsService; 901 902 /** 903 * Information about component usage 904 */ 905 UsageStatsManagerInternal mUsageStatsService; 906 907 /** 908 * Information about and control over application operations 909 */ 910 final AppOpsService mAppOpsService; 911 912 /** 913 * Save recent tasks information across reboots. 914 */ 915 final TaskPersister mTaskPersister; 916 917 /** 918 * Current configuration information. HistoryRecord objects are given 919 * a reference to this object to indicate which configuration they are 920 * currently running in, so this object must be kept immutable. 921 */ 922 Configuration mConfiguration = new Configuration(); 923 924 /** 925 * Current sequencing integer of the configuration, for skipping old 926 * configurations. 927 */ 928 int mConfigurationSeq = 0; 929 930 /** 931 * Hardware-reported OpenGLES version. 932 */ 933 final int GL_ES_VERSION; 934 935 /** 936 * List of initialization arguments to pass to all processes when binding applications to them. 937 * For example, references to the commonly used services. 938 */ 939 HashMap<String, IBinder> mAppBindArgs; 940 941 /** 942 * Temporary to avoid allocations. Protected by main lock. 943 */ 944 final StringBuilder mStringBuilder = new StringBuilder(256); 945 946 /** 947 * Used to control how we initialize the service. 948 */ 949 ComponentName mTopComponent; 950 String mTopAction = Intent.ACTION_MAIN; 951 String mTopData; 952 boolean mProcessesReady = false; 953 boolean mSystemReady = false; 954 boolean mBooting = false; 955 boolean mCallFinishBooting = false; 956 boolean mBootAnimationComplete = false; 957 boolean mWaitingUpdate = false; 958 boolean mDidUpdate = false; 959 boolean mOnBattery = false; 960 boolean mLaunchWarningShown = false; 961 962 Context mContext; 963 964 int mFactoryTest; 965 966 boolean mCheckedForSetup; 967 968 /** 969 * The time at which we will allow normal application switches again, 970 * after a call to {@link #stopAppSwitches()}. 971 */ 972 long mAppSwitchesAllowedTime; 973 974 /** 975 * This is set to true after the first switch after mAppSwitchesAllowedTime 976 * is set; any switches after that will clear the time. 977 */ 978 boolean mDidAppSwitch; 979 980 /** 981 * Last time (in realtime) at which we checked for power usage. 982 */ 983 long mLastPowerCheckRealtime; 984 985 /** 986 * Last time (in uptime) at which we checked for power usage. 987 */ 988 long mLastPowerCheckUptime; 989 990 /** 991 * Set while we are wanting to sleep, to prevent any 992 * activities from being started/resumed. 993 */ 994 private boolean mSleeping = false; 995 996 /** 997 * Set while we are running a voice interaction. This overrides 998 * sleeping while it is active. 999 */ 1000 private boolean mRunningVoice = false; 1001 1002 /** 1003 * State of external calls telling us if the device is awake or asleep. 1004 */ 1005 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 1006 1007 static final int LOCK_SCREEN_HIDDEN = 0; 1008 static final int LOCK_SCREEN_LEAVING = 1; 1009 static final int LOCK_SCREEN_SHOWN = 2; 1010 /** 1011 * State of external call telling us if the lock screen is shown. 1012 */ 1013 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 1014 1015 /** 1016 * Set if we are shutting down the system, similar to sleeping. 1017 */ 1018 boolean mShuttingDown = false; 1019 1020 /** 1021 * Current sequence id for oom_adj computation traversal. 1022 */ 1023 int mAdjSeq = 0; 1024 1025 /** 1026 * Current sequence id for process LRU updating. 1027 */ 1028 int mLruSeq = 0; 1029 1030 /** 1031 * Keep track of the non-cached/empty process we last found, to help 1032 * determine how to distribute cached/empty processes next time. 1033 */ 1034 int mNumNonCachedProcs = 0; 1035 1036 /** 1037 * Keep track of the number of cached hidden procs, to balance oom adj 1038 * distribution between those and empty procs. 1039 */ 1040 int mNumCachedHiddenProcs = 0; 1041 1042 /** 1043 * Keep track of the number of service processes we last found, to 1044 * determine on the next iteration which should be B services. 1045 */ 1046 int mNumServiceProcs = 0; 1047 int mNewNumAServiceProcs = 0; 1048 int mNewNumServiceProcs = 0; 1049 1050 /** 1051 * Allow the current computed overall memory level of the system to go down? 1052 * This is set to false when we are killing processes for reasons other than 1053 * memory management, so that the now smaller process list will not be taken as 1054 * an indication that memory is tighter. 1055 */ 1056 boolean mAllowLowerMemLevel = false; 1057 1058 /** 1059 * The last computed memory level, for holding when we are in a state that 1060 * processes are going away for other reasons. 1061 */ 1062 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1063 1064 /** 1065 * The last total number of process we have, to determine if changes actually look 1066 * like a shrinking number of process due to lower RAM. 1067 */ 1068 int mLastNumProcesses; 1069 1070 /** 1071 * The uptime of the last time we performed idle maintenance. 1072 */ 1073 long mLastIdleTime = SystemClock.uptimeMillis(); 1074 1075 /** 1076 * Total time spent with RAM that has been added in the past since the last idle time. 1077 */ 1078 long mLowRamTimeSinceLastIdle = 0; 1079 1080 /** 1081 * If RAM is currently low, when that horrible situation started. 1082 */ 1083 long mLowRamStartTime = 0; 1084 1085 /** 1086 * For reporting to battery stats the current top application. 1087 */ 1088 private String mCurResumedPackage = null; 1089 private int mCurResumedUid = -1; 1090 1091 /** 1092 * For reporting to battery stats the apps currently running foreground 1093 * service. The ProcessMap is package/uid tuples; each of these contain 1094 * an array of the currently foreground processes. 1095 */ 1096 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1097 = new ProcessMap<ArrayList<ProcessRecord>>(); 1098 1099 /** 1100 * This is set if we had to do a delayed dexopt of an app before launching 1101 * it, to increase the ANR timeouts in that case. 1102 */ 1103 boolean mDidDexOpt; 1104 1105 /** 1106 * Set if the systemServer made a call to enterSafeMode. 1107 */ 1108 boolean mSafeMode; 1109 1110 /** 1111 * If true, we are running under a test environment so will sample PSS from processes 1112 * much more rapidly to try to collect better data when the tests are rapidly 1113 * running through apps. 1114 */ 1115 boolean mTestPssMode = false; 1116 1117 String mDebugApp = null; 1118 boolean mWaitForDebugger = false; 1119 boolean mDebugTransient = false; 1120 String mOrigDebugApp = null; 1121 boolean mOrigWaitForDebugger = false; 1122 boolean mAlwaysFinishActivities = false; 1123 IActivityController mController = null; 1124 String mProfileApp = null; 1125 ProcessRecord mProfileProc = null; 1126 String mProfileFile; 1127 ParcelFileDescriptor mProfileFd; 1128 int mSamplingInterval = 0; 1129 boolean mAutoStopProfiler = false; 1130 int mProfileType = 0; 1131 String mOpenGlTraceApp = null; 1132 1133 final long[] mTmpLong = new long[1]; 1134 1135 static class ProcessChangeItem { 1136 static final int CHANGE_ACTIVITIES = 1<<0; 1137 static final int CHANGE_PROCESS_STATE = 1<<1; 1138 int changes; 1139 int uid; 1140 int pid; 1141 int processState; 1142 boolean foregroundActivities; 1143 } 1144 1145 final RemoteCallbackList<IProcessObserver> mProcessObservers 1146 = new RemoteCallbackList<IProcessObserver>(); 1147 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1148 1149 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1150 = new ArrayList<ProcessChangeItem>(); 1151 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1152 = new ArrayList<ProcessChangeItem>(); 1153 1154 /** 1155 * Runtime CPU use collection thread. This object's lock is used to 1156 * perform synchronization with the thread (notifying it to run). 1157 */ 1158 final Thread mProcessCpuThread; 1159 1160 /** 1161 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1162 * Must acquire this object's lock when accessing it. 1163 * NOTE: this lock will be held while doing long operations (trawling 1164 * through all processes in /proc), so it should never be acquired by 1165 * any critical paths such as when holding the main activity manager lock. 1166 */ 1167 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1168 MONITOR_THREAD_CPU_USAGE); 1169 final AtomicLong mLastCpuTime = new AtomicLong(0); 1170 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1171 1172 long mLastWriteTime = 0; 1173 1174 /** 1175 * Used to retain an update lock when the foreground activity is in 1176 * immersive mode. 1177 */ 1178 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1179 1180 /** 1181 * Set to true after the system has finished booting. 1182 */ 1183 boolean mBooted = false; 1184 1185 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1186 int mProcessLimitOverride = -1; 1187 1188 WindowManagerService mWindowManager; 1189 1190 final ActivityThread mSystemThread; 1191 1192 // Holds the current foreground user's id 1193 int mCurrentUserId = 0; 1194 // Holds the target user's id during a user switch 1195 int mTargetUserId = UserHandle.USER_NULL; 1196 // If there are multiple profiles for the current user, their ids are here 1197 // Currently only the primary user can have managed profiles 1198 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1199 1200 /** 1201 * Mapping from each known user ID to the profile group ID it is associated with. 1202 */ 1203 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1204 1205 private UserManagerService mUserManager; 1206 1207 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1208 final ProcessRecord mApp; 1209 final int mPid; 1210 final IApplicationThread mAppThread; 1211 1212 AppDeathRecipient(ProcessRecord app, int pid, 1213 IApplicationThread thread) { 1214 if (localLOGV) Slog.v( 1215 TAG, "New death recipient " + this 1216 + " for thread " + thread.asBinder()); 1217 mApp = app; 1218 mPid = pid; 1219 mAppThread = thread; 1220 } 1221 1222 @Override 1223 public void binderDied() { 1224 if (localLOGV) Slog.v( 1225 TAG, "Death received in " + this 1226 + " for thread " + mAppThread.asBinder()); 1227 synchronized(ActivityManagerService.this) { 1228 appDiedLocked(mApp, mPid, mAppThread); 1229 } 1230 } 1231 } 1232 1233 static final int SHOW_ERROR_MSG = 1; 1234 static final int SHOW_NOT_RESPONDING_MSG = 2; 1235 static final int SHOW_FACTORY_ERROR_MSG = 3; 1236 static final int UPDATE_CONFIGURATION_MSG = 4; 1237 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1238 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1239 static final int SERVICE_TIMEOUT_MSG = 12; 1240 static final int UPDATE_TIME_ZONE = 13; 1241 static final int SHOW_UID_ERROR_MSG = 14; 1242 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1243 static final int PROC_START_TIMEOUT_MSG = 20; 1244 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1245 static final int KILL_APPLICATION_MSG = 22; 1246 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1247 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1248 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1249 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1250 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1251 static final int CLEAR_DNS_CACHE_MSG = 28; 1252 static final int UPDATE_HTTP_PROXY_MSG = 29; 1253 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1254 static final int DISPATCH_PROCESSES_CHANGED = 31; 1255 static final int DISPATCH_PROCESS_DIED = 32; 1256 static final int REPORT_MEM_USAGE_MSG = 33; 1257 static final int REPORT_USER_SWITCH_MSG = 34; 1258 static final int CONTINUE_USER_SWITCH_MSG = 35; 1259 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1260 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1261 static final int PERSIST_URI_GRANTS_MSG = 38; 1262 static final int REQUEST_ALL_PSS_MSG = 39; 1263 static final int START_PROFILES_MSG = 40; 1264 static final int UPDATE_TIME = 41; 1265 static final int SYSTEM_USER_START_MSG = 42; 1266 static final int SYSTEM_USER_CURRENT_MSG = 43; 1267 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1268 static final int FINISH_BOOTING_MSG = 45; 1269 static final int START_USER_SWITCH_MSG = 46; 1270 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1271 static final int DISMISS_DIALOG_MSG = 48; 1272 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1273 1274 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1275 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1276 static final int FIRST_COMPAT_MODE_MSG = 300; 1277 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1278 1279 CompatModeDialog mCompatModeDialog; 1280 long mLastMemUsageReportTime = 0; 1281 1282 /** 1283 * Flag whether the current user is a "monkey", i.e. whether 1284 * the UI is driven by a UI automation tool. 1285 */ 1286 private boolean mUserIsMonkey; 1287 1288 /** Flag whether the device has a Recents UI */ 1289 boolean mHasRecents; 1290 1291 /** The dimensions of the thumbnails in the Recents UI. */ 1292 int mThumbnailWidth; 1293 int mThumbnailHeight; 1294 1295 final ServiceThread mHandlerThread; 1296 final MainHandler mHandler; 1297 1298 final class MainHandler extends Handler { 1299 public MainHandler(Looper looper) { 1300 super(looper, null, true); 1301 } 1302 1303 @Override 1304 public void handleMessage(Message msg) { 1305 switch (msg.what) { 1306 case SHOW_ERROR_MSG: { 1307 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1308 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1309 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1310 synchronized (ActivityManagerService.this) { 1311 ProcessRecord proc = (ProcessRecord)data.get("app"); 1312 AppErrorResult res = (AppErrorResult) data.get("result"); 1313 if (proc != null && proc.crashDialog != null) { 1314 Slog.e(TAG, "App already has crash dialog: " + proc); 1315 if (res != null) { 1316 res.set(0); 1317 } 1318 return; 1319 } 1320 boolean isBackground = (UserHandle.getAppId(proc.uid) 1321 >= Process.FIRST_APPLICATION_UID 1322 && proc.pid != MY_PID); 1323 for (int userId : mCurrentProfileIds) { 1324 isBackground &= (proc.userId != userId); 1325 } 1326 if (isBackground && !showBackground) { 1327 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1328 if (res != null) { 1329 res.set(0); 1330 } 1331 return; 1332 } 1333 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1334 Dialog d = new AppErrorDialog(mContext, 1335 ActivityManagerService.this, res, proc); 1336 d.show(); 1337 proc.crashDialog = d; 1338 } else { 1339 // The device is asleep, so just pretend that the user 1340 // saw a crash dialog and hit "force quit". 1341 if (res != null) { 1342 res.set(0); 1343 } 1344 } 1345 } 1346 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_NOT_RESPONDING_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1352 ProcessRecord proc = (ProcessRecord)data.get("app"); 1353 if (proc != null && proc.anrDialog != null) { 1354 Slog.e(TAG, "App already has anr dialog: " + proc); 1355 return; 1356 } 1357 1358 Intent intent = new Intent("android.intent.action.ANR"); 1359 if (!mProcessesReady) { 1360 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1361 | Intent.FLAG_RECEIVER_FOREGROUND); 1362 } 1363 broadcastIntentLocked(null, null, intent, 1364 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1365 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1366 1367 if (mShowDialogs) { 1368 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1369 mContext, proc, (ActivityRecord)data.get("activity"), 1370 msg.arg1 != 0); 1371 d.show(); 1372 proc.anrDialog = d; 1373 } else { 1374 // Just kill the app if there is no dialog to be shown. 1375 killAppAtUsersRequest(proc, null); 1376 } 1377 } 1378 1379 ensureBootCompleted(); 1380 } break; 1381 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1382 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1383 synchronized (ActivityManagerService.this) { 1384 ProcessRecord proc = (ProcessRecord) data.get("app"); 1385 if (proc == null) { 1386 Slog.e(TAG, "App not found when showing strict mode dialog."); 1387 break; 1388 } 1389 if (proc.crashDialog != null) { 1390 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1391 return; 1392 } 1393 AppErrorResult res = (AppErrorResult) data.get("result"); 1394 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1395 Dialog d = new StrictModeViolationDialog(mContext, 1396 ActivityManagerService.this, res, proc); 1397 d.show(); 1398 proc.crashDialog = d; 1399 } else { 1400 // The device is asleep, so just pretend that the user 1401 // saw a crash dialog and hit "force quit". 1402 res.set(0); 1403 } 1404 } 1405 ensureBootCompleted(); 1406 } break; 1407 case SHOW_FACTORY_ERROR_MSG: { 1408 Dialog d = new FactoryErrorDialog( 1409 mContext, msg.getData().getCharSequence("msg")); 1410 d.show(); 1411 ensureBootCompleted(); 1412 } break; 1413 case UPDATE_CONFIGURATION_MSG: { 1414 final ContentResolver resolver = mContext.getContentResolver(); 1415 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1416 } break; 1417 case GC_BACKGROUND_PROCESSES_MSG: { 1418 synchronized (ActivityManagerService.this) { 1419 performAppGcsIfAppropriateLocked(); 1420 } 1421 } break; 1422 case WAIT_FOR_DEBUGGER_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 ProcessRecord app = (ProcessRecord)msg.obj; 1425 if (msg.arg1 != 0) { 1426 if (!app.waitedForDebugger) { 1427 Dialog d = new AppWaitingForDebuggerDialog( 1428 ActivityManagerService.this, 1429 mContext, app); 1430 app.waitDialog = d; 1431 app.waitedForDebugger = true; 1432 d.show(); 1433 } 1434 } else { 1435 if (app.waitDialog != null) { 1436 app.waitDialog.dismiss(); 1437 app.waitDialog = null; 1438 } 1439 } 1440 } 1441 } break; 1442 case SERVICE_TIMEOUT_MSG: { 1443 if (mDidDexOpt) { 1444 mDidDexOpt = false; 1445 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1446 nmsg.obj = msg.obj; 1447 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1448 return; 1449 } 1450 mServices.serviceTimeout((ProcessRecord)msg.obj); 1451 } break; 1452 case UPDATE_TIME_ZONE: { 1453 synchronized (ActivityManagerService.this) { 1454 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1455 ProcessRecord r = mLruProcesses.get(i); 1456 if (r.thread != null) { 1457 try { 1458 r.thread.updateTimeZone(); 1459 } catch (RemoteException ex) { 1460 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1461 } 1462 } 1463 } 1464 } 1465 } break; 1466 case CLEAR_DNS_CACHE_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1469 ProcessRecord r = mLruProcesses.get(i); 1470 if (r.thread != null) { 1471 try { 1472 r.thread.clearDnsCache(); 1473 } catch (RemoteException ex) { 1474 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1475 } 1476 } 1477 } 1478 } 1479 } break; 1480 case UPDATE_HTTP_PROXY_MSG: { 1481 ProxyInfo proxy = (ProxyInfo)msg.obj; 1482 String host = ""; 1483 String port = ""; 1484 String exclList = ""; 1485 Uri pacFileUrl = Uri.EMPTY; 1486 if (proxy != null) { 1487 host = proxy.getHost(); 1488 port = Integer.toString(proxy.getPort()); 1489 exclList = proxy.getExclusionListAsString(); 1490 pacFileUrl = proxy.getPacFileUrl(); 1491 } 1492 synchronized (ActivityManagerService.this) { 1493 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1494 ProcessRecord r = mLruProcesses.get(i); 1495 if (r.thread != null) { 1496 try { 1497 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1498 } catch (RemoteException ex) { 1499 Slog.w(TAG, "Failed to update http proxy for: " + 1500 r.info.processName); 1501 } 1502 } 1503 } 1504 } 1505 } break; 1506 case SHOW_UID_ERROR_MSG: { 1507 if (mShowDialogs) { 1508 AlertDialog d = new BaseErrorDialog(mContext); 1509 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1510 d.setCancelable(false); 1511 d.setTitle(mContext.getText(R.string.android_system_label)); 1512 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1513 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1514 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1515 d.show(); 1516 } 1517 } break; 1518 case SHOW_FINGERPRINT_ERROR_MSG: { 1519 if (mShowDialogs) { 1520 AlertDialog d = new BaseErrorDialog(mContext); 1521 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1522 d.setCancelable(false); 1523 d.setTitle(mContext.getText(R.string.android_system_label)); 1524 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1525 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1526 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1527 d.show(); 1528 } 1529 } break; 1530 case PROC_START_TIMEOUT_MSG: { 1531 if (mDidDexOpt) { 1532 mDidDexOpt = false; 1533 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1534 nmsg.obj = msg.obj; 1535 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1536 return; 1537 } 1538 ProcessRecord app = (ProcessRecord)msg.obj; 1539 synchronized (ActivityManagerService.this) { 1540 processStartTimedOutLocked(app); 1541 } 1542 } break; 1543 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1544 synchronized (ActivityManagerService.this) { 1545 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1546 } 1547 } break; 1548 case KILL_APPLICATION_MSG: { 1549 synchronized (ActivityManagerService.this) { 1550 int appid = msg.arg1; 1551 boolean restart = (msg.arg2 == 1); 1552 Bundle bundle = (Bundle)msg.obj; 1553 String pkg = bundle.getString("pkg"); 1554 String reason = bundle.getString("reason"); 1555 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1556 false, UserHandle.USER_ALL, reason); 1557 } 1558 } break; 1559 case FINALIZE_PENDING_INTENT_MSG: { 1560 ((PendingIntentRecord)msg.obj).completeFinalize(); 1561 } break; 1562 case POST_HEAVY_NOTIFICATION_MSG: { 1563 INotificationManager inm = NotificationManager.getService(); 1564 if (inm == null) { 1565 return; 1566 } 1567 1568 ActivityRecord root = (ActivityRecord)msg.obj; 1569 ProcessRecord process = root.app; 1570 if (process == null) { 1571 return; 1572 } 1573 1574 try { 1575 Context context = mContext.createPackageContext(process.info.packageName, 0); 1576 String text = mContext.getString(R.string.heavy_weight_notification, 1577 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1578 Notification notification = new Notification(); 1579 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1580 notification.when = 0; 1581 notification.flags = Notification.FLAG_ONGOING_EVENT; 1582 notification.tickerText = text; 1583 notification.defaults = 0; // please be quiet 1584 notification.sound = null; 1585 notification.vibrate = null; 1586 notification.color = mContext.getResources().getColor( 1587 com.android.internal.R.color.system_notification_accent_color); 1588 notification.setLatestEventInfo(context, text, 1589 mContext.getText(R.string.heavy_weight_notification_detail), 1590 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1591 PendingIntent.FLAG_CANCEL_CURRENT, null, 1592 new UserHandle(root.userId))); 1593 1594 try { 1595 int[] outId = new int[1]; 1596 inm.enqueueNotificationWithTag("android", "android", null, 1597 R.string.heavy_weight_notification, 1598 notification, outId, root.userId); 1599 } catch (RuntimeException e) { 1600 Slog.w(ActivityManagerService.TAG, 1601 "Error showing notification for heavy-weight app", e); 1602 } catch (RemoteException e) { 1603 } 1604 } catch (NameNotFoundException e) { 1605 Slog.w(TAG, "Unable to create context for heavy notification", e); 1606 } 1607 } break; 1608 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1609 INotificationManager inm = NotificationManager.getService(); 1610 if (inm == null) { 1611 return; 1612 } 1613 try { 1614 inm.cancelNotificationWithTag("android", null, 1615 R.string.heavy_weight_notification, msg.arg1); 1616 } catch (RuntimeException e) { 1617 Slog.w(ActivityManagerService.TAG, 1618 "Error canceling notification for service", e); 1619 } catch (RemoteException e) { 1620 } 1621 } break; 1622 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1623 synchronized (ActivityManagerService.this) { 1624 checkExcessivePowerUsageLocked(true); 1625 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1626 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1627 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1628 } 1629 } break; 1630 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1631 synchronized (ActivityManagerService.this) { 1632 ActivityRecord ar = (ActivityRecord)msg.obj; 1633 if (mCompatModeDialog != null) { 1634 if (mCompatModeDialog.mAppInfo.packageName.equals( 1635 ar.info.applicationInfo.packageName)) { 1636 return; 1637 } 1638 mCompatModeDialog.dismiss(); 1639 mCompatModeDialog = null; 1640 } 1641 if (ar != null && false) { 1642 if (mCompatModePackages.getPackageAskCompatModeLocked( 1643 ar.packageName)) { 1644 int mode = mCompatModePackages.computeCompatModeLocked( 1645 ar.info.applicationInfo); 1646 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1647 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1648 mCompatModeDialog = new CompatModeDialog( 1649 ActivityManagerService.this, mContext, 1650 ar.info.applicationInfo); 1651 mCompatModeDialog.show(); 1652 } 1653 } 1654 } 1655 } 1656 break; 1657 } 1658 case DISPATCH_PROCESSES_CHANGED: { 1659 dispatchProcessesChanged(); 1660 break; 1661 } 1662 case DISPATCH_PROCESS_DIED: { 1663 final int pid = msg.arg1; 1664 final int uid = msg.arg2; 1665 dispatchProcessDied(pid, uid); 1666 break; 1667 } 1668 case REPORT_MEM_USAGE_MSG: { 1669 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1670 Thread thread = new Thread() { 1671 @Override public void run() { 1672 reportMemUsage(memInfos); 1673 } 1674 }; 1675 thread.start(); 1676 break; 1677 } 1678 case START_USER_SWITCH_MSG: { 1679 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1680 break; 1681 } 1682 case REPORT_USER_SWITCH_MSG: { 1683 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1684 break; 1685 } 1686 case CONTINUE_USER_SWITCH_MSG: { 1687 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1688 break; 1689 } 1690 case USER_SWITCH_TIMEOUT_MSG: { 1691 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1692 break; 1693 } 1694 case IMMERSIVE_MODE_LOCK_MSG: { 1695 final boolean nextState = (msg.arg1 != 0); 1696 if (mUpdateLock.isHeld() != nextState) { 1697 if (DEBUG_IMMERSIVE) { 1698 final ActivityRecord r = (ActivityRecord) msg.obj; 1699 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1700 } 1701 if (nextState) { 1702 mUpdateLock.acquire(); 1703 } else { 1704 mUpdateLock.release(); 1705 } 1706 } 1707 break; 1708 } 1709 case PERSIST_URI_GRANTS_MSG: { 1710 writeGrantedUriPermissions(); 1711 break; 1712 } 1713 case REQUEST_ALL_PSS_MSG: { 1714 synchronized (ActivityManagerService.this) { 1715 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1716 } 1717 break; 1718 } 1719 case START_PROFILES_MSG: { 1720 synchronized (ActivityManagerService.this) { 1721 startProfilesLocked(); 1722 } 1723 break; 1724 } 1725 case UPDATE_TIME: { 1726 synchronized (ActivityManagerService.this) { 1727 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1728 ProcessRecord r = mLruProcesses.get(i); 1729 if (r.thread != null) { 1730 try { 1731 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1732 } catch (RemoteException ex) { 1733 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1734 } 1735 } 1736 } 1737 } 1738 break; 1739 } 1740 case SYSTEM_USER_START_MSG: { 1741 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1742 Integer.toString(msg.arg1), msg.arg1); 1743 mSystemServiceManager.startUser(msg.arg1); 1744 break; 1745 } 1746 case SYSTEM_USER_CURRENT_MSG: { 1747 mBatteryStatsService.noteEvent( 1748 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1749 Integer.toString(msg.arg2), msg.arg2); 1750 mBatteryStatsService.noteEvent( 1751 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1752 Integer.toString(msg.arg1), msg.arg1); 1753 mSystemServiceManager.switchUser(msg.arg1); 1754 break; 1755 } 1756 case ENTER_ANIMATION_COMPLETE_MSG: { 1757 synchronized (ActivityManagerService.this) { 1758 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1759 if (r != null && r.app != null && r.app.thread != null) { 1760 try { 1761 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1762 } catch (RemoteException e) { 1763 } 1764 } 1765 } 1766 break; 1767 } 1768 case FINISH_BOOTING_MSG: { 1769 if (msg.arg1 != 0) { 1770 finishBooting(); 1771 } 1772 if (msg.arg2 != 0) { 1773 enableScreenAfterBoot(); 1774 } 1775 break; 1776 } 1777 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1778 try { 1779 Locale l = (Locale) msg.obj; 1780 IBinder service = ServiceManager.getService("mount"); 1781 IMountService mountService = IMountService.Stub.asInterface(service); 1782 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1783 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1784 } catch (RemoteException e) { 1785 Log.e(TAG, "Error storing locale for decryption UI", e); 1786 } 1787 break; 1788 } 1789 case DISMISS_DIALOG_MSG: { 1790 final Dialog d = (Dialog) msg.obj; 1791 d.dismiss(); 1792 break; 1793 } 1794 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1795 synchronized (ActivityManagerService.this) { 1796 int i = mTaskStackListeners.beginBroadcast(); 1797 while (i > 0) { 1798 i--; 1799 try { 1800 // Make a one-way callback to the listener 1801 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1802 } catch (RemoteException e){ 1803 // Handled by the RemoteCallbackList 1804 } 1805 } 1806 mTaskStackListeners.finishBroadcast(); 1807 } 1808 break; 1809 } 1810 } 1811 } 1812 }; 1813 1814 static final int COLLECT_PSS_BG_MSG = 1; 1815 1816 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1817 @Override 1818 public void handleMessage(Message msg) { 1819 switch (msg.what) { 1820 case COLLECT_PSS_BG_MSG: { 1821 long start = SystemClock.uptimeMillis(); 1822 MemInfoReader memInfo = null; 1823 synchronized (ActivityManagerService.this) { 1824 if (mFullPssPending) { 1825 mFullPssPending = false; 1826 memInfo = new MemInfoReader(); 1827 } 1828 } 1829 if (memInfo != null) { 1830 updateCpuStatsNow(); 1831 long nativeTotalPss = 0; 1832 synchronized (mProcessCpuTracker) { 1833 final int N = mProcessCpuTracker.countStats(); 1834 for (int j=0; j<N; j++) { 1835 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1836 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1837 // This is definitely an application process; skip it. 1838 continue; 1839 } 1840 synchronized (mPidsSelfLocked) { 1841 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1842 // This is one of our own processes; skip it. 1843 continue; 1844 } 1845 } 1846 nativeTotalPss += Debug.getPss(st.pid, null, null); 1847 } 1848 } 1849 memInfo.readMemInfo(); 1850 synchronized (ActivityManagerService.this) { 1851 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1852 + (SystemClock.uptimeMillis()-start) + "ms"); 1853 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1854 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1855 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1856 } 1857 } 1858 1859 int num = 0; 1860 long[] tmp = new long[1]; 1861 do { 1862 ProcessRecord proc; 1863 int procState; 1864 int pid; 1865 long lastPssTime; 1866 synchronized (ActivityManagerService.this) { 1867 if (mPendingPssProcesses.size() <= 0) { 1868 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1869 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1870 mPendingPssProcesses.clear(); 1871 return; 1872 } 1873 proc = mPendingPssProcesses.remove(0); 1874 procState = proc.pssProcState; 1875 lastPssTime = proc.lastPssTime; 1876 if (proc.thread != null && procState == proc.setProcState 1877 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1878 < SystemClock.uptimeMillis()) { 1879 pid = proc.pid; 1880 } else { 1881 proc = null; 1882 pid = 0; 1883 } 1884 } 1885 if (proc != null) { 1886 long pss = Debug.getPss(pid, tmp, null); 1887 synchronized (ActivityManagerService.this) { 1888 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1889 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1890 num++; 1891 recordPssSample(proc, procState, pss, tmp[0], 1892 SystemClock.uptimeMillis()); 1893 } 1894 } 1895 } 1896 } while (true); 1897 } 1898 } 1899 } 1900 }; 1901 1902 public void setSystemProcess() { 1903 try { 1904 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1905 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1906 ServiceManager.addService("meminfo", new MemBinder(this)); 1907 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1908 ServiceManager.addService("dbinfo", new DbBinder(this)); 1909 if (MONITOR_CPU_USAGE) { 1910 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1911 } 1912 ServiceManager.addService("permission", new PermissionController(this)); 1913 1914 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1915 "android", STOCK_PM_FLAGS); 1916 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1917 1918 synchronized (this) { 1919 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1920 app.persistent = true; 1921 app.pid = MY_PID; 1922 app.maxAdj = ProcessList.SYSTEM_ADJ; 1923 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1924 mProcessNames.put(app.processName, app.uid, app); 1925 synchronized (mPidsSelfLocked) { 1926 mPidsSelfLocked.put(app.pid, app); 1927 } 1928 updateLruProcessLocked(app, false, null); 1929 updateOomAdjLocked(); 1930 } 1931 } catch (PackageManager.NameNotFoundException e) { 1932 throw new RuntimeException( 1933 "Unable to find android system package", e); 1934 } 1935 } 1936 1937 public void setWindowManager(WindowManagerService wm) { 1938 mWindowManager = wm; 1939 mStackSupervisor.setWindowManager(wm); 1940 } 1941 1942 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1943 mUsageStatsService = usageStatsManager; 1944 } 1945 1946 public void startObservingNativeCrashes() { 1947 final NativeCrashListener ncl = new NativeCrashListener(this); 1948 ncl.start(); 1949 } 1950 1951 public IAppOpsService getAppOpsService() { 1952 return mAppOpsService; 1953 } 1954 1955 static class MemBinder extends Binder { 1956 ActivityManagerService mActivityManagerService; 1957 MemBinder(ActivityManagerService activityManagerService) { 1958 mActivityManagerService = activityManagerService; 1959 } 1960 1961 @Override 1962 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1963 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1964 != PackageManager.PERMISSION_GRANTED) { 1965 pw.println("Permission Denial: can't dump meminfo from from pid=" 1966 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1967 + " without permission " + android.Manifest.permission.DUMP); 1968 return; 1969 } 1970 1971 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1972 } 1973 } 1974 1975 static class GraphicsBinder extends Binder { 1976 ActivityManagerService mActivityManagerService; 1977 GraphicsBinder(ActivityManagerService activityManagerService) { 1978 mActivityManagerService = activityManagerService; 1979 } 1980 1981 @Override 1982 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1983 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1984 != PackageManager.PERMISSION_GRANTED) { 1985 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1986 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1987 + " without permission " + android.Manifest.permission.DUMP); 1988 return; 1989 } 1990 1991 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1992 } 1993 } 1994 1995 static class DbBinder extends Binder { 1996 ActivityManagerService mActivityManagerService; 1997 DbBinder(ActivityManagerService activityManagerService) { 1998 mActivityManagerService = activityManagerService; 1999 } 2000 2001 @Override 2002 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2003 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2004 != PackageManager.PERMISSION_GRANTED) { 2005 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2006 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2007 + " without permission " + android.Manifest.permission.DUMP); 2008 return; 2009 } 2010 2011 mActivityManagerService.dumpDbInfo(fd, pw, args); 2012 } 2013 } 2014 2015 static class CpuBinder extends Binder { 2016 ActivityManagerService mActivityManagerService; 2017 CpuBinder(ActivityManagerService activityManagerService) { 2018 mActivityManagerService = activityManagerService; 2019 } 2020 2021 @Override 2022 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2023 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2024 != PackageManager.PERMISSION_GRANTED) { 2025 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2026 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2027 + " without permission " + android.Manifest.permission.DUMP); 2028 return; 2029 } 2030 2031 synchronized (mActivityManagerService.mProcessCpuTracker) { 2032 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2033 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2034 SystemClock.uptimeMillis())); 2035 } 2036 } 2037 } 2038 2039 public static final class Lifecycle extends SystemService { 2040 private final ActivityManagerService mService; 2041 2042 public Lifecycle(Context context) { 2043 super(context); 2044 mService = new ActivityManagerService(context); 2045 } 2046 2047 @Override 2048 public void onStart() { 2049 mService.start(); 2050 } 2051 2052 public ActivityManagerService getService() { 2053 return mService; 2054 } 2055 } 2056 2057 // Note: This method is invoked on the main thread but may need to attach various 2058 // handlers to other threads. So take care to be explicit about the looper. 2059 public ActivityManagerService(Context systemContext) { 2060 mContext = systemContext; 2061 mFactoryTest = FactoryTest.getMode(); 2062 mSystemThread = ActivityThread.currentActivityThread(); 2063 2064 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2065 2066 mHandlerThread = new ServiceThread(TAG, 2067 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2068 mHandlerThread.start(); 2069 mHandler = new MainHandler(mHandlerThread.getLooper()); 2070 2071 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2072 "foreground", BROADCAST_FG_TIMEOUT, false); 2073 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2074 "background", BROADCAST_BG_TIMEOUT, true); 2075 mBroadcastQueues[0] = mFgBroadcastQueue; 2076 mBroadcastQueues[1] = mBgBroadcastQueue; 2077 2078 mServices = new ActiveServices(this); 2079 mProviderMap = new ProviderMap(this); 2080 2081 // TODO: Move creation of battery stats service outside of activity manager service. 2082 File dataDir = Environment.getDataDirectory(); 2083 File systemDir = new File(dataDir, "system"); 2084 systemDir.mkdirs(); 2085 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2086 mBatteryStatsService.getActiveStatistics().readLocked(); 2087 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2088 mOnBattery = DEBUG_POWER ? true 2089 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2090 mBatteryStatsService.getActiveStatistics().setCallback(this); 2091 2092 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2093 2094 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2095 2096 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2097 2098 // User 0 is the first and only user that runs at boot. 2099 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2100 mUserLru.add(Integer.valueOf(0)); 2101 updateStartedUserArrayLocked(); 2102 2103 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2104 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2105 2106 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2107 2108 mConfiguration.setToDefaults(); 2109 mConfiguration.setLocale(Locale.getDefault()); 2110 2111 mConfigurationSeq = mConfiguration.seq = 1; 2112 mProcessCpuTracker.init(); 2113 2114 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2115 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2116 mStackSupervisor = new ActivityStackSupervisor(this); 2117 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2118 2119 mProcessCpuThread = new Thread("CpuTracker") { 2120 @Override 2121 public void run() { 2122 while (true) { 2123 try { 2124 try { 2125 synchronized(this) { 2126 final long now = SystemClock.uptimeMillis(); 2127 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2128 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2129 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2130 // + ", write delay=" + nextWriteDelay); 2131 if (nextWriteDelay < nextCpuDelay) { 2132 nextCpuDelay = nextWriteDelay; 2133 } 2134 if (nextCpuDelay > 0) { 2135 mProcessCpuMutexFree.set(true); 2136 this.wait(nextCpuDelay); 2137 } 2138 } 2139 } catch (InterruptedException e) { 2140 } 2141 updateCpuStatsNow(); 2142 } catch (Exception e) { 2143 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2144 } 2145 } 2146 } 2147 }; 2148 2149 Watchdog.getInstance().addMonitor(this); 2150 Watchdog.getInstance().addThread(mHandler); 2151 } 2152 2153 public void setSystemServiceManager(SystemServiceManager mgr) { 2154 mSystemServiceManager = mgr; 2155 } 2156 2157 public void setInstaller(Installer installer) { 2158 mInstaller = installer; 2159 } 2160 2161 private void start() { 2162 Process.removeAllProcessGroups(); 2163 mProcessCpuThread.start(); 2164 2165 mBatteryStatsService.publish(mContext); 2166 mAppOpsService.publish(mContext); 2167 Slog.d("AppOps", "AppOpsService published"); 2168 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2169 } 2170 2171 public void initPowerManagement() { 2172 mStackSupervisor.initPowerManagement(); 2173 mBatteryStatsService.initPowerManagement(); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuTracker) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<>(); 2347 2348 // Isolated processes won't get this optimization, so that we don't 2349 // violate the rules about which services they have access to. 2350 if (!isolated) { 2351 // Setup the application init args 2352 mAppBindArgs.put("package", ServiceManager.getService("package")); 2353 mAppBindArgs.put("window", ServiceManager.getService("window")); 2354 mAppBindArgs.put(Context.ALARM_SERVICE, 2355 ServiceManager.getService(Context.ALARM_SERVICE)); 2356 } 2357 } 2358 return mAppBindArgs; 2359 } 2360 2361 final void setFocusedActivityLocked(ActivityRecord r) { 2362 if (mFocusedActivity != r) { 2363 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2364 mFocusedActivity = r; 2365 if (r.task != null && r.task.voiceInteractor != null) { 2366 startRunningVoiceLocked(); 2367 } else { 2368 finishRunningVoiceLocked(); 2369 } 2370 mStackSupervisor.setFocusedStack(r); 2371 if (r != null) { 2372 mWindowManager.setFocusedApp(r.appToken, true); 2373 } 2374 applyUpdateLockStateLocked(r); 2375 } 2376 } 2377 2378 final void clearFocusedActivity(ActivityRecord r) { 2379 if (mFocusedActivity == r) { 2380 mFocusedActivity = null; 2381 } 2382 } 2383 2384 @Override 2385 public void setFocusedStack(int stackId) { 2386 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2387 synchronized (ActivityManagerService.this) { 2388 ActivityStack stack = mStackSupervisor.getStack(stackId); 2389 if (stack != null) { 2390 ActivityRecord r = stack.topRunningActivityLocked(null); 2391 if (r != null) { 2392 setFocusedActivityLocked(r); 2393 } 2394 } 2395 } 2396 } 2397 2398 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2399 @Override 2400 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2401 synchronized (ActivityManagerService.this) { 2402 if (listener != null) { 2403 mTaskStackListeners.register(listener); 2404 } 2405 } 2406 } 2407 2408 @Override 2409 public void notifyActivityDrawn(IBinder token) { 2410 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2411 synchronized (this) { 2412 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2413 if (r != null) { 2414 r.task.stack.notifyActivityDrawnLocked(r); 2415 } 2416 } 2417 } 2418 2419 final void applyUpdateLockStateLocked(ActivityRecord r) { 2420 // Modifications to the UpdateLock state are done on our handler, outside 2421 // the activity manager's locks. The new state is determined based on the 2422 // state *now* of the relevant activity record. The object is passed to 2423 // the handler solely for logging detail, not to be consulted/modified. 2424 final boolean nextState = r != null && r.immersive; 2425 mHandler.sendMessage( 2426 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2427 } 2428 2429 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2430 Message msg = Message.obtain(); 2431 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2432 msg.obj = r.task.askedCompatMode ? null : r; 2433 mHandler.sendMessage(msg); 2434 } 2435 2436 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2437 String what, Object obj, ProcessRecord srcApp) { 2438 app.lastActivityTime = now; 2439 2440 if (app.activities.size() > 0) { 2441 // Don't want to touch dependent processes that are hosting activities. 2442 return index; 2443 } 2444 2445 int lrui = mLruProcesses.lastIndexOf(app); 2446 if (lrui < 0) { 2447 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2448 + what + " " + obj + " from " + srcApp); 2449 return index; 2450 } 2451 2452 if (lrui >= index) { 2453 // Don't want to cause this to move dependent processes *back* in the 2454 // list as if they were less frequently used. 2455 return index; 2456 } 2457 2458 if (lrui >= mLruProcessActivityStart) { 2459 // Don't want to touch dependent processes that are hosting activities. 2460 return index; 2461 } 2462 2463 mLruProcesses.remove(lrui); 2464 if (index > 0) { 2465 index--; 2466 } 2467 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2468 + " in LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 return index; 2471 } 2472 2473 final void removeLruProcessLocked(ProcessRecord app) { 2474 int lrui = mLruProcesses.lastIndexOf(app); 2475 if (lrui >= 0) { 2476 if (!app.killed) { 2477 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2478 Process.killProcessQuiet(app.pid); 2479 Process.killProcessGroup(app.info.uid, app.pid); 2480 } 2481 if (lrui <= mLruProcessActivityStart) { 2482 mLruProcessActivityStart--; 2483 } 2484 if (lrui <= mLruProcessServiceStart) { 2485 mLruProcessServiceStart--; 2486 } 2487 mLruProcesses.remove(lrui); 2488 } 2489 } 2490 2491 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2492 ProcessRecord client) { 2493 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2494 || app.treatLikeActivity; 2495 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2496 if (!activityChange && hasActivity) { 2497 // The process has activities, so we are only allowing activity-based adjustments 2498 // to move it. It should be kept in the front of the list with other 2499 // processes that have activities, and we don't want those to change their 2500 // order except due to activity operations. 2501 return; 2502 } 2503 2504 mLruSeq++; 2505 final long now = SystemClock.uptimeMillis(); 2506 app.lastActivityTime = now; 2507 2508 // First a quick reject: if the app is already at the position we will 2509 // put it, then there is nothing to do. 2510 if (hasActivity) { 2511 final int N = mLruProcesses.size(); 2512 if (N > 0 && mLruProcesses.get(N-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2514 return; 2515 } 2516 } else { 2517 if (mLruProcessServiceStart > 0 2518 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2519 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2520 return; 2521 } 2522 } 2523 2524 int lrui = mLruProcesses.lastIndexOf(app); 2525 2526 if (app.persistent && lrui >= 0) { 2527 // We don't care about the position of persistent processes, as long as 2528 // they are in the list. 2529 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2530 return; 2531 } 2532 2533 /* In progress: compute new position first, so we can avoid doing work 2534 if the process is not actually going to move. Not yet working. 2535 int addIndex; 2536 int nextIndex; 2537 boolean inActivity = false, inService = false; 2538 if (hasActivity) { 2539 // Process has activities, put it at the very tipsy-top. 2540 addIndex = mLruProcesses.size(); 2541 nextIndex = mLruProcessServiceStart; 2542 inActivity = true; 2543 } else if (hasService) { 2544 // Process has services, put it at the top of the service list. 2545 addIndex = mLruProcessActivityStart; 2546 nextIndex = mLruProcessServiceStart; 2547 inActivity = true; 2548 inService = true; 2549 } else { 2550 // Process not otherwise of interest, it goes to the top of the non-service area. 2551 addIndex = mLruProcessServiceStart; 2552 if (client != null) { 2553 int clientIndex = mLruProcesses.lastIndexOf(client); 2554 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2555 + app); 2556 if (clientIndex >= 0 && addIndex > clientIndex) { 2557 addIndex = clientIndex; 2558 } 2559 } 2560 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2561 } 2562 2563 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2564 + mLruProcessActivityStart + "): " + app); 2565 */ 2566 2567 if (lrui >= 0) { 2568 if (lrui < mLruProcessActivityStart) { 2569 mLruProcessActivityStart--; 2570 } 2571 if (lrui < mLruProcessServiceStart) { 2572 mLruProcessServiceStart--; 2573 } 2574 /* 2575 if (addIndex > lrui) { 2576 addIndex--; 2577 } 2578 if (nextIndex > lrui) { 2579 nextIndex--; 2580 } 2581 */ 2582 mLruProcesses.remove(lrui); 2583 } 2584 2585 /* 2586 mLruProcesses.add(addIndex, app); 2587 if (inActivity) { 2588 mLruProcessActivityStart++; 2589 } 2590 if (inService) { 2591 mLruProcessActivityStart++; 2592 } 2593 */ 2594 2595 int nextIndex; 2596 if (hasActivity) { 2597 final int N = mLruProcesses.size(); 2598 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2599 // Process doesn't have activities, but has clients with 2600 // activities... move it up, but one below the top (the top 2601 // should always have a real activity). 2602 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2603 mLruProcesses.add(N-1, app); 2604 // To keep it from spamming the LRU list (by making a bunch of clients), 2605 // we will push down any other entries owned by the app. 2606 final int uid = app.info.uid; 2607 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2608 ProcessRecord subProc = mLruProcesses.get(i); 2609 if (subProc.info.uid == uid) { 2610 // We want to push this one down the list. If the process after 2611 // it is for the same uid, however, don't do so, because we don't 2612 // want them internally to be re-ordered. 2613 if (mLruProcesses.get(i-1).info.uid != uid) { 2614 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2615 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2616 ProcessRecord tmp = mLruProcesses.get(i); 2617 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2618 mLruProcesses.set(i-1, tmp); 2619 i--; 2620 } 2621 } else { 2622 // A gap, we can stop here. 2623 break; 2624 } 2625 } 2626 } else { 2627 // Process has activities, put it at the very tipsy-top. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2629 mLruProcesses.add(app); 2630 } 2631 nextIndex = mLruProcessServiceStart; 2632 } else if (hasService) { 2633 // Process has services, put it at the top of the service list. 2634 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2635 mLruProcesses.add(mLruProcessActivityStart, app); 2636 nextIndex = mLruProcessServiceStart; 2637 mLruProcessActivityStart++; 2638 } else { 2639 // Process not otherwise of interest, it goes to the top of the non-service area. 2640 int index = mLruProcessServiceStart; 2641 if (client != null) { 2642 // If there is a client, don't allow the process to be moved up higher 2643 // in the list than that client. 2644 int clientIndex = mLruProcesses.lastIndexOf(client); 2645 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2646 + " when updating " + app); 2647 if (clientIndex <= lrui) { 2648 // Don't allow the client index restriction to push it down farther in the 2649 // list than it already is. 2650 clientIndex = lrui; 2651 } 2652 if (clientIndex >= 0 && index > clientIndex) { 2653 index = clientIndex; 2654 } 2655 } 2656 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2657 mLruProcesses.add(index, app); 2658 nextIndex = index-1; 2659 mLruProcessActivityStart++; 2660 mLruProcessServiceStart++; 2661 } 2662 2663 // If the app is currently using a content provider or service, 2664 // bump those processes as well. 2665 for (int j=app.connections.size()-1; j>=0; j--) { 2666 ConnectionRecord cr = app.connections.valueAt(j); 2667 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2668 && cr.binding.service.app != null 2669 && cr.binding.service.app.lruSeq != mLruSeq 2670 && !cr.binding.service.app.persistent) { 2671 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2672 "service connection", cr, app); 2673 } 2674 } 2675 for (int j=app.conProviders.size()-1; j>=0; j--) { 2676 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2677 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2678 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2679 "provider reference", cpr, app); 2680 } 2681 } 2682 } 2683 2684 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2685 if (uid == Process.SYSTEM_UID) { 2686 // The system gets to run in any process. If there are multiple 2687 // processes with the same uid, just pick the first (this 2688 // should never happen). 2689 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2690 if (procs == null) return null; 2691 final int N = procs.size(); 2692 for (int i = 0; i < N; i++) { 2693 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2694 } 2695 } 2696 ProcessRecord proc = mProcessNames.get(processName, uid); 2697 if (false && proc != null && !keepIfLarge 2698 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2699 && proc.lastCachedPss >= 4000) { 2700 // Turn this condition on to cause killing to happen regularly, for testing. 2701 if (proc.baseProcessTracker != null) { 2702 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2703 } 2704 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2705 } else if (proc != null && !keepIfLarge 2706 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2707 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2708 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2709 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2710 if (proc.baseProcessTracker != null) { 2711 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2712 } 2713 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2714 } 2715 } 2716 return proc; 2717 } 2718 2719 void ensurePackageDexOpt(String packageName) { 2720 IPackageManager pm = AppGlobals.getPackageManager(); 2721 try { 2722 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2723 mDidDexOpt = true; 2724 } 2725 } catch (RemoteException e) { 2726 } 2727 } 2728 2729 boolean isNextTransitionForward() { 2730 int transit = mWindowManager.getPendingAppTransition(); 2731 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2732 || transit == AppTransition.TRANSIT_TASK_OPEN 2733 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2734 } 2735 2736 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2737 String processName, String abiOverride, int uid, Runnable crashHandler) { 2738 synchronized(this) { 2739 ApplicationInfo info = new ApplicationInfo(); 2740 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2741 // For isolated processes, the former contains the parent's uid and the latter the 2742 // actual uid of the isolated process. 2743 // In the special case introduced by this method (which is, starting an isolated 2744 // process directly from the SystemServer without an actual parent app process) the 2745 // closest thing to a parent's uid is SYSTEM_UID. 2746 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2747 // the |isolated| logic in the ProcessRecord constructor. 2748 info.uid = Process.SYSTEM_UID; 2749 info.processName = processName; 2750 info.className = entryPoint; 2751 info.packageName = "android"; 2752 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2753 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2754 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2755 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2756 crashHandler); 2757 return proc != null ? proc.pid : 0; 2758 } 2759 } 2760 2761 final ProcessRecord startProcessLocked(String processName, 2762 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2763 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2764 boolean isolated, boolean keepIfLarge) { 2765 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2766 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2767 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2768 null /* crashHandler */); 2769 } 2770 2771 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2772 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2773 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2774 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2775 long startTime = SystemClock.elapsedRealtime(); 2776 ProcessRecord app; 2777 if (!isolated) { 2778 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2779 checkTime(startTime, "startProcess: after getProcessRecord"); 2780 } else { 2781 // If this is an isolated process, it can't re-use an existing process. 2782 app = null; 2783 } 2784 // We don't have to do anything more if: 2785 // (1) There is an existing application record; and 2786 // (2) The caller doesn't think it is dead, OR there is no thread 2787 // object attached to it so we know it couldn't have crashed; and 2788 // (3) There is a pid assigned to it, so it is either starting or 2789 // already running. 2790 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2791 + " app=" + app + " knownToBeDead=" + knownToBeDead 2792 + " thread=" + (app != null ? app.thread : null) 2793 + " pid=" + (app != null ? app.pid : -1)); 2794 if (app != null && app.pid > 0) { 2795 if (!knownToBeDead || app.thread == null) { 2796 // We already have the app running, or are waiting for it to 2797 // come up (we have a pid but not yet its thread), so keep it. 2798 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2799 // If this is a new package in the process, add the package to the list 2800 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2801 checkTime(startTime, "startProcess: done, added package to proc"); 2802 return app; 2803 } 2804 2805 // An application record is attached to a previous process, 2806 // clean it up now. 2807 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2808 checkTime(startTime, "startProcess: bad proc running, killing"); 2809 Process.killProcessGroup(app.info.uid, app.pid); 2810 handleAppDiedLocked(app, true, true); 2811 checkTime(startTime, "startProcess: done killing old proc"); 2812 } 2813 2814 String hostingNameStr = hostingName != null 2815 ? hostingName.flattenToShortString() : null; 2816 2817 if (!isolated) { 2818 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2819 // If we are in the background, then check to see if this process 2820 // is bad. If so, we will just silently fail. 2821 if (mBadProcesses.get(info.processName, info.uid) != null) { 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2823 + "/" + info.processName); 2824 return null; 2825 } 2826 } else { 2827 // When the user is explicitly starting a process, then clear its 2828 // crash count so that we won't make it bad until they see at 2829 // least one crash dialog again, and make the process good again 2830 // if it had been bad. 2831 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2832 + "/" + info.processName); 2833 mProcessCrashTimes.remove(info.processName, info.uid); 2834 if (mBadProcesses.get(info.processName, info.uid) != null) { 2835 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2836 UserHandle.getUserId(info.uid), info.uid, 2837 info.processName); 2838 mBadProcesses.remove(info.processName, info.uid); 2839 if (app != null) { 2840 app.bad = false; 2841 } 2842 } 2843 } 2844 } 2845 2846 if (app == null) { 2847 checkTime(startTime, "startProcess: creating new process record"); 2848 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2849 if (app == null) { 2850 Slog.w(TAG, "Failed making new process record for " 2851 + processName + "/" + info.uid + " isolated=" + isolated); 2852 return null; 2853 } 2854 app.crashHandler = crashHandler; 2855 mProcessNames.put(processName, app.uid, app); 2856 if (isolated) { 2857 mIsolatedProcesses.put(app.uid, app); 2858 } 2859 checkTime(startTime, "startProcess: done creating new process record"); 2860 } else { 2861 // If this is a new package in the process, add the package to the list 2862 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2863 checkTime(startTime, "startProcess: added package to existing proc"); 2864 } 2865 2866 // If the system is not ready yet, then hold off on starting this 2867 // process until it is. 2868 if (!mProcessesReady 2869 && !isAllowedWhileBooting(info) 2870 && !allowWhileBooting) { 2871 if (!mProcessesOnHold.contains(app)) { 2872 mProcessesOnHold.add(app); 2873 } 2874 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2875 checkTime(startTime, "startProcess: returning with proc on hold"); 2876 return app; 2877 } 2878 2879 checkTime(startTime, "startProcess: stepping in to startProcess"); 2880 startProcessLocked( 2881 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2882 checkTime(startTime, "startProcess: done starting proc!"); 2883 return (app.pid != 0) ? app : null; 2884 } 2885 2886 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2887 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2888 } 2889 2890 private final void startProcessLocked(ProcessRecord app, 2891 String hostingType, String hostingNameStr) { 2892 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2893 null /* entryPoint */, null /* entryPointArgs */); 2894 } 2895 2896 private final void startProcessLocked(ProcessRecord app, String hostingType, 2897 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2898 long startTime = SystemClock.elapsedRealtime(); 2899 if (app.pid > 0 && app.pid != MY_PID) { 2900 checkTime(startTime, "startProcess: removing from pids map"); 2901 synchronized (mPidsSelfLocked) { 2902 mPidsSelfLocked.remove(app.pid); 2903 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2904 } 2905 checkTime(startTime, "startProcess: done removing from pids map"); 2906 app.setPid(0); 2907 } 2908 2909 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2910 "startProcessLocked removing on hold: " + app); 2911 mProcessesOnHold.remove(app); 2912 2913 checkTime(startTime, "startProcess: starting to update cpu stats"); 2914 updateCpuStats(); 2915 checkTime(startTime, "startProcess: done updating cpu stats"); 2916 2917 try { 2918 int uid = app.uid; 2919 2920 int[] gids = null; 2921 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2922 if (!app.isolated) { 2923 int[] permGids = null; 2924 try { 2925 checkTime(startTime, "startProcess: getting gids from package manager"); 2926 final PackageManager pm = mContext.getPackageManager(); 2927 permGids = pm.getPackageGids(app.info.packageName); 2928 2929 if (Environment.isExternalStorageEmulated()) { 2930 checkTime(startTime, "startProcess: checking external storage perm"); 2931 if (pm.checkPermission( 2932 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2933 app.info.packageName) == PERMISSION_GRANTED) { 2934 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2935 } else { 2936 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2937 } 2938 } 2939 } catch (PackageManager.NameNotFoundException e) { 2940 Slog.w(TAG, "Unable to retrieve gids", e); 2941 } 2942 2943 /* 2944 * Add shared application and profile GIDs so applications can share some 2945 * resources like shared libraries and access user-wide resources 2946 */ 2947 if (permGids == null) { 2948 gids = new int[2]; 2949 } else { 2950 gids = new int[permGids.length + 2]; 2951 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2952 } 2953 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2954 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2955 } 2956 checkTime(startTime, "startProcess: building args"); 2957 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2958 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2959 && mTopComponent != null 2960 && app.processName.equals(mTopComponent.getPackageName())) { 2961 uid = 0; 2962 } 2963 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2964 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2965 uid = 0; 2966 } 2967 } 2968 int debugFlags = 0; 2969 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2970 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2971 // Also turn on CheckJNI for debuggable apps. It's quite 2972 // awkward to turn on otherwise. 2973 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2974 } 2975 // Run the app in safe mode if its manifest requests so or the 2976 // system is booted in safe mode. 2977 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2978 mSafeMode == true) { 2979 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2980 } 2981 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2986 } 2987 if ("1".equals(SystemProperties.get("debug.assert"))) { 2988 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2989 } 2990 2991 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2992 if (requiredAbi == null) { 2993 requiredAbi = Build.SUPPORTED_ABIS[0]; 2994 } 2995 2996 String instructionSet = null; 2997 if (app.info.primaryCpuAbi != null) { 2998 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2999 } 3000 3001 app.gids = gids; 3002 app.requiredAbi = requiredAbi; 3003 app.instructionSet = instructionSet; 3004 3005 // Start the process. It will either succeed and return a result containing 3006 // the PID of the new process, or else throw a RuntimeException. 3007 boolean isActivityProcess = (entryPoint == null); 3008 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3009 checkTime(startTime, "startProcess: asking zygote to start proc"); 3010 Process.ProcessStartResult startResult = Process.start(entryPoint, 3011 app.processName, uid, uid, gids, debugFlags, mountExternal, 3012 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3013 app.info.dataDir, entryPointArgs); 3014 checkTime(startTime, "startProcess: returned from zygote!"); 3015 3016 if (app.isolated) { 3017 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3018 } 3019 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3020 checkTime(startTime, "startProcess: done updating battery stats"); 3021 3022 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3023 UserHandle.getUserId(uid), startResult.pid, uid, 3024 app.processName, hostingType, 3025 hostingNameStr != null ? hostingNameStr : ""); 3026 3027 if (app.persistent) { 3028 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3029 } 3030 3031 checkTime(startTime, "startProcess: building log message"); 3032 StringBuilder buf = mStringBuilder; 3033 buf.setLength(0); 3034 buf.append("Start proc "); 3035 buf.append(startResult.pid); 3036 buf.append(':'); 3037 buf.append(app.processName); 3038 buf.append('/'); 3039 UserHandle.formatUid(buf, uid); 3040 if (!isActivityProcess) { 3041 buf.append(" ["); 3042 buf.append(entryPoint); 3043 buf.append("]"); 3044 } 3045 buf.append(" for "); 3046 buf.append(hostingType); 3047 if (hostingNameStr != null) { 3048 buf.append(" "); 3049 buf.append(hostingNameStr); 3050 } 3051 Slog.i(TAG, buf.toString()); 3052 app.setPid(startResult.pid); 3053 app.usingWrapper = startResult.usingWrapper; 3054 app.removed = false; 3055 app.killed = false; 3056 app.killedByAm = false; 3057 checkTime(startTime, "startProcess: starting to update pids map"); 3058 synchronized (mPidsSelfLocked) { 3059 this.mPidsSelfLocked.put(startResult.pid, app); 3060 if (isActivityProcess) { 3061 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3062 msg.obj = app; 3063 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3064 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3065 } 3066 } 3067 checkTime(startTime, "startProcess: done updating pids map"); 3068 } catch (RuntimeException e) { 3069 // XXX do better error recovery. 3070 app.setPid(0); 3071 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3072 if (app.isolated) { 3073 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3074 } 3075 Slog.e(TAG, "Failure starting process " + app.processName, e); 3076 } 3077 } 3078 3079 void updateUsageStats(ActivityRecord component, boolean resumed) { 3080 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3081 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3082 if (resumed) { 3083 if (mUsageStatsService != null) { 3084 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3085 UsageEvents.Event.MOVE_TO_FOREGROUND); 3086 } 3087 synchronized (stats) { 3088 stats.noteActivityResumedLocked(component.app.uid); 3089 } 3090 } else { 3091 if (mUsageStatsService != null) { 3092 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3093 UsageEvents.Event.MOVE_TO_BACKGROUND); 3094 } 3095 synchronized (stats) { 3096 stats.noteActivityPausedLocked(component.app.uid); 3097 } 3098 } 3099 } 3100 3101 Intent getHomeIntent() { 3102 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3103 intent.setComponent(mTopComponent); 3104 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3105 intent.addCategory(Intent.CATEGORY_HOME); 3106 } 3107 return intent; 3108 } 3109 3110 boolean startHomeActivityLocked(int userId) { 3111 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3112 && mTopAction == null) { 3113 // We are running in factory test mode, but unable to find 3114 // the factory test app, so just sit around displaying the 3115 // error message and don't try to start anything. 3116 return false; 3117 } 3118 Intent intent = getHomeIntent(); 3119 ActivityInfo aInfo = 3120 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3121 if (aInfo != null) { 3122 intent.setComponent(new ComponentName( 3123 aInfo.applicationInfo.packageName, aInfo.name)); 3124 // Don't do this if the home app is currently being 3125 // instrumented. 3126 aInfo = new ActivityInfo(aInfo); 3127 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3128 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3129 aInfo.applicationInfo.uid, true); 3130 if (app == null || app.instrumentationClass == null) { 3131 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3132 mStackSupervisor.startHomeActivity(intent, aInfo); 3133 } 3134 } 3135 3136 return true; 3137 } 3138 3139 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3140 ActivityInfo ai = null; 3141 ComponentName comp = intent.getComponent(); 3142 try { 3143 if (comp != null) { 3144 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3145 } else { 3146 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3147 intent, 3148 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3149 flags, userId); 3150 3151 if (info != null) { 3152 ai = info.activityInfo; 3153 } 3154 } 3155 } catch (RemoteException e) { 3156 // ignore 3157 } 3158 3159 return ai; 3160 } 3161 3162 /** 3163 * Starts the "new version setup screen" if appropriate. 3164 */ 3165 void startSetupActivityLocked() { 3166 // Only do this once per boot. 3167 if (mCheckedForSetup) { 3168 return; 3169 } 3170 3171 // We will show this screen if the current one is a different 3172 // version than the last one shown, and we are not running in 3173 // low-level factory test mode. 3174 final ContentResolver resolver = mContext.getContentResolver(); 3175 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3176 Settings.Global.getInt(resolver, 3177 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3178 mCheckedForSetup = true; 3179 3180 // See if we should be showing the platform update setup UI. 3181 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3182 List<ResolveInfo> ris = mContext.getPackageManager() 3183 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3184 3185 // We don't allow third party apps to replace this. 3186 ResolveInfo ri = null; 3187 for (int i=0; ris != null && i<ris.size(); i++) { 3188 if ((ris.get(i).activityInfo.applicationInfo.flags 3189 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3190 ri = ris.get(i); 3191 break; 3192 } 3193 } 3194 3195 if (ri != null) { 3196 String vers = ri.activityInfo.metaData != null 3197 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3198 : null; 3199 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3200 vers = ri.activityInfo.applicationInfo.metaData.getString( 3201 Intent.METADATA_SETUP_VERSION); 3202 } 3203 String lastVers = Settings.Secure.getString( 3204 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3205 if (vers != null && !vers.equals(lastVers)) { 3206 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3207 intent.setComponent(new ComponentName( 3208 ri.activityInfo.packageName, ri.activityInfo.name)); 3209 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3210 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3211 null); 3212 } 3213 } 3214 } 3215 } 3216 3217 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3218 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3219 } 3220 3221 void enforceNotIsolatedCaller(String caller) { 3222 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3223 throw new SecurityException("Isolated process not allowed to call " + caller); 3224 } 3225 } 3226 3227 void enforceShellRestriction(String restriction, int userHandle) { 3228 if (Binder.getCallingUid() == Process.SHELL_UID) { 3229 if (userHandle < 0 3230 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3231 throw new SecurityException("Shell does not have permission to access user " 3232 + userHandle); 3233 } 3234 } 3235 } 3236 3237 @Override 3238 public int getFrontActivityScreenCompatMode() { 3239 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3240 synchronized (this) { 3241 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3242 } 3243 } 3244 3245 @Override 3246 public void setFrontActivityScreenCompatMode(int mode) { 3247 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3248 "setFrontActivityScreenCompatMode"); 3249 synchronized (this) { 3250 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3251 } 3252 } 3253 3254 @Override 3255 public int getPackageScreenCompatMode(String packageName) { 3256 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3257 synchronized (this) { 3258 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3259 } 3260 } 3261 3262 @Override 3263 public void setPackageScreenCompatMode(String packageName, int mode) { 3264 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3265 "setPackageScreenCompatMode"); 3266 synchronized (this) { 3267 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3268 } 3269 } 3270 3271 @Override 3272 public boolean getPackageAskScreenCompat(String packageName) { 3273 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3274 synchronized (this) { 3275 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3276 } 3277 } 3278 3279 @Override 3280 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3281 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3282 "setPackageAskScreenCompat"); 3283 synchronized (this) { 3284 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3285 } 3286 } 3287 3288 private void dispatchProcessesChanged() { 3289 int N; 3290 synchronized (this) { 3291 N = mPendingProcessChanges.size(); 3292 if (mActiveProcessChanges.length < N) { 3293 mActiveProcessChanges = new ProcessChangeItem[N]; 3294 } 3295 mPendingProcessChanges.toArray(mActiveProcessChanges); 3296 mAvailProcessChanges.addAll(mPendingProcessChanges); 3297 mPendingProcessChanges.clear(); 3298 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3299 } 3300 3301 int i = mProcessObservers.beginBroadcast(); 3302 while (i > 0) { 3303 i--; 3304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3305 if (observer != null) { 3306 try { 3307 for (int j=0; j<N; j++) { 3308 ProcessChangeItem item = mActiveProcessChanges[j]; 3309 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3310 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3311 + item.pid + " uid=" + item.uid + ": " 3312 + item.foregroundActivities); 3313 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3314 item.foregroundActivities); 3315 } 3316 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3317 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3318 + item.pid + " uid=" + item.uid + ": " + item.processState); 3319 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3320 } 3321 } 3322 } catch (RemoteException e) { 3323 } 3324 } 3325 } 3326 mProcessObservers.finishBroadcast(); 3327 } 3328 3329 private void dispatchProcessDied(int pid, int uid) { 3330 int i = mProcessObservers.beginBroadcast(); 3331 while (i > 0) { 3332 i--; 3333 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3334 if (observer != null) { 3335 try { 3336 observer.onProcessDied(pid, uid); 3337 } catch (RemoteException e) { 3338 } 3339 } 3340 } 3341 mProcessObservers.finishBroadcast(); 3342 } 3343 3344 @Override 3345 public final int startActivity(IApplicationThread caller, String callingPackage, 3346 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3347 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3348 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3349 resultWho, requestCode, startFlags, profilerInfo, options, 3350 UserHandle.getCallingUserId()); 3351 } 3352 3353 @Override 3354 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3355 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3356 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3357 enforceNotIsolatedCaller("startActivity"); 3358 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3359 false, ALLOW_FULL_ONLY, "startActivity", null); 3360 // TODO: Switch to user app stacks here. 3361 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3362 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3363 profilerInfo, null, null, options, userId, null, null); 3364 } 3365 3366 @Override 3367 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3368 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3369 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3370 3371 // This is very dangerous -- it allows you to perform a start activity (including 3372 // permission grants) as any app that may launch one of your own activities. So 3373 // we will only allow this to be done from activities that are part of the core framework, 3374 // and then only when they are running as the system. 3375 final ActivityRecord sourceRecord; 3376 final int targetUid; 3377 final String targetPackage; 3378 synchronized (this) { 3379 if (resultTo == null) { 3380 throw new SecurityException("Must be called from an activity"); 3381 } 3382 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3383 if (sourceRecord == null) { 3384 throw new SecurityException("Called with bad activity token: " + resultTo); 3385 } 3386 if (!sourceRecord.info.packageName.equals("android")) { 3387 throw new SecurityException( 3388 "Must be called from an activity that is declared in the android package"); 3389 } 3390 if (sourceRecord.app == null) { 3391 throw new SecurityException("Called without a process attached to activity"); 3392 } 3393 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3394 // This is still okay, as long as this activity is running under the 3395 // uid of the original calling activity. 3396 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3397 throw new SecurityException( 3398 "Calling activity in uid " + sourceRecord.app.uid 3399 + " must be system uid or original calling uid " 3400 + sourceRecord.launchedFromUid); 3401 } 3402 } 3403 targetUid = sourceRecord.launchedFromUid; 3404 targetPackage = sourceRecord.launchedFromPackage; 3405 } 3406 3407 if (userId == UserHandle.USER_NULL) { 3408 userId = UserHandle.getUserId(sourceRecord.app.uid); 3409 } 3410 3411 // TODO: Switch to user app stacks here. 3412 try { 3413 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3414 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3415 null, null, options, userId, null, null); 3416 return ret; 3417 } catch (SecurityException e) { 3418 // XXX need to figure out how to propagate to original app. 3419 // A SecurityException here is generally actually a fault of the original 3420 // calling activity (such as a fairly granting permissions), so propagate it 3421 // back to them. 3422 /* 3423 StringBuilder msg = new StringBuilder(); 3424 msg.append("While launching"); 3425 msg.append(intent.toString()); 3426 msg.append(": "); 3427 msg.append(e.getMessage()); 3428 */ 3429 throw e; 3430 } 3431 } 3432 3433 @Override 3434 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3435 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3436 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3437 enforceNotIsolatedCaller("startActivityAndWait"); 3438 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3439 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3440 WaitResult res = new WaitResult(); 3441 // TODO: Switch to user app stacks here. 3442 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3443 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3444 options, userId, null, null); 3445 return res; 3446 } 3447 3448 @Override 3449 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3450 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3451 int startFlags, Configuration config, Bundle options, int userId) { 3452 enforceNotIsolatedCaller("startActivityWithConfig"); 3453 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3454 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3455 // TODO: Switch to user app stacks here. 3456 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3457 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3458 null, null, config, options, userId, null, null); 3459 return ret; 3460 } 3461 3462 @Override 3463 public int startActivityIntentSender(IApplicationThread caller, 3464 IntentSender intent, Intent fillInIntent, String resolvedType, 3465 IBinder resultTo, String resultWho, int requestCode, 3466 int flagsMask, int flagsValues, Bundle options) { 3467 enforceNotIsolatedCaller("startActivityIntentSender"); 3468 // Refuse possible leaked file descriptors 3469 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3470 throw new IllegalArgumentException("File descriptors passed in Intent"); 3471 } 3472 3473 IIntentSender sender = intent.getTarget(); 3474 if (!(sender instanceof PendingIntentRecord)) { 3475 throw new IllegalArgumentException("Bad PendingIntent object"); 3476 } 3477 3478 PendingIntentRecord pir = (PendingIntentRecord)sender; 3479 3480 synchronized (this) { 3481 // If this is coming from the currently resumed activity, it is 3482 // effectively saying that app switches are allowed at this point. 3483 final ActivityStack stack = getFocusedStack(); 3484 if (stack.mResumedActivity != null && 3485 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3486 mAppSwitchesAllowedTime = 0; 3487 } 3488 } 3489 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3490 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3491 return ret; 3492 } 3493 3494 @Override 3495 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3496 Intent intent, String resolvedType, IVoiceInteractionSession session, 3497 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3498 Bundle options, int userId) { 3499 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3500 != PackageManager.PERMISSION_GRANTED) { 3501 String msg = "Permission Denial: startVoiceActivity() from pid=" 3502 + Binder.getCallingPid() 3503 + ", uid=" + Binder.getCallingUid() 3504 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3505 Slog.w(TAG, msg); 3506 throw new SecurityException(msg); 3507 } 3508 if (session == null || interactor == null) { 3509 throw new NullPointerException("null session or interactor"); 3510 } 3511 userId = handleIncomingUser(callingPid, callingUid, userId, 3512 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3513 // TODO: Switch to user app stacks here. 3514 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3515 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3516 null, options, userId, null, null); 3517 } 3518 3519 @Override 3520 public boolean startNextMatchingActivity(IBinder callingActivity, 3521 Intent intent, Bundle options) { 3522 // Refuse possible leaked file descriptors 3523 if (intent != null && intent.hasFileDescriptors() == true) { 3524 throw new IllegalArgumentException("File descriptors passed in Intent"); 3525 } 3526 3527 synchronized (this) { 3528 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3529 if (r == null) { 3530 ActivityOptions.abort(options); 3531 return false; 3532 } 3533 if (r.app == null || r.app.thread == null) { 3534 // The caller is not running... d'oh! 3535 ActivityOptions.abort(options); 3536 return false; 3537 } 3538 intent = new Intent(intent); 3539 // The caller is not allowed to change the data. 3540 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3541 // And we are resetting to find the next component... 3542 intent.setComponent(null); 3543 3544 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3545 3546 ActivityInfo aInfo = null; 3547 try { 3548 List<ResolveInfo> resolves = 3549 AppGlobals.getPackageManager().queryIntentActivities( 3550 intent, r.resolvedType, 3551 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3552 UserHandle.getCallingUserId()); 3553 3554 // Look for the original activity in the list... 3555 final int N = resolves != null ? resolves.size() : 0; 3556 for (int i=0; i<N; i++) { 3557 ResolveInfo rInfo = resolves.get(i); 3558 if (rInfo.activityInfo.packageName.equals(r.packageName) 3559 && rInfo.activityInfo.name.equals(r.info.name)) { 3560 // We found the current one... the next matching is 3561 // after it. 3562 i++; 3563 if (i<N) { 3564 aInfo = resolves.get(i).activityInfo; 3565 } 3566 if (debug) { 3567 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3568 + "/" + r.info.name); 3569 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3570 + "/" + aInfo.name); 3571 } 3572 break; 3573 } 3574 } 3575 } catch (RemoteException e) { 3576 } 3577 3578 if (aInfo == null) { 3579 // Nobody who is next! 3580 ActivityOptions.abort(options); 3581 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3582 return false; 3583 } 3584 3585 intent.setComponent(new ComponentName( 3586 aInfo.applicationInfo.packageName, aInfo.name)); 3587 intent.setFlags(intent.getFlags()&~( 3588 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3589 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3590 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3591 Intent.FLAG_ACTIVITY_NEW_TASK)); 3592 3593 // Okay now we need to start the new activity, replacing the 3594 // currently running activity. This is a little tricky because 3595 // we want to start the new one as if the current one is finished, 3596 // but not finish the current one first so that there is no flicker. 3597 // And thus... 3598 final boolean wasFinishing = r.finishing; 3599 r.finishing = true; 3600 3601 // Propagate reply information over to the new activity. 3602 final ActivityRecord resultTo = r.resultTo; 3603 final String resultWho = r.resultWho; 3604 final int requestCode = r.requestCode; 3605 r.resultTo = null; 3606 if (resultTo != null) { 3607 resultTo.removeResultsLocked(r, resultWho, requestCode); 3608 } 3609 3610 final long origId = Binder.clearCallingIdentity(); 3611 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3612 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3613 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3614 -1, r.launchedFromUid, 0, options, false, null, null, null); 3615 Binder.restoreCallingIdentity(origId); 3616 3617 r.finishing = wasFinishing; 3618 if (res != ActivityManager.START_SUCCESS) { 3619 return false; 3620 } 3621 return true; 3622 } 3623 } 3624 3625 @Override 3626 public final int startActivityFromRecents(int taskId, Bundle options) { 3627 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3628 String msg = "Permission Denial: startActivityFromRecents called without " + 3629 START_TASKS_FROM_RECENTS; 3630 Slog.w(TAG, msg); 3631 throw new SecurityException(msg); 3632 } 3633 return startActivityFromRecentsInner(taskId, options); 3634 } 3635 3636 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3637 final TaskRecord task; 3638 final int callingUid; 3639 final String callingPackage; 3640 final Intent intent; 3641 final int userId; 3642 synchronized (this) { 3643 task = recentTaskForIdLocked(taskId); 3644 if (task == null) { 3645 throw new IllegalArgumentException("Task " + taskId + " not found."); 3646 } 3647 if (task.getRootActivity() != null) { 3648 moveTaskToFrontLocked(task.taskId, 0, null); 3649 return ActivityManager.START_TASK_TO_FRONT; 3650 } 3651 callingUid = task.mCallingUid; 3652 callingPackage = task.mCallingPackage; 3653 intent = task.intent; 3654 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3655 userId = task.userId; 3656 } 3657 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3658 options, userId, null, task); 3659 } 3660 3661 final int startActivityInPackage(int uid, String callingPackage, 3662 Intent intent, String resolvedType, IBinder resultTo, 3663 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3664 IActivityContainer container, TaskRecord inTask) { 3665 3666 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3667 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3668 3669 // TODO: Switch to user app stacks here. 3670 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3671 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3672 null, null, null, options, userId, container, inTask); 3673 return ret; 3674 } 3675 3676 @Override 3677 public final int startActivities(IApplicationThread caller, String callingPackage, 3678 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3679 int userId) { 3680 enforceNotIsolatedCaller("startActivities"); 3681 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3682 false, ALLOW_FULL_ONLY, "startActivity", null); 3683 // TODO: Switch to user app stacks here. 3684 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3685 resolvedTypes, resultTo, options, userId); 3686 return ret; 3687 } 3688 3689 final int startActivitiesInPackage(int uid, String callingPackage, 3690 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3691 Bundle options, int userId) { 3692 3693 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3694 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3695 // TODO: Switch to user app stacks here. 3696 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3697 resultTo, options, userId); 3698 return ret; 3699 } 3700 3701 //explicitly remove thd old information in mRecentTasks when removing existing user. 3702 private void removeRecentTasksForUserLocked(int userId) { 3703 if(userId <= 0) { 3704 Slog.i(TAG, "Can't remove recent task on user " + userId); 3705 return; 3706 } 3707 3708 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3709 TaskRecord tr = mRecentTasks.get(i); 3710 if (tr.userId == userId) { 3711 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3712 + " when finishing user" + userId); 3713 mRecentTasks.remove(i); 3714 tr.removedFromRecents(); 3715 } 3716 } 3717 3718 // Remove tasks from persistent storage. 3719 notifyTaskPersisterLocked(null, true); 3720 } 3721 3722 // Sort by taskId 3723 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3724 @Override 3725 public int compare(TaskRecord lhs, TaskRecord rhs) { 3726 return rhs.taskId - lhs.taskId; 3727 } 3728 }; 3729 3730 // Extract the affiliates of the chain containing mRecentTasks[start]. 3731 private int processNextAffiliateChainLocked(int start) { 3732 final TaskRecord startTask = mRecentTasks.get(start); 3733 final int affiliateId = startTask.mAffiliatedTaskId; 3734 3735 // Quick identification of isolated tasks. I.e. those not launched behind. 3736 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3737 startTask.mNextAffiliate == null) { 3738 // There is still a slim chance that there are other tasks that point to this task 3739 // and that the chain is so messed up that this task no longer points to them but 3740 // the gain of this optimization outweighs the risk. 3741 startTask.inRecents = true; 3742 return start + 1; 3743 } 3744 3745 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3746 mTmpRecents.clear(); 3747 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3748 final TaskRecord task = mRecentTasks.get(i); 3749 if (task.mAffiliatedTaskId == affiliateId) { 3750 mRecentTasks.remove(i); 3751 mTmpRecents.add(task); 3752 } 3753 } 3754 3755 // Sort them all by taskId. That is the order they were create in and that order will 3756 // always be correct. 3757 Collections.sort(mTmpRecents, mTaskRecordComparator); 3758 3759 // Go through and fix up the linked list. 3760 // The first one is the end of the chain and has no next. 3761 final TaskRecord first = mTmpRecents.get(0); 3762 first.inRecents = true; 3763 if (first.mNextAffiliate != null) { 3764 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3765 first.setNextAffiliate(null); 3766 notifyTaskPersisterLocked(first, false); 3767 } 3768 // Everything in the middle is doubly linked from next to prev. 3769 final int tmpSize = mTmpRecents.size(); 3770 for (int i = 0; i < tmpSize - 1; ++i) { 3771 final TaskRecord next = mTmpRecents.get(i); 3772 final TaskRecord prev = mTmpRecents.get(i + 1); 3773 if (next.mPrevAffiliate != prev) { 3774 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3775 " setting prev=" + prev); 3776 next.setPrevAffiliate(prev); 3777 notifyTaskPersisterLocked(next, false); 3778 } 3779 if (prev.mNextAffiliate != next) { 3780 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3781 " setting next=" + next); 3782 prev.setNextAffiliate(next); 3783 notifyTaskPersisterLocked(prev, false); 3784 } 3785 prev.inRecents = true; 3786 } 3787 // The last one is the beginning of the list and has no prev. 3788 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3789 if (last.mPrevAffiliate != null) { 3790 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3791 last.setPrevAffiliate(null); 3792 notifyTaskPersisterLocked(last, false); 3793 } 3794 3795 // Insert the group back into mRecentTasks at start. 3796 mRecentTasks.addAll(start, mTmpRecents); 3797 3798 // Let the caller know where we left off. 3799 return start + tmpSize; 3800 } 3801 3802 /** 3803 * Update the recent tasks lists: make sure tasks should still be here (their 3804 * applications / activities still exist), update their availability, fixup ordering 3805 * of affiliations. 3806 */ 3807 void cleanupRecentTasksLocked(int userId) { 3808 if (mRecentTasks == null) { 3809 // Happens when called from the packagemanager broadcast before boot. 3810 return; 3811 } 3812 3813 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3814 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3815 final IPackageManager pm = AppGlobals.getPackageManager(); 3816 final ActivityInfo dummyAct = new ActivityInfo(); 3817 final ApplicationInfo dummyApp = new ApplicationInfo(); 3818 3819 int N = mRecentTasks.size(); 3820 3821 int[] users = userId == UserHandle.USER_ALL 3822 ? getUsersLocked() : new int[] { userId }; 3823 for (int user : users) { 3824 for (int i = 0; i < N; i++) { 3825 TaskRecord task = mRecentTasks.get(i); 3826 if (task.userId != user) { 3827 // Only look at tasks for the user ID of interest. 3828 continue; 3829 } 3830 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3831 // This situation is broken, and we should just get rid of it now. 3832 mRecentTasks.remove(i); 3833 task.removedFromRecents(); 3834 i--; 3835 N--; 3836 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3837 continue; 3838 } 3839 // Check whether this activity is currently available. 3840 if (task.realActivity != null) { 3841 ActivityInfo ai = availActCache.get(task.realActivity); 3842 if (ai == null) { 3843 try { 3844 ai = pm.getActivityInfo(task.realActivity, 3845 PackageManager.GET_UNINSTALLED_PACKAGES 3846 | PackageManager.GET_DISABLED_COMPONENTS, user); 3847 } catch (RemoteException e) { 3848 // Will never happen. 3849 continue; 3850 } 3851 if (ai == null) { 3852 ai = dummyAct; 3853 } 3854 availActCache.put(task.realActivity, ai); 3855 } 3856 if (ai == dummyAct) { 3857 // This could be either because the activity no longer exists, or the 3858 // app is temporarily gone. For the former we want to remove the recents 3859 // entry; for the latter we want to mark it as unavailable. 3860 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3861 if (app == null) { 3862 try { 3863 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3864 PackageManager.GET_UNINSTALLED_PACKAGES 3865 | PackageManager.GET_DISABLED_COMPONENTS, user); 3866 } catch (RemoteException e) { 3867 // Will never happen. 3868 continue; 3869 } 3870 if (app == null) { 3871 app = dummyApp; 3872 } 3873 availAppCache.put(task.realActivity.getPackageName(), app); 3874 } 3875 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3876 // Doesn't exist any more! Good-bye. 3877 mRecentTasks.remove(i); 3878 task.removedFromRecents(); 3879 i--; 3880 N--; 3881 Slog.w(TAG, "Removing no longer valid recent: " + task); 3882 continue; 3883 } else { 3884 // Otherwise just not available for now. 3885 if (task.isAvailable) { 3886 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3887 + task); 3888 } 3889 task.isAvailable = false; 3890 } 3891 } else { 3892 if (!ai.enabled || !ai.applicationInfo.enabled 3893 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3894 if (task.isAvailable) { 3895 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3896 + task + " (enabled=" + ai.enabled + "/" 3897 + ai.applicationInfo.enabled + " flags=" 3898 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3899 } 3900 task.isAvailable = false; 3901 } else { 3902 if (!task.isAvailable) { 3903 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3904 + task); 3905 } 3906 task.isAvailable = true; 3907 } 3908 } 3909 } 3910 } 3911 } 3912 3913 // Verify the affiliate chain for each task. 3914 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3915 } 3916 3917 mTmpRecents.clear(); 3918 // mRecentTasks is now in sorted, affiliated order. 3919 } 3920 3921 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3922 int N = mRecentTasks.size(); 3923 TaskRecord top = task; 3924 int topIndex = taskIndex; 3925 while (top.mNextAffiliate != null && topIndex > 0) { 3926 top = top.mNextAffiliate; 3927 topIndex--; 3928 } 3929 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3930 + topIndex + " from intial " + taskIndex); 3931 // Find the end of the chain, doing a sanity check along the way. 3932 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3933 int endIndex = topIndex; 3934 TaskRecord prev = top; 3935 while (endIndex < N) { 3936 TaskRecord cur = mRecentTasks.get(endIndex); 3937 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3938 + endIndex + " " + cur); 3939 if (cur == top) { 3940 // Verify start of the chain. 3941 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3942 Slog.wtf(TAG, "Bad chain @" + endIndex 3943 + ": first task has next affiliate: " + prev); 3944 sane = false; 3945 break; 3946 } 3947 } else { 3948 // Verify middle of the chain's next points back to the one before. 3949 if (cur.mNextAffiliate != prev 3950 || cur.mNextAffiliateTaskId != prev.taskId) { 3951 Slog.wtf(TAG, "Bad chain @" + endIndex 3952 + ": middle task " + cur + " @" + endIndex 3953 + " has bad next affiliate " 3954 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3955 + ", expected " + prev); 3956 sane = false; 3957 break; 3958 } 3959 } 3960 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3961 // Chain ends here. 3962 if (cur.mPrevAffiliate != null) { 3963 Slog.wtf(TAG, "Bad chain @" + endIndex 3964 + ": last task " + cur + " has previous affiliate " 3965 + cur.mPrevAffiliate); 3966 sane = false; 3967 } 3968 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3969 break; 3970 } else { 3971 // Verify middle of the chain's prev points to a valid item. 3972 if (cur.mPrevAffiliate == null) { 3973 Slog.wtf(TAG, "Bad chain @" + endIndex 3974 + ": task " + cur + " has previous affiliate " 3975 + cur.mPrevAffiliate + " but should be id " 3976 + cur.mPrevAffiliate); 3977 sane = false; 3978 break; 3979 } 3980 } 3981 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3982 Slog.wtf(TAG, "Bad chain @" + endIndex 3983 + ": task " + cur + " has affiliated id " 3984 + cur.mAffiliatedTaskId + " but should be " 3985 + task.mAffiliatedTaskId); 3986 sane = false; 3987 break; 3988 } 3989 prev = cur; 3990 endIndex++; 3991 if (endIndex >= N) { 3992 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3993 + ": last task " + prev); 3994 sane = false; 3995 break; 3996 } 3997 } 3998 if (sane) { 3999 if (endIndex < taskIndex) { 4000 Slog.wtf(TAG, "Bad chain @" + endIndex 4001 + ": did not extend to task " + task + " @" + taskIndex); 4002 sane = false; 4003 } 4004 } 4005 if (sane) { 4006 // All looks good, we can just move all of the affiliated tasks 4007 // to the top. 4008 for (int i=topIndex; i<=endIndex; i++) { 4009 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4010 + " from " + i + " to " + (i-topIndex)); 4011 TaskRecord cur = mRecentTasks.remove(i); 4012 mRecentTasks.add(i-topIndex, cur); 4013 } 4014 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4015 + " to " + endIndex); 4016 return true; 4017 } 4018 4019 // Whoops, couldn't do it. 4020 return false; 4021 } 4022 4023 final void addRecentTaskLocked(TaskRecord task) { 4024 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4025 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4026 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4027 4028 int N = mRecentTasks.size(); 4029 // Quick case: check if the top-most recent task is the same. 4030 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4031 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4032 return; 4033 } 4034 // Another quick case: check if this is part of a set of affiliated 4035 // tasks that are at the top. 4036 if (isAffiliated && N > 0 && task.inRecents 4037 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4038 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4039 + " at top when adding " + task); 4040 return; 4041 } 4042 // Another quick case: never add voice sessions. 4043 if (task.voiceSession != null) { 4044 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4045 return; 4046 } 4047 4048 boolean needAffiliationFix = false; 4049 4050 // Slightly less quick case: the task is already in recents, so all we need 4051 // to do is move it. 4052 if (task.inRecents) { 4053 int taskIndex = mRecentTasks.indexOf(task); 4054 if (taskIndex >= 0) { 4055 if (!isAffiliated) { 4056 // Simple case: this is not an affiliated task, so we just move it to the front. 4057 mRecentTasks.remove(taskIndex); 4058 mRecentTasks.add(0, task); 4059 notifyTaskPersisterLocked(task, false); 4060 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4061 + " from " + taskIndex); 4062 return; 4063 } else { 4064 // More complicated: need to keep all affiliated tasks together. 4065 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4066 // All went well. 4067 return; 4068 } 4069 4070 // Uh oh... something bad in the affiliation chain, try to rebuild 4071 // everything and then go through our general path of adding a new task. 4072 needAffiliationFix = true; 4073 } 4074 } else { 4075 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4076 needAffiliationFix = true; 4077 } 4078 } 4079 4080 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4081 trimRecentsForTaskLocked(task, true); 4082 4083 N = mRecentTasks.size(); 4084 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4085 final TaskRecord tr = mRecentTasks.remove(N - 1); 4086 tr.removedFromRecents(); 4087 N--; 4088 } 4089 task.inRecents = true; 4090 if (!isAffiliated || needAffiliationFix) { 4091 // If this is a simple non-affiliated task, or we had some failure trying to 4092 // handle it as part of an affilated task, then just place it at the top. 4093 mRecentTasks.add(0, task); 4094 } else if (isAffiliated) { 4095 // If this is a new affiliated task, then move all of the affiliated tasks 4096 // to the front and insert this new one. 4097 TaskRecord other = task.mNextAffiliate; 4098 if (other == null) { 4099 other = task.mPrevAffiliate; 4100 } 4101 if (other != null) { 4102 int otherIndex = mRecentTasks.indexOf(other); 4103 if (otherIndex >= 0) { 4104 // Insert new task at appropriate location. 4105 int taskIndex; 4106 if (other == task.mNextAffiliate) { 4107 // We found the index of our next affiliation, which is who is 4108 // before us in the list, so add after that point. 4109 taskIndex = otherIndex+1; 4110 } else { 4111 // We found the index of our previous affiliation, which is who is 4112 // after us in the list, so add at their position. 4113 taskIndex = otherIndex; 4114 } 4115 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4116 + taskIndex + ": " + task); 4117 mRecentTasks.add(taskIndex, task); 4118 4119 // Now move everything to the front. 4120 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4121 // All went well. 4122 return; 4123 } 4124 4125 // Uh oh... something bad in the affiliation chain, try to rebuild 4126 // everything and then go through our general path of adding a new task. 4127 needAffiliationFix = true; 4128 } else { 4129 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4130 + other); 4131 needAffiliationFix = true; 4132 } 4133 } else { 4134 if (DEBUG_RECENTS) Slog.d(TAG, 4135 "addRecent: adding affiliated task without next/prev:" + task); 4136 needAffiliationFix = true; 4137 } 4138 } 4139 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4140 4141 if (needAffiliationFix) { 4142 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4143 cleanupRecentTasksLocked(task.userId); 4144 } 4145 } 4146 4147 /** 4148 * If needed, remove oldest existing entries in recents that are for the same kind 4149 * of task as the given one. 4150 */ 4151 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4152 int N = mRecentTasks.size(); 4153 final Intent intent = task.intent; 4154 final boolean document = intent != null && intent.isDocument(); 4155 4156 int maxRecents = task.maxRecents - 1; 4157 for (int i=0; i<N; i++) { 4158 final TaskRecord tr = mRecentTasks.get(i); 4159 if (task != tr) { 4160 if (task.userId != tr.userId) { 4161 continue; 4162 } 4163 if (i > MAX_RECENT_BITMAPS) { 4164 tr.freeLastThumbnail(); 4165 } 4166 final Intent trIntent = tr.intent; 4167 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4168 (intent == null || !intent.filterEquals(trIntent))) { 4169 continue; 4170 } 4171 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4172 if (document && trIsDocument) { 4173 // These are the same document activity (not necessarily the same doc). 4174 if (maxRecents > 0) { 4175 --maxRecents; 4176 continue; 4177 } 4178 // Hit the maximum number of documents for this task. Fall through 4179 // and remove this document from recents. 4180 } else if (document || trIsDocument) { 4181 // Only one of these is a document. Not the droid we're looking for. 4182 continue; 4183 } 4184 } 4185 4186 if (!doTrim) { 4187 // If the caller is not actually asking for a trim, just tell them we reached 4188 // a point where the trim would happen. 4189 return i; 4190 } 4191 4192 // Either task and tr are the same or, their affinities match or their intents match 4193 // and neither of them is a document, or they are documents using the same activity 4194 // and their maxRecents has been reached. 4195 tr.disposeThumbnail(); 4196 mRecentTasks.remove(i); 4197 if (task != tr) { 4198 tr.removedFromRecents(); 4199 } 4200 i--; 4201 N--; 4202 if (task.intent == null) { 4203 // If the new recent task we are adding is not fully 4204 // specified, then replace it with the existing recent task. 4205 task = tr; 4206 } 4207 notifyTaskPersisterLocked(tr, false); 4208 } 4209 4210 return -1; 4211 } 4212 4213 @Override 4214 public void reportActivityFullyDrawn(IBinder token) { 4215 synchronized (this) { 4216 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4217 if (r == null) { 4218 return; 4219 } 4220 r.reportFullyDrawnLocked(); 4221 } 4222 } 4223 4224 @Override 4225 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4226 synchronized (this) { 4227 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4228 if (r == null) { 4229 return; 4230 } 4231 final long origId = Binder.clearCallingIdentity(); 4232 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4233 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4234 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4235 if (config != null) { 4236 r.frozenBeforeDestroy = true; 4237 if (!updateConfigurationLocked(config, r, false, false)) { 4238 mStackSupervisor.resumeTopActivitiesLocked(); 4239 } 4240 } 4241 Binder.restoreCallingIdentity(origId); 4242 } 4243 } 4244 4245 @Override 4246 public int getRequestedOrientation(IBinder token) { 4247 synchronized (this) { 4248 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4249 if (r == null) { 4250 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4251 } 4252 return mWindowManager.getAppOrientation(r.appToken); 4253 } 4254 } 4255 4256 /** 4257 * This is the internal entry point for handling Activity.finish(). 4258 * 4259 * @param token The Binder token referencing the Activity we want to finish. 4260 * @param resultCode Result code, if any, from this Activity. 4261 * @param resultData Result data (Intent), if any, from this Activity. 4262 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4263 * the root Activity in the task. 4264 * 4265 * @return Returns true if the activity successfully finished, or false if it is still running. 4266 */ 4267 @Override 4268 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4269 boolean finishTask) { 4270 // Refuse possible leaked file descriptors 4271 if (resultData != null && resultData.hasFileDescriptors() == true) { 4272 throw new IllegalArgumentException("File descriptors passed in Intent"); 4273 } 4274 4275 synchronized(this) { 4276 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4277 if (r == null) { 4278 return true; 4279 } 4280 // Keep track of the root activity of the task before we finish it 4281 TaskRecord tr = r.task; 4282 ActivityRecord rootR = tr.getRootActivity(); 4283 if (rootR == null) { 4284 Slog.w(TAG, "Finishing task with all activities already finished"); 4285 } 4286 // Do not allow task to finish in Lock Task mode. 4287 if (tr == mStackSupervisor.mLockTaskModeTask) { 4288 if (rootR == r) { 4289 Slog.i(TAG, "Not finishing task in lock task mode"); 4290 mStackSupervisor.showLockTaskToast(); 4291 return false; 4292 } 4293 } 4294 if (mController != null) { 4295 // Find the first activity that is not finishing. 4296 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4297 if (next != null) { 4298 // ask watcher if this is allowed 4299 boolean resumeOK = true; 4300 try { 4301 resumeOK = mController.activityResuming(next.packageName); 4302 } catch (RemoteException e) { 4303 mController = null; 4304 Watchdog.getInstance().setActivityController(null); 4305 } 4306 4307 if (!resumeOK) { 4308 Slog.i(TAG, "Not finishing activity because controller resumed"); 4309 return false; 4310 } 4311 } 4312 } 4313 final long origId = Binder.clearCallingIdentity(); 4314 try { 4315 boolean res; 4316 if (finishTask && r == rootR) { 4317 // If requested, remove the task that is associated to this activity only if it 4318 // was the root activity in the task. The result code and data is ignored 4319 // because we don't support returning them across task boundaries. 4320 res = removeTaskByIdLocked(tr.taskId, false); 4321 if (!res) { 4322 Slog.i(TAG, "Removing task failed to finish activity"); 4323 } 4324 } else { 4325 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4326 resultData, "app-request", true); 4327 if (!res) { 4328 Slog.i(TAG, "Failed to finish by app-request"); 4329 } 4330 } 4331 return res; 4332 } finally { 4333 Binder.restoreCallingIdentity(origId); 4334 } 4335 } 4336 } 4337 4338 @Override 4339 public final void finishHeavyWeightApp() { 4340 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4341 != PackageManager.PERMISSION_GRANTED) { 4342 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4343 + Binder.getCallingPid() 4344 + ", uid=" + Binder.getCallingUid() 4345 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4346 Slog.w(TAG, msg); 4347 throw new SecurityException(msg); 4348 } 4349 4350 synchronized(this) { 4351 if (mHeavyWeightProcess == null) { 4352 return; 4353 } 4354 4355 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4356 mHeavyWeightProcess.activities); 4357 for (int i=0; i<activities.size(); i++) { 4358 ActivityRecord r = activities.get(i); 4359 if (!r.finishing) { 4360 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4361 null, "finish-heavy", true); 4362 } 4363 } 4364 4365 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4366 mHeavyWeightProcess.userId, 0)); 4367 mHeavyWeightProcess = null; 4368 } 4369 } 4370 4371 @Override 4372 public void crashApplication(int uid, int initialPid, String packageName, 4373 String message) { 4374 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4375 != PackageManager.PERMISSION_GRANTED) { 4376 String msg = "Permission Denial: crashApplication() from pid=" 4377 + Binder.getCallingPid() 4378 + ", uid=" + Binder.getCallingUid() 4379 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4380 Slog.w(TAG, msg); 4381 throw new SecurityException(msg); 4382 } 4383 4384 synchronized(this) { 4385 ProcessRecord proc = null; 4386 4387 // Figure out which process to kill. We don't trust that initialPid 4388 // still has any relation to current pids, so must scan through the 4389 // list. 4390 synchronized (mPidsSelfLocked) { 4391 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4392 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4393 if (p.uid != uid) { 4394 continue; 4395 } 4396 if (p.pid == initialPid) { 4397 proc = p; 4398 break; 4399 } 4400 if (p.pkgList.containsKey(packageName)) { 4401 proc = p; 4402 } 4403 } 4404 } 4405 4406 if (proc == null) { 4407 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4408 + " initialPid=" + initialPid 4409 + " packageName=" + packageName); 4410 return; 4411 } 4412 4413 if (proc.thread != null) { 4414 if (proc.pid == Process.myPid()) { 4415 Log.w(TAG, "crashApplication: trying to crash self!"); 4416 return; 4417 } 4418 long ident = Binder.clearCallingIdentity(); 4419 try { 4420 proc.thread.scheduleCrash(message); 4421 } catch (RemoteException e) { 4422 } 4423 Binder.restoreCallingIdentity(ident); 4424 } 4425 } 4426 } 4427 4428 @Override 4429 public final void finishSubActivity(IBinder token, String resultWho, 4430 int requestCode) { 4431 synchronized(this) { 4432 final long origId = Binder.clearCallingIdentity(); 4433 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4434 if (r != null) { 4435 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4436 } 4437 Binder.restoreCallingIdentity(origId); 4438 } 4439 } 4440 4441 @Override 4442 public boolean finishActivityAffinity(IBinder token) { 4443 synchronized(this) { 4444 final long origId = Binder.clearCallingIdentity(); 4445 try { 4446 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4447 4448 ActivityRecord rootR = r.task.getRootActivity(); 4449 // Do not allow task to finish in Lock Task mode. 4450 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4451 if (rootR == r) { 4452 mStackSupervisor.showLockTaskToast(); 4453 return false; 4454 } 4455 } 4456 boolean res = false; 4457 if (r != null) { 4458 res = r.task.stack.finishActivityAffinityLocked(r); 4459 } 4460 return res; 4461 } finally { 4462 Binder.restoreCallingIdentity(origId); 4463 } 4464 } 4465 } 4466 4467 @Override 4468 public void finishVoiceTask(IVoiceInteractionSession session) { 4469 synchronized(this) { 4470 final long origId = Binder.clearCallingIdentity(); 4471 try { 4472 mStackSupervisor.finishVoiceTask(session); 4473 } finally { 4474 Binder.restoreCallingIdentity(origId); 4475 } 4476 } 4477 4478 } 4479 4480 @Override 4481 public boolean releaseActivityInstance(IBinder token) { 4482 synchronized(this) { 4483 final long origId = Binder.clearCallingIdentity(); 4484 try { 4485 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4486 if (r.task == null || r.task.stack == null) { 4487 return false; 4488 } 4489 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4490 } finally { 4491 Binder.restoreCallingIdentity(origId); 4492 } 4493 } 4494 } 4495 4496 @Override 4497 public void releaseSomeActivities(IApplicationThread appInt) { 4498 synchronized(this) { 4499 final long origId = Binder.clearCallingIdentity(); 4500 try { 4501 ProcessRecord app = getRecordForAppLocked(appInt); 4502 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4503 } finally { 4504 Binder.restoreCallingIdentity(origId); 4505 } 4506 } 4507 } 4508 4509 @Override 4510 public boolean willActivityBeVisible(IBinder token) { 4511 synchronized(this) { 4512 ActivityStack stack = ActivityRecord.getStackLocked(token); 4513 if (stack != null) { 4514 return stack.willActivityBeVisibleLocked(token); 4515 } 4516 return false; 4517 } 4518 } 4519 4520 @Override 4521 public void overridePendingTransition(IBinder token, String packageName, 4522 int enterAnim, int exitAnim) { 4523 synchronized(this) { 4524 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4525 if (self == null) { 4526 return; 4527 } 4528 4529 final long origId = Binder.clearCallingIdentity(); 4530 4531 if (self.state == ActivityState.RESUMED 4532 || self.state == ActivityState.PAUSING) { 4533 mWindowManager.overridePendingAppTransition(packageName, 4534 enterAnim, exitAnim, null); 4535 } 4536 4537 Binder.restoreCallingIdentity(origId); 4538 } 4539 } 4540 4541 /** 4542 * Main function for removing an existing process from the activity manager 4543 * as a result of that process going away. Clears out all connections 4544 * to the process. 4545 */ 4546 private final void handleAppDiedLocked(ProcessRecord app, 4547 boolean restarting, boolean allowRestart) { 4548 int pid = app.pid; 4549 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4550 if (!kept && !restarting) { 4551 removeLruProcessLocked(app); 4552 if (pid > 0) { 4553 ProcessList.remove(pid); 4554 } 4555 } 4556 4557 if (mProfileProc == app) { 4558 clearProfilerLocked(); 4559 } 4560 4561 // Remove this application's activities from active lists. 4562 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4563 4564 app.activities.clear(); 4565 4566 if (app.instrumentationClass != null) { 4567 Slog.w(TAG, "Crash of app " + app.processName 4568 + " running instrumentation " + app.instrumentationClass); 4569 Bundle info = new Bundle(); 4570 info.putString("shortMsg", "Process crashed."); 4571 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4572 } 4573 4574 if (!restarting) { 4575 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4576 // If there was nothing to resume, and we are not already 4577 // restarting this process, but there is a visible activity that 4578 // is hosted by the process... then make sure all visible 4579 // activities are running, taking care of restarting this 4580 // process. 4581 if (hasVisibleActivities) { 4582 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4583 } 4584 } 4585 } 4586 } 4587 4588 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4589 IBinder threadBinder = thread.asBinder(); 4590 // Find the application record. 4591 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4592 ProcessRecord rec = mLruProcesses.get(i); 4593 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4594 return i; 4595 } 4596 } 4597 return -1; 4598 } 4599 4600 final ProcessRecord getRecordForAppLocked( 4601 IApplicationThread thread) { 4602 if (thread == null) { 4603 return null; 4604 } 4605 4606 int appIndex = getLRURecordIndexForAppLocked(thread); 4607 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4608 } 4609 4610 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4611 // If there are no longer any background processes running, 4612 // and the app that died was not running instrumentation, 4613 // then tell everyone we are now low on memory. 4614 boolean haveBg = false; 4615 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4616 ProcessRecord rec = mLruProcesses.get(i); 4617 if (rec.thread != null 4618 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4619 haveBg = true; 4620 break; 4621 } 4622 } 4623 4624 if (!haveBg) { 4625 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4626 if (doReport) { 4627 long now = SystemClock.uptimeMillis(); 4628 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4629 doReport = false; 4630 } else { 4631 mLastMemUsageReportTime = now; 4632 } 4633 } 4634 final ArrayList<ProcessMemInfo> memInfos 4635 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4636 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4637 long now = SystemClock.uptimeMillis(); 4638 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4639 ProcessRecord rec = mLruProcesses.get(i); 4640 if (rec == dyingProc || rec.thread == null) { 4641 continue; 4642 } 4643 if (doReport) { 4644 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4645 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4646 } 4647 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4648 // The low memory report is overriding any current 4649 // state for a GC request. Make sure to do 4650 // heavy/important/visible/foreground processes first. 4651 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4652 rec.lastRequestedGc = 0; 4653 } else { 4654 rec.lastRequestedGc = rec.lastLowMemory; 4655 } 4656 rec.reportLowMemory = true; 4657 rec.lastLowMemory = now; 4658 mProcessesToGc.remove(rec); 4659 addProcessToGcListLocked(rec); 4660 } 4661 } 4662 if (doReport) { 4663 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4664 mHandler.sendMessage(msg); 4665 } 4666 scheduleAppGcsLocked(); 4667 } 4668 } 4669 4670 final void appDiedLocked(ProcessRecord app) { 4671 appDiedLocked(app, app.pid, app.thread); 4672 } 4673 4674 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4675 // First check if this ProcessRecord is actually active for the pid. 4676 synchronized (mPidsSelfLocked) { 4677 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4678 if (curProc != app) { 4679 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4680 return; 4681 } 4682 } 4683 4684 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4685 synchronized (stats) { 4686 stats.noteProcessDiedLocked(app.info.uid, pid); 4687 } 4688 4689 if (!app.killed) { 4690 Process.killProcessQuiet(pid); 4691 Process.killProcessGroup(app.info.uid, pid); 4692 app.killed = true; 4693 } 4694 4695 // Clean up already done if the process has been re-started. 4696 if (app.pid == pid && app.thread != null && 4697 app.thread.asBinder() == thread.asBinder()) { 4698 boolean doLowMem = app.instrumentationClass == null; 4699 boolean doOomAdj = doLowMem; 4700 if (!app.killedByAm) { 4701 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4702 + ") has died"); 4703 mAllowLowerMemLevel = true; 4704 } else { 4705 // Note that we always want to do oom adj to update our state with the 4706 // new number of procs. 4707 mAllowLowerMemLevel = false; 4708 doLowMem = false; 4709 } 4710 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4711 if (DEBUG_CLEANUP) Slog.v( 4712 TAG, "Dying app: " + app + ", pid: " + pid 4713 + ", thread: " + thread.asBinder()); 4714 handleAppDiedLocked(app, false, true); 4715 4716 if (doOomAdj) { 4717 updateOomAdjLocked(); 4718 } 4719 if (doLowMem) { 4720 doLowMemReportIfNeededLocked(app); 4721 } 4722 } else if (app.pid != pid) { 4723 // A new process has already been started. 4724 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4725 + ") has died and restarted (pid " + app.pid + ")."); 4726 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4727 } else if (DEBUG_PROCESSES) { 4728 Slog.d(TAG, "Received spurious death notification for thread " 4729 + thread.asBinder()); 4730 } 4731 } 4732 4733 /** 4734 * If a stack trace dump file is configured, dump process stack traces. 4735 * @param clearTraces causes the dump file to be erased prior to the new 4736 * traces being written, if true; when false, the new traces will be 4737 * appended to any existing file content. 4738 * @param firstPids of dalvik VM processes to dump stack traces for first 4739 * @param lastPids of dalvik VM processes to dump stack traces for last 4740 * @param nativeProcs optional list of native process names to dump stack crawls 4741 * @return file containing stack traces, or null if no dump file is configured 4742 */ 4743 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4744 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4745 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4746 if (tracesPath == null || tracesPath.length() == 0) { 4747 return null; 4748 } 4749 4750 File tracesFile = new File(tracesPath); 4751 try { 4752 File tracesDir = tracesFile.getParentFile(); 4753 if (!tracesDir.exists()) { 4754 tracesDir.mkdirs(); 4755 if (!SELinux.restorecon(tracesDir)) { 4756 return null; 4757 } 4758 } 4759 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4760 4761 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4762 tracesFile.createNewFile(); 4763 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4764 } catch (IOException e) { 4765 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4766 return null; 4767 } 4768 4769 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4770 return tracesFile; 4771 } 4772 4773 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4774 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4775 // Use a FileObserver to detect when traces finish writing. 4776 // The order of traces is considered important to maintain for legibility. 4777 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4778 @Override 4779 public synchronized void onEvent(int event, String path) { notify(); } 4780 }; 4781 4782 try { 4783 observer.startWatching(); 4784 4785 // First collect all of the stacks of the most important pids. 4786 if (firstPids != null) { 4787 try { 4788 int num = firstPids.size(); 4789 for (int i = 0; i < num; i++) { 4790 synchronized (observer) { 4791 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4792 observer.wait(200); // Wait for write-close, give up after 200msec 4793 } 4794 } 4795 } catch (InterruptedException e) { 4796 Slog.wtf(TAG, e); 4797 } 4798 } 4799 4800 // Next collect the stacks of the native pids 4801 if (nativeProcs != null) { 4802 int[] pids = Process.getPidsForCommands(nativeProcs); 4803 if (pids != null) { 4804 for (int pid : pids) { 4805 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4806 } 4807 } 4808 } 4809 4810 // Lastly, measure CPU usage. 4811 if (processCpuTracker != null) { 4812 processCpuTracker.init(); 4813 System.gc(); 4814 processCpuTracker.update(); 4815 try { 4816 synchronized (processCpuTracker) { 4817 processCpuTracker.wait(500); // measure over 1/2 second. 4818 } 4819 } catch (InterruptedException e) { 4820 } 4821 processCpuTracker.update(); 4822 4823 // We'll take the stack crawls of just the top apps using CPU. 4824 final int N = processCpuTracker.countWorkingStats(); 4825 int numProcs = 0; 4826 for (int i=0; i<N && numProcs<5; i++) { 4827 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4828 if (lastPids.indexOfKey(stats.pid) >= 0) { 4829 numProcs++; 4830 try { 4831 synchronized (observer) { 4832 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4833 observer.wait(200); // Wait for write-close, give up after 200msec 4834 } 4835 } catch (InterruptedException e) { 4836 Slog.wtf(TAG, e); 4837 } 4838 4839 } 4840 } 4841 } 4842 } finally { 4843 observer.stopWatching(); 4844 } 4845 } 4846 4847 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4848 if (true || IS_USER_BUILD) { 4849 return; 4850 } 4851 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4852 if (tracesPath == null || tracesPath.length() == 0) { 4853 return; 4854 } 4855 4856 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4857 StrictMode.allowThreadDiskWrites(); 4858 try { 4859 final File tracesFile = new File(tracesPath); 4860 final File tracesDir = tracesFile.getParentFile(); 4861 final File tracesTmp = new File(tracesDir, "__tmp__"); 4862 try { 4863 if (!tracesDir.exists()) { 4864 tracesDir.mkdirs(); 4865 if (!SELinux.restorecon(tracesDir.getPath())) { 4866 return; 4867 } 4868 } 4869 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4870 4871 if (tracesFile.exists()) { 4872 tracesTmp.delete(); 4873 tracesFile.renameTo(tracesTmp); 4874 } 4875 StringBuilder sb = new StringBuilder(); 4876 Time tobj = new Time(); 4877 tobj.set(System.currentTimeMillis()); 4878 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4879 sb.append(": "); 4880 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4881 sb.append(" since "); 4882 sb.append(msg); 4883 FileOutputStream fos = new FileOutputStream(tracesFile); 4884 fos.write(sb.toString().getBytes()); 4885 if (app == null) { 4886 fos.write("\n*** No application process!".getBytes()); 4887 } 4888 fos.close(); 4889 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4890 } catch (IOException e) { 4891 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4892 return; 4893 } 4894 4895 if (app != null) { 4896 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4897 firstPids.add(app.pid); 4898 dumpStackTraces(tracesPath, firstPids, null, null, null); 4899 } 4900 4901 File lastTracesFile = null; 4902 File curTracesFile = null; 4903 for (int i=9; i>=0; i--) { 4904 String name = String.format(Locale.US, "slow%02d.txt", i); 4905 curTracesFile = new File(tracesDir, name); 4906 if (curTracesFile.exists()) { 4907 if (lastTracesFile != null) { 4908 curTracesFile.renameTo(lastTracesFile); 4909 } else { 4910 curTracesFile.delete(); 4911 } 4912 } 4913 lastTracesFile = curTracesFile; 4914 } 4915 tracesFile.renameTo(curTracesFile); 4916 if (tracesTmp.exists()) { 4917 tracesTmp.renameTo(tracesFile); 4918 } 4919 } finally { 4920 StrictMode.setThreadPolicy(oldPolicy); 4921 } 4922 } 4923 4924 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4925 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4926 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4927 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4928 4929 if (mController != null) { 4930 try { 4931 // 0 == continue, -1 = kill process immediately 4932 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4933 if (res < 0 && app.pid != MY_PID) { 4934 app.kill("anr", true); 4935 } 4936 } catch (RemoteException e) { 4937 mController = null; 4938 Watchdog.getInstance().setActivityController(null); 4939 } 4940 } 4941 4942 long anrTime = SystemClock.uptimeMillis(); 4943 if (MONITOR_CPU_USAGE) { 4944 updateCpuStatsNow(); 4945 } 4946 4947 synchronized (this) { 4948 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4949 if (mShuttingDown) { 4950 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4951 return; 4952 } else if (app.notResponding) { 4953 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4954 return; 4955 } else if (app.crashing) { 4956 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4957 return; 4958 } 4959 4960 // In case we come through here for the same app before completing 4961 // this one, mark as anring now so we will bail out. 4962 app.notResponding = true; 4963 4964 // Log the ANR to the event log. 4965 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4966 app.processName, app.info.flags, annotation); 4967 4968 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4969 firstPids.add(app.pid); 4970 4971 int parentPid = app.pid; 4972 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4973 if (parentPid != app.pid) firstPids.add(parentPid); 4974 4975 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4976 4977 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4978 ProcessRecord r = mLruProcesses.get(i); 4979 if (r != null && r.thread != null) { 4980 int pid = r.pid; 4981 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4982 if (r.persistent) { 4983 firstPids.add(pid); 4984 } else { 4985 lastPids.put(pid, Boolean.TRUE); 4986 } 4987 } 4988 } 4989 } 4990 } 4991 4992 // Log the ANR to the main log. 4993 StringBuilder info = new StringBuilder(); 4994 info.setLength(0); 4995 info.append("ANR in ").append(app.processName); 4996 if (activity != null && activity.shortComponentName != null) { 4997 info.append(" (").append(activity.shortComponentName).append(")"); 4998 } 4999 info.append("\n"); 5000 info.append("PID: ").append(app.pid).append("\n"); 5001 if (annotation != null) { 5002 info.append("Reason: ").append(annotation).append("\n"); 5003 } 5004 if (parent != null && parent != activity) { 5005 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5006 } 5007 5008 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5009 5010 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5011 NATIVE_STACKS_OF_INTEREST); 5012 5013 String cpuInfo = null; 5014 if (MONITOR_CPU_USAGE) { 5015 updateCpuStatsNow(); 5016 synchronized (mProcessCpuTracker) { 5017 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5018 } 5019 info.append(processCpuTracker.printCurrentLoad()); 5020 info.append(cpuInfo); 5021 } 5022 5023 info.append(processCpuTracker.printCurrentState(anrTime)); 5024 5025 Slog.e(TAG, info.toString()); 5026 if (tracesFile == null) { 5027 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5028 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5029 } 5030 5031 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5032 cpuInfo, tracesFile, null); 5033 5034 if (mController != null) { 5035 try { 5036 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5037 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5038 if (res != 0) { 5039 if (res < 0 && app.pid != MY_PID) { 5040 app.kill("anr", true); 5041 } else { 5042 synchronized (this) { 5043 mServices.scheduleServiceTimeoutLocked(app); 5044 } 5045 } 5046 return; 5047 } 5048 } catch (RemoteException e) { 5049 mController = null; 5050 Watchdog.getInstance().setActivityController(null); 5051 } 5052 } 5053 5054 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5055 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5056 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5057 5058 synchronized (this) { 5059 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5060 5061 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5062 app.kill("bg anr", true); 5063 return; 5064 } 5065 5066 // Set the app's notResponding state, and look up the errorReportReceiver 5067 makeAppNotRespondingLocked(app, 5068 activity != null ? activity.shortComponentName : null, 5069 annotation != null ? "ANR " + annotation : "ANR", 5070 info.toString()); 5071 5072 // Bring up the infamous App Not Responding dialog 5073 Message msg = Message.obtain(); 5074 HashMap<String, Object> map = new HashMap<String, Object>(); 5075 msg.what = SHOW_NOT_RESPONDING_MSG; 5076 msg.obj = map; 5077 msg.arg1 = aboveSystem ? 1 : 0; 5078 map.put("app", app); 5079 if (activity != null) { 5080 map.put("activity", activity); 5081 } 5082 5083 mHandler.sendMessage(msg); 5084 } 5085 } 5086 5087 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5088 if (!mLaunchWarningShown) { 5089 mLaunchWarningShown = true; 5090 mHandler.post(new Runnable() { 5091 @Override 5092 public void run() { 5093 synchronized (ActivityManagerService.this) { 5094 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5095 d.show(); 5096 mHandler.postDelayed(new Runnable() { 5097 @Override 5098 public void run() { 5099 synchronized (ActivityManagerService.this) { 5100 d.dismiss(); 5101 mLaunchWarningShown = false; 5102 } 5103 } 5104 }, 4000); 5105 } 5106 } 5107 }); 5108 } 5109 } 5110 5111 @Override 5112 public boolean clearApplicationUserData(final String packageName, 5113 final IPackageDataObserver observer, int userId) { 5114 enforceNotIsolatedCaller("clearApplicationUserData"); 5115 int uid = Binder.getCallingUid(); 5116 int pid = Binder.getCallingPid(); 5117 userId = handleIncomingUser(pid, uid, 5118 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5119 long callingId = Binder.clearCallingIdentity(); 5120 try { 5121 IPackageManager pm = AppGlobals.getPackageManager(); 5122 int pkgUid = -1; 5123 synchronized(this) { 5124 try { 5125 pkgUid = pm.getPackageUid(packageName, userId); 5126 } catch (RemoteException e) { 5127 } 5128 if (pkgUid == -1) { 5129 Slog.w(TAG, "Invalid packageName: " + packageName); 5130 if (observer != null) { 5131 try { 5132 observer.onRemoveCompleted(packageName, false); 5133 } catch (RemoteException e) { 5134 Slog.i(TAG, "Observer no longer exists."); 5135 } 5136 } 5137 return false; 5138 } 5139 if (uid == pkgUid || checkComponentPermission( 5140 android.Manifest.permission.CLEAR_APP_USER_DATA, 5141 pid, uid, -1, true) 5142 == PackageManager.PERMISSION_GRANTED) { 5143 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5144 } else { 5145 throw new SecurityException("PID " + pid + " does not have permission " 5146 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5147 + " of package " + packageName); 5148 } 5149 5150 // Remove all tasks match the cleared application package and user 5151 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5152 final TaskRecord tr = mRecentTasks.get(i); 5153 final String taskPackageName = 5154 tr.getBaseIntent().getComponent().getPackageName(); 5155 if (tr.userId != userId) continue; 5156 if (!taskPackageName.equals(packageName)) continue; 5157 removeTaskByIdLocked(tr.taskId, false); 5158 } 5159 } 5160 5161 try { 5162 // Clear application user data 5163 pm.clearApplicationUserData(packageName, observer, userId); 5164 5165 synchronized(this) { 5166 // Remove all permissions granted from/to this package 5167 removeUriPermissionsForPackageLocked(packageName, userId, true); 5168 } 5169 5170 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5171 Uri.fromParts("package", packageName, null)); 5172 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5173 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5174 null, null, 0, null, null, null, false, false, userId); 5175 } catch (RemoteException e) { 5176 } 5177 } finally { 5178 Binder.restoreCallingIdentity(callingId); 5179 } 5180 return true; 5181 } 5182 5183 @Override 5184 public void killBackgroundProcesses(final String packageName, int userId) { 5185 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5186 != PackageManager.PERMISSION_GRANTED && 5187 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5188 != PackageManager.PERMISSION_GRANTED) { 5189 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5190 + Binder.getCallingPid() 5191 + ", uid=" + Binder.getCallingUid() 5192 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5193 Slog.w(TAG, msg); 5194 throw new SecurityException(msg); 5195 } 5196 5197 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5198 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5199 long callingId = Binder.clearCallingIdentity(); 5200 try { 5201 IPackageManager pm = AppGlobals.getPackageManager(); 5202 synchronized(this) { 5203 int appId = -1; 5204 try { 5205 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5206 } catch (RemoteException e) { 5207 } 5208 if (appId == -1) { 5209 Slog.w(TAG, "Invalid packageName: " + packageName); 5210 return; 5211 } 5212 killPackageProcessesLocked(packageName, appId, userId, 5213 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5214 } 5215 } finally { 5216 Binder.restoreCallingIdentity(callingId); 5217 } 5218 } 5219 5220 @Override 5221 public void killAllBackgroundProcesses() { 5222 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5223 != PackageManager.PERMISSION_GRANTED) { 5224 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5225 + Binder.getCallingPid() 5226 + ", uid=" + Binder.getCallingUid() 5227 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5228 Slog.w(TAG, msg); 5229 throw new SecurityException(msg); 5230 } 5231 5232 long callingId = Binder.clearCallingIdentity(); 5233 try { 5234 synchronized(this) { 5235 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5236 final int NP = mProcessNames.getMap().size(); 5237 for (int ip=0; ip<NP; ip++) { 5238 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5239 final int NA = apps.size(); 5240 for (int ia=0; ia<NA; ia++) { 5241 ProcessRecord app = apps.valueAt(ia); 5242 if (app.persistent) { 5243 // we don't kill persistent processes 5244 continue; 5245 } 5246 if (app.removed) { 5247 procs.add(app); 5248 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5249 app.removed = true; 5250 procs.add(app); 5251 } 5252 } 5253 } 5254 5255 int N = procs.size(); 5256 for (int i=0; i<N; i++) { 5257 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5258 } 5259 mAllowLowerMemLevel = true; 5260 updateOomAdjLocked(); 5261 doLowMemReportIfNeededLocked(null); 5262 } 5263 } finally { 5264 Binder.restoreCallingIdentity(callingId); 5265 } 5266 } 5267 5268 @Override 5269 public void forceStopPackage(final String packageName, int userId) { 5270 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5271 != PackageManager.PERMISSION_GRANTED) { 5272 String msg = "Permission Denial: forceStopPackage() from pid=" 5273 + Binder.getCallingPid() 5274 + ", uid=" + Binder.getCallingUid() 5275 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5276 Slog.w(TAG, msg); 5277 throw new SecurityException(msg); 5278 } 5279 final int callingPid = Binder.getCallingPid(); 5280 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5281 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5282 long callingId = Binder.clearCallingIdentity(); 5283 try { 5284 IPackageManager pm = AppGlobals.getPackageManager(); 5285 synchronized(this) { 5286 int[] users = userId == UserHandle.USER_ALL 5287 ? getUsersLocked() : new int[] { userId }; 5288 for (int user : users) { 5289 int pkgUid = -1; 5290 try { 5291 pkgUid = pm.getPackageUid(packageName, user); 5292 } catch (RemoteException e) { 5293 } 5294 if (pkgUid == -1) { 5295 Slog.w(TAG, "Invalid packageName: " + packageName); 5296 continue; 5297 } 5298 try { 5299 pm.setPackageStoppedState(packageName, true, user); 5300 } catch (RemoteException e) { 5301 } catch (IllegalArgumentException e) { 5302 Slog.w(TAG, "Failed trying to unstop package " 5303 + packageName + ": " + e); 5304 } 5305 if (isUserRunningLocked(user, false)) { 5306 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5307 } 5308 } 5309 } 5310 } finally { 5311 Binder.restoreCallingIdentity(callingId); 5312 } 5313 } 5314 5315 @Override 5316 public void addPackageDependency(String packageName) { 5317 synchronized (this) { 5318 int callingPid = Binder.getCallingPid(); 5319 if (callingPid == Process.myPid()) { 5320 // Yeah, um, no. 5321 return; 5322 } 5323 ProcessRecord proc; 5324 synchronized (mPidsSelfLocked) { 5325 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5326 } 5327 if (proc != null) { 5328 if (proc.pkgDeps == null) { 5329 proc.pkgDeps = new ArraySet<String>(1); 5330 } 5331 proc.pkgDeps.add(packageName); 5332 } 5333 } 5334 } 5335 5336 /* 5337 * The pkg name and app id have to be specified. 5338 */ 5339 @Override 5340 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5341 if (pkg == null) { 5342 return; 5343 } 5344 // Make sure the uid is valid. 5345 if (appid < 0) { 5346 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5347 return; 5348 } 5349 int callerUid = Binder.getCallingUid(); 5350 // Only the system server can kill an application 5351 if (callerUid == Process.SYSTEM_UID) { 5352 // Post an aysnc message to kill the application 5353 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5354 msg.arg1 = appid; 5355 msg.arg2 = 0; 5356 Bundle bundle = new Bundle(); 5357 bundle.putString("pkg", pkg); 5358 bundle.putString("reason", reason); 5359 msg.obj = bundle; 5360 mHandler.sendMessage(msg); 5361 } else { 5362 throw new SecurityException(callerUid + " cannot kill pkg: " + 5363 pkg); 5364 } 5365 } 5366 5367 @Override 5368 public void closeSystemDialogs(String reason) { 5369 enforceNotIsolatedCaller("closeSystemDialogs"); 5370 5371 final int pid = Binder.getCallingPid(); 5372 final int uid = Binder.getCallingUid(); 5373 final long origId = Binder.clearCallingIdentity(); 5374 try { 5375 synchronized (this) { 5376 // Only allow this from foreground processes, so that background 5377 // applications can't abuse it to prevent system UI from being shown. 5378 if (uid >= Process.FIRST_APPLICATION_UID) { 5379 ProcessRecord proc; 5380 synchronized (mPidsSelfLocked) { 5381 proc = mPidsSelfLocked.get(pid); 5382 } 5383 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5384 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5385 + " from background process " + proc); 5386 return; 5387 } 5388 } 5389 closeSystemDialogsLocked(reason); 5390 } 5391 } finally { 5392 Binder.restoreCallingIdentity(origId); 5393 } 5394 } 5395 5396 void closeSystemDialogsLocked(String reason) { 5397 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5398 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5399 | Intent.FLAG_RECEIVER_FOREGROUND); 5400 if (reason != null) { 5401 intent.putExtra("reason", reason); 5402 } 5403 mWindowManager.closeSystemDialogs(reason); 5404 5405 mStackSupervisor.closeSystemDialogsLocked(); 5406 5407 broadcastIntentLocked(null, null, intent, null, 5408 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5409 Process.SYSTEM_UID, UserHandle.USER_ALL); 5410 } 5411 5412 @Override 5413 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5414 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5415 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5416 for (int i=pids.length-1; i>=0; i--) { 5417 ProcessRecord proc; 5418 int oomAdj; 5419 synchronized (this) { 5420 synchronized (mPidsSelfLocked) { 5421 proc = mPidsSelfLocked.get(pids[i]); 5422 oomAdj = proc != null ? proc.setAdj : 0; 5423 } 5424 } 5425 infos[i] = new Debug.MemoryInfo(); 5426 Debug.getMemoryInfo(pids[i], infos[i]); 5427 if (proc != null) { 5428 synchronized (this) { 5429 if (proc.thread != null && proc.setAdj == oomAdj) { 5430 // Record this for posterity if the process has been stable. 5431 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5432 infos[i].getTotalUss(), false, proc.pkgList); 5433 } 5434 } 5435 } 5436 } 5437 return infos; 5438 } 5439 5440 @Override 5441 public long[] getProcessPss(int[] pids) { 5442 enforceNotIsolatedCaller("getProcessPss"); 5443 long[] pss = new long[pids.length]; 5444 for (int i=pids.length-1; i>=0; i--) { 5445 ProcessRecord proc; 5446 int oomAdj; 5447 synchronized (this) { 5448 synchronized (mPidsSelfLocked) { 5449 proc = mPidsSelfLocked.get(pids[i]); 5450 oomAdj = proc != null ? proc.setAdj : 0; 5451 } 5452 } 5453 long[] tmpUss = new long[1]; 5454 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5455 if (proc != null) { 5456 synchronized (this) { 5457 if (proc.thread != null && proc.setAdj == oomAdj) { 5458 // Record this for posterity if the process has been stable. 5459 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5460 } 5461 } 5462 } 5463 } 5464 return pss; 5465 } 5466 5467 @Override 5468 public void killApplicationProcess(String processName, int uid) { 5469 if (processName == null) { 5470 return; 5471 } 5472 5473 int callerUid = Binder.getCallingUid(); 5474 // Only the system server can kill an application 5475 if (callerUid == Process.SYSTEM_UID) { 5476 synchronized (this) { 5477 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5478 if (app != null && app.thread != null) { 5479 try { 5480 app.thread.scheduleSuicide(); 5481 } catch (RemoteException e) { 5482 // If the other end already died, then our work here is done. 5483 } 5484 } else { 5485 Slog.w(TAG, "Process/uid not found attempting kill of " 5486 + processName + " / " + uid); 5487 } 5488 } 5489 } else { 5490 throw new SecurityException(callerUid + " cannot kill app process: " + 5491 processName); 5492 } 5493 } 5494 5495 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5496 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5497 false, true, false, false, UserHandle.getUserId(uid), reason); 5498 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5499 Uri.fromParts("package", packageName, null)); 5500 if (!mProcessesReady) { 5501 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5502 | Intent.FLAG_RECEIVER_FOREGROUND); 5503 } 5504 intent.putExtra(Intent.EXTRA_UID, uid); 5505 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5506 broadcastIntentLocked(null, null, intent, 5507 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5508 false, false, 5509 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5510 } 5511 5512 private void forceStopUserLocked(int userId, String reason) { 5513 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5514 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5515 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5516 | Intent.FLAG_RECEIVER_FOREGROUND); 5517 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5518 broadcastIntentLocked(null, null, intent, 5519 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5520 false, false, 5521 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5522 } 5523 5524 private final boolean killPackageProcessesLocked(String packageName, int appId, 5525 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5526 boolean doit, boolean evenPersistent, String reason) { 5527 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5528 5529 // Remove all processes this package may have touched: all with the 5530 // same UID (except for the system or root user), and all whose name 5531 // matches the package name. 5532 final int NP = mProcessNames.getMap().size(); 5533 for (int ip=0; ip<NP; ip++) { 5534 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5535 final int NA = apps.size(); 5536 for (int ia=0; ia<NA; ia++) { 5537 ProcessRecord app = apps.valueAt(ia); 5538 if (app.persistent && !evenPersistent) { 5539 // we don't kill persistent processes 5540 continue; 5541 } 5542 if (app.removed) { 5543 if (doit) { 5544 procs.add(app); 5545 } 5546 continue; 5547 } 5548 5549 // Skip process if it doesn't meet our oom adj requirement. 5550 if (app.setAdj < minOomAdj) { 5551 continue; 5552 } 5553 5554 // If no package is specified, we call all processes under the 5555 // give user id. 5556 if (packageName == null) { 5557 if (app.userId != userId) { 5558 continue; 5559 } 5560 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5561 continue; 5562 } 5563 // Package has been specified, we want to hit all processes 5564 // that match it. We need to qualify this by the processes 5565 // that are running under the specified app and user ID. 5566 } else { 5567 final boolean isDep = app.pkgDeps != null 5568 && app.pkgDeps.contains(packageName); 5569 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5570 continue; 5571 } 5572 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5573 continue; 5574 } 5575 if (!app.pkgList.containsKey(packageName) && !isDep) { 5576 continue; 5577 } 5578 } 5579 5580 // Process has passed all conditions, kill it! 5581 if (!doit) { 5582 return true; 5583 } 5584 app.removed = true; 5585 procs.add(app); 5586 } 5587 } 5588 5589 int N = procs.size(); 5590 for (int i=0; i<N; i++) { 5591 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5592 } 5593 updateOomAdjLocked(); 5594 return N > 0; 5595 } 5596 5597 private final boolean forceStopPackageLocked(String name, int appId, 5598 boolean callerWillRestart, boolean purgeCache, boolean doit, 5599 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5600 int i; 5601 int N; 5602 5603 if (userId == UserHandle.USER_ALL && name == null) { 5604 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5605 } 5606 5607 if (appId < 0 && name != null) { 5608 try { 5609 appId = UserHandle.getAppId( 5610 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5611 } catch (RemoteException e) { 5612 } 5613 } 5614 5615 if (doit) { 5616 if (name != null) { 5617 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5618 + " user=" + userId + ": " + reason); 5619 } else { 5620 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5621 } 5622 5623 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5624 for (int ip=pmap.size()-1; ip>=0; ip--) { 5625 SparseArray<Long> ba = pmap.valueAt(ip); 5626 for (i=ba.size()-1; i>=0; i--) { 5627 boolean remove = false; 5628 final int entUid = ba.keyAt(i); 5629 if (name != null) { 5630 if (userId == UserHandle.USER_ALL) { 5631 if (UserHandle.getAppId(entUid) == appId) { 5632 remove = true; 5633 } 5634 } else { 5635 if (entUid == UserHandle.getUid(userId, appId)) { 5636 remove = true; 5637 } 5638 } 5639 } else if (UserHandle.getUserId(entUid) == userId) { 5640 remove = true; 5641 } 5642 if (remove) { 5643 ba.removeAt(i); 5644 } 5645 } 5646 if (ba.size() == 0) { 5647 pmap.removeAt(ip); 5648 } 5649 } 5650 } 5651 5652 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5653 -100, callerWillRestart, true, doit, evenPersistent, 5654 name == null ? ("stop user " + userId) : ("stop " + name)); 5655 5656 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5657 if (!doit) { 5658 return true; 5659 } 5660 didSomething = true; 5661 } 5662 5663 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5664 if (!doit) { 5665 return true; 5666 } 5667 didSomething = true; 5668 } 5669 5670 if (name == null) { 5671 // Remove all sticky broadcasts from this user. 5672 mStickyBroadcasts.remove(userId); 5673 } 5674 5675 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5676 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5677 userId, providers)) { 5678 if (!doit) { 5679 return true; 5680 } 5681 didSomething = true; 5682 } 5683 N = providers.size(); 5684 for (i=0; i<N; i++) { 5685 removeDyingProviderLocked(null, providers.get(i), true); 5686 } 5687 5688 // Remove transient permissions granted from/to this package/user 5689 removeUriPermissionsForPackageLocked(name, userId, false); 5690 5691 if (name == null || uninstalling) { 5692 // Remove pending intents. For now we only do this when force 5693 // stopping users, because we have some problems when doing this 5694 // for packages -- app widgets are not currently cleaned up for 5695 // such packages, so they can be left with bad pending intents. 5696 if (mIntentSenderRecords.size() > 0) { 5697 Iterator<WeakReference<PendingIntentRecord>> it 5698 = mIntentSenderRecords.values().iterator(); 5699 while (it.hasNext()) { 5700 WeakReference<PendingIntentRecord> wpir = it.next(); 5701 if (wpir == null) { 5702 it.remove(); 5703 continue; 5704 } 5705 PendingIntentRecord pir = wpir.get(); 5706 if (pir == null) { 5707 it.remove(); 5708 continue; 5709 } 5710 if (name == null) { 5711 // Stopping user, remove all objects for the user. 5712 if (pir.key.userId != userId) { 5713 // Not the same user, skip it. 5714 continue; 5715 } 5716 } else { 5717 if (UserHandle.getAppId(pir.uid) != appId) { 5718 // Different app id, skip it. 5719 continue; 5720 } 5721 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5722 // Different user, skip it. 5723 continue; 5724 } 5725 if (!pir.key.packageName.equals(name)) { 5726 // Different package, skip it. 5727 continue; 5728 } 5729 } 5730 if (!doit) { 5731 return true; 5732 } 5733 didSomething = true; 5734 it.remove(); 5735 pir.canceled = true; 5736 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5737 pir.key.activity.pendingResults.remove(pir.ref); 5738 } 5739 } 5740 } 5741 } 5742 5743 if (doit) { 5744 if (purgeCache && name != null) { 5745 AttributeCache ac = AttributeCache.instance(); 5746 if (ac != null) { 5747 ac.removePackage(name); 5748 } 5749 } 5750 if (mBooted) { 5751 mStackSupervisor.resumeTopActivitiesLocked(); 5752 mStackSupervisor.scheduleIdleLocked(); 5753 } 5754 } 5755 5756 return didSomething; 5757 } 5758 5759 private final boolean removeProcessLocked(ProcessRecord app, 5760 boolean callerWillRestart, boolean allowRestart, String reason) { 5761 final String name = app.processName; 5762 final int uid = app.uid; 5763 if (DEBUG_PROCESSES) Slog.d( 5764 TAG, "Force removing proc " + app.toShortString() + " (" + name 5765 + "/" + uid + ")"); 5766 5767 mProcessNames.remove(name, uid); 5768 mIsolatedProcesses.remove(app.uid); 5769 if (mHeavyWeightProcess == app) { 5770 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5771 mHeavyWeightProcess.userId, 0)); 5772 mHeavyWeightProcess = null; 5773 } 5774 boolean needRestart = false; 5775 if (app.pid > 0 && app.pid != MY_PID) { 5776 int pid = app.pid; 5777 synchronized (mPidsSelfLocked) { 5778 mPidsSelfLocked.remove(pid); 5779 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5780 } 5781 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5782 if (app.isolated) { 5783 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5784 } 5785 app.kill(reason, true); 5786 handleAppDiedLocked(app, true, allowRestart); 5787 removeLruProcessLocked(app); 5788 5789 if (app.persistent && !app.isolated) { 5790 if (!callerWillRestart) { 5791 addAppLocked(app.info, false, null /* ABI override */); 5792 } else { 5793 needRestart = true; 5794 } 5795 } 5796 } else { 5797 mRemovedProcesses.add(app); 5798 } 5799 5800 return needRestart; 5801 } 5802 5803 private final void processStartTimedOutLocked(ProcessRecord app) { 5804 final int pid = app.pid; 5805 boolean gone = false; 5806 synchronized (mPidsSelfLocked) { 5807 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5808 if (knownApp != null && knownApp.thread == null) { 5809 mPidsSelfLocked.remove(pid); 5810 gone = true; 5811 } 5812 } 5813 5814 if (gone) { 5815 Slog.w(TAG, "Process " + app + " failed to attach"); 5816 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5817 pid, app.uid, app.processName); 5818 mProcessNames.remove(app.processName, app.uid); 5819 mIsolatedProcesses.remove(app.uid); 5820 if (mHeavyWeightProcess == app) { 5821 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5822 mHeavyWeightProcess.userId, 0)); 5823 mHeavyWeightProcess = null; 5824 } 5825 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5826 if (app.isolated) { 5827 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5828 } 5829 // Take care of any launching providers waiting for this process. 5830 checkAppInLaunchingProvidersLocked(app, true); 5831 // Take care of any services that are waiting for the process. 5832 mServices.processStartTimedOutLocked(app); 5833 app.kill("start timeout", true); 5834 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5835 Slog.w(TAG, "Unattached app died before backup, skipping"); 5836 try { 5837 IBackupManager bm = IBackupManager.Stub.asInterface( 5838 ServiceManager.getService(Context.BACKUP_SERVICE)); 5839 bm.agentDisconnected(app.info.packageName); 5840 } catch (RemoteException e) { 5841 // Can't happen; the backup manager is local 5842 } 5843 } 5844 if (isPendingBroadcastProcessLocked(pid)) { 5845 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5846 skipPendingBroadcastLocked(pid); 5847 } 5848 } else { 5849 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5850 } 5851 } 5852 5853 private final boolean attachApplicationLocked(IApplicationThread thread, 5854 int pid) { 5855 5856 // Find the application record that is being attached... either via 5857 // the pid if we are running in multiple processes, or just pull the 5858 // next app record if we are emulating process with anonymous threads. 5859 ProcessRecord app; 5860 if (pid != MY_PID && pid >= 0) { 5861 synchronized (mPidsSelfLocked) { 5862 app = mPidsSelfLocked.get(pid); 5863 } 5864 } else { 5865 app = null; 5866 } 5867 5868 if (app == null) { 5869 Slog.w(TAG, "No pending application record for pid " + pid 5870 + " (IApplicationThread " + thread + "); dropping process"); 5871 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5872 if (pid > 0 && pid != MY_PID) { 5873 Process.killProcessQuiet(pid); 5874 //TODO: Process.killProcessGroup(app.info.uid, pid); 5875 } else { 5876 try { 5877 thread.scheduleExit(); 5878 } catch (Exception e) { 5879 // Ignore exceptions. 5880 } 5881 } 5882 return false; 5883 } 5884 5885 // If this application record is still attached to a previous 5886 // process, clean it up now. 5887 if (app.thread != null) { 5888 handleAppDiedLocked(app, true, true); 5889 } 5890 5891 // Tell the process all about itself. 5892 5893 if (localLOGV) Slog.v( 5894 TAG, "Binding process pid " + pid + " to record " + app); 5895 5896 final String processName = app.processName; 5897 try { 5898 AppDeathRecipient adr = new AppDeathRecipient( 5899 app, pid, thread); 5900 thread.asBinder().linkToDeath(adr, 0); 5901 app.deathRecipient = adr; 5902 } catch (RemoteException e) { 5903 app.resetPackageList(mProcessStats); 5904 startProcessLocked(app, "link fail", processName); 5905 return false; 5906 } 5907 5908 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5909 5910 app.makeActive(thread, mProcessStats); 5911 app.curAdj = app.setAdj = -100; 5912 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5913 app.forcingToForeground = null; 5914 updateProcessForegroundLocked(app, false, false); 5915 app.hasShownUi = false; 5916 app.debugging = false; 5917 app.cached = false; 5918 app.killedByAm = false; 5919 5920 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5921 5922 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5923 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5924 5925 if (!normalMode) { 5926 Slog.i(TAG, "Launching preboot mode app: " + app); 5927 } 5928 5929 if (localLOGV) Slog.v( 5930 TAG, "New app record " + app 5931 + " thread=" + thread.asBinder() + " pid=" + pid); 5932 try { 5933 int testMode = IApplicationThread.DEBUG_OFF; 5934 if (mDebugApp != null && mDebugApp.equals(processName)) { 5935 testMode = mWaitForDebugger 5936 ? IApplicationThread.DEBUG_WAIT 5937 : IApplicationThread.DEBUG_ON; 5938 app.debugging = true; 5939 if (mDebugTransient) { 5940 mDebugApp = mOrigDebugApp; 5941 mWaitForDebugger = mOrigWaitForDebugger; 5942 } 5943 } 5944 String profileFile = app.instrumentationProfileFile; 5945 ParcelFileDescriptor profileFd = null; 5946 int samplingInterval = 0; 5947 boolean profileAutoStop = false; 5948 if (mProfileApp != null && mProfileApp.equals(processName)) { 5949 mProfileProc = app; 5950 profileFile = mProfileFile; 5951 profileFd = mProfileFd; 5952 samplingInterval = mSamplingInterval; 5953 profileAutoStop = mAutoStopProfiler; 5954 } 5955 boolean enableOpenGlTrace = false; 5956 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5957 enableOpenGlTrace = true; 5958 mOpenGlTraceApp = null; 5959 } 5960 5961 // If the app is being launched for restore or full backup, set it up specially 5962 boolean isRestrictedBackupMode = false; 5963 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5964 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5965 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5966 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5967 } 5968 5969 ensurePackageDexOpt(app.instrumentationInfo != null 5970 ? app.instrumentationInfo.packageName 5971 : app.info.packageName); 5972 if (app.instrumentationClass != null) { 5973 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5974 } 5975 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5976 + processName + " with config " + mConfiguration); 5977 ApplicationInfo appInfo = app.instrumentationInfo != null 5978 ? app.instrumentationInfo : app.info; 5979 app.compat = compatibilityInfoForPackageLocked(appInfo); 5980 if (profileFd != null) { 5981 profileFd = profileFd.dup(); 5982 } 5983 ProfilerInfo profilerInfo = profileFile == null ? null 5984 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5985 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5986 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5987 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5988 isRestrictedBackupMode || !normalMode, app.persistent, 5989 new Configuration(mConfiguration), app.compat, 5990 getCommonServicesLocked(app.isolated), 5991 mCoreSettingsObserver.getCoreSettingsLocked()); 5992 updateLruProcessLocked(app, false, null); 5993 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5994 } catch (Exception e) { 5995 // todo: Yikes! What should we do? For now we will try to 5996 // start another process, but that could easily get us in 5997 // an infinite loop of restarting processes... 5998 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5999 6000 app.resetPackageList(mProcessStats); 6001 app.unlinkDeathRecipient(); 6002 startProcessLocked(app, "bind fail", processName); 6003 return false; 6004 } 6005 6006 // Remove this record from the list of starting applications. 6007 mPersistentStartingProcesses.remove(app); 6008 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6009 "Attach application locked removing on hold: " + app); 6010 mProcessesOnHold.remove(app); 6011 6012 boolean badApp = false; 6013 boolean didSomething = false; 6014 6015 // See if the top visible activity is waiting to run in this process... 6016 if (normalMode) { 6017 try { 6018 if (mStackSupervisor.attachApplicationLocked(app)) { 6019 didSomething = true; 6020 } 6021 } catch (Exception e) { 6022 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6023 badApp = true; 6024 } 6025 } 6026 6027 // Find any services that should be running in this process... 6028 if (!badApp) { 6029 try { 6030 didSomething |= mServices.attachApplicationLocked(app, processName); 6031 } catch (Exception e) { 6032 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6033 badApp = true; 6034 } 6035 } 6036 6037 // Check if a next-broadcast receiver is in this process... 6038 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6039 try { 6040 didSomething |= sendPendingBroadcastsLocked(app); 6041 } catch (Exception e) { 6042 // If the app died trying to launch the receiver we declare it 'bad' 6043 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6044 badApp = true; 6045 } 6046 } 6047 6048 // Check whether the next backup agent is in this process... 6049 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6050 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6051 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6052 try { 6053 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6054 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6055 mBackupTarget.backupMode); 6056 } catch (Exception e) { 6057 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6058 badApp = true; 6059 } 6060 } 6061 6062 if (badApp) { 6063 app.kill("error during init", true); 6064 handleAppDiedLocked(app, false, true); 6065 return false; 6066 } 6067 6068 if (!didSomething) { 6069 updateOomAdjLocked(); 6070 } 6071 6072 return true; 6073 } 6074 6075 @Override 6076 public final void attachApplication(IApplicationThread thread) { 6077 synchronized (this) { 6078 int callingPid = Binder.getCallingPid(); 6079 final long origId = Binder.clearCallingIdentity(); 6080 attachApplicationLocked(thread, callingPid); 6081 Binder.restoreCallingIdentity(origId); 6082 } 6083 } 6084 6085 @Override 6086 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6087 final long origId = Binder.clearCallingIdentity(); 6088 synchronized (this) { 6089 ActivityStack stack = ActivityRecord.getStackLocked(token); 6090 if (stack != null) { 6091 ActivityRecord r = 6092 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6093 if (stopProfiling) { 6094 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6095 try { 6096 mProfileFd.close(); 6097 } catch (IOException e) { 6098 } 6099 clearProfilerLocked(); 6100 } 6101 } 6102 } 6103 } 6104 Binder.restoreCallingIdentity(origId); 6105 } 6106 6107 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6108 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6109 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6110 } 6111 6112 void enableScreenAfterBoot() { 6113 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6114 SystemClock.uptimeMillis()); 6115 mWindowManager.enableScreenAfterBoot(); 6116 6117 synchronized (this) { 6118 updateEventDispatchingLocked(); 6119 } 6120 } 6121 6122 @Override 6123 public void showBootMessage(final CharSequence msg, final boolean always) { 6124 enforceNotIsolatedCaller("showBootMessage"); 6125 mWindowManager.showBootMessage(msg, always); 6126 } 6127 6128 @Override 6129 public void keyguardWaitingForActivityDrawn() { 6130 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6131 final long token = Binder.clearCallingIdentity(); 6132 try { 6133 synchronized (this) { 6134 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6135 mWindowManager.keyguardWaitingForActivityDrawn(); 6136 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6137 mLockScreenShown = LOCK_SCREEN_LEAVING; 6138 updateSleepIfNeededLocked(); 6139 } 6140 } 6141 } finally { 6142 Binder.restoreCallingIdentity(token); 6143 } 6144 } 6145 6146 final void finishBooting() { 6147 synchronized (this) { 6148 if (!mBootAnimationComplete) { 6149 mCallFinishBooting = true; 6150 return; 6151 } 6152 mCallFinishBooting = false; 6153 } 6154 6155 ArraySet<String> completedIsas = new ArraySet<String>(); 6156 for (String abi : Build.SUPPORTED_ABIS) { 6157 Process.establishZygoteConnectionForAbi(abi); 6158 final String instructionSet = VMRuntime.getInstructionSet(abi); 6159 if (!completedIsas.contains(instructionSet)) { 6160 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6161 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6162 } 6163 completedIsas.add(instructionSet); 6164 } 6165 } 6166 6167 IntentFilter pkgFilter = new IntentFilter(); 6168 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6169 pkgFilter.addDataScheme("package"); 6170 mContext.registerReceiver(new BroadcastReceiver() { 6171 @Override 6172 public void onReceive(Context context, Intent intent) { 6173 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6174 if (pkgs != null) { 6175 for (String pkg : pkgs) { 6176 synchronized (ActivityManagerService.this) { 6177 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6178 0, "finished booting")) { 6179 setResultCode(Activity.RESULT_OK); 6180 return; 6181 } 6182 } 6183 } 6184 } 6185 } 6186 }, pkgFilter); 6187 6188 // Let system services know. 6189 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6190 6191 synchronized (this) { 6192 // Ensure that any processes we had put on hold are now started 6193 // up. 6194 final int NP = mProcessesOnHold.size(); 6195 if (NP > 0) { 6196 ArrayList<ProcessRecord> procs = 6197 new ArrayList<ProcessRecord>(mProcessesOnHold); 6198 for (int ip=0; ip<NP; ip++) { 6199 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6200 + procs.get(ip)); 6201 startProcessLocked(procs.get(ip), "on-hold", null); 6202 } 6203 } 6204 6205 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6206 // Start looking for apps that are abusing wake locks. 6207 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6208 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6209 // Tell anyone interested that we are done booting! 6210 SystemProperties.set("sys.boot_completed", "1"); 6211 6212 // And trigger dev.bootcomplete if we are not showing encryption progress 6213 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6214 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6215 SystemProperties.set("dev.bootcomplete", "1"); 6216 } 6217 for (int i=0; i<mStartedUsers.size(); i++) { 6218 UserStartedState uss = mStartedUsers.valueAt(i); 6219 if (uss.mState == UserStartedState.STATE_BOOTING) { 6220 uss.mState = UserStartedState.STATE_RUNNING; 6221 final int userId = mStartedUsers.keyAt(i); 6222 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6223 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6224 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6225 broadcastIntentLocked(null, null, intent, null, 6226 new IIntentReceiver.Stub() { 6227 @Override 6228 public void performReceive(Intent intent, int resultCode, 6229 String data, Bundle extras, boolean ordered, 6230 boolean sticky, int sendingUser) { 6231 synchronized (ActivityManagerService.this) { 6232 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6233 true, false); 6234 } 6235 } 6236 }, 6237 0, null, null, 6238 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6239 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6240 userId); 6241 } 6242 } 6243 scheduleStartProfilesLocked(); 6244 } 6245 } 6246 } 6247 6248 @Override 6249 public void bootAnimationComplete() { 6250 final boolean callFinishBooting; 6251 synchronized (this) { 6252 callFinishBooting = mCallFinishBooting; 6253 mBootAnimationComplete = true; 6254 } 6255 if (callFinishBooting) { 6256 finishBooting(); 6257 } 6258 } 6259 6260 @Override 6261 public void systemBackupRestored() { 6262 synchronized (this) { 6263 if (mSystemReady) { 6264 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6265 } else { 6266 Slog.w(TAG, "System backup restored before system is ready"); 6267 } 6268 } 6269 } 6270 6271 final void ensureBootCompleted() { 6272 boolean booting; 6273 boolean enableScreen; 6274 synchronized (this) { 6275 booting = mBooting; 6276 mBooting = false; 6277 enableScreen = !mBooted; 6278 mBooted = true; 6279 } 6280 6281 if (booting) { 6282 finishBooting(); 6283 } 6284 6285 if (enableScreen) { 6286 enableScreenAfterBoot(); 6287 } 6288 } 6289 6290 @Override 6291 public final void activityResumed(IBinder token) { 6292 final long origId = Binder.clearCallingIdentity(); 6293 synchronized(this) { 6294 ActivityStack stack = ActivityRecord.getStackLocked(token); 6295 if (stack != null) { 6296 ActivityRecord.activityResumedLocked(token); 6297 } 6298 } 6299 Binder.restoreCallingIdentity(origId); 6300 } 6301 6302 @Override 6303 public final void activityPaused(IBinder token) { 6304 final long origId = Binder.clearCallingIdentity(); 6305 synchronized(this) { 6306 ActivityStack stack = ActivityRecord.getStackLocked(token); 6307 if (stack != null) { 6308 stack.activityPausedLocked(token, false); 6309 } 6310 } 6311 Binder.restoreCallingIdentity(origId); 6312 } 6313 6314 @Override 6315 public final void activityStopped(IBinder token, Bundle icicle, 6316 PersistableBundle persistentState, CharSequence description) { 6317 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6318 6319 // Refuse possible leaked file descriptors 6320 if (icicle != null && icicle.hasFileDescriptors()) { 6321 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6322 } 6323 6324 final long origId = Binder.clearCallingIdentity(); 6325 6326 synchronized (this) { 6327 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6328 if (r != null) { 6329 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6330 } 6331 } 6332 6333 trimApplications(); 6334 6335 Binder.restoreCallingIdentity(origId); 6336 } 6337 6338 @Override 6339 public final void activityDestroyed(IBinder token) { 6340 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6341 synchronized (this) { 6342 ActivityStack stack = ActivityRecord.getStackLocked(token); 6343 if (stack != null) { 6344 stack.activityDestroyedLocked(token); 6345 } 6346 } 6347 } 6348 6349 @Override 6350 public final void backgroundResourcesReleased(IBinder token) { 6351 final long origId = Binder.clearCallingIdentity(); 6352 try { 6353 synchronized (this) { 6354 ActivityStack stack = ActivityRecord.getStackLocked(token); 6355 if (stack != null) { 6356 stack.backgroundResourcesReleased(); 6357 } 6358 } 6359 } finally { 6360 Binder.restoreCallingIdentity(origId); 6361 } 6362 } 6363 6364 @Override 6365 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6366 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6367 } 6368 6369 @Override 6370 public final void notifyEnterAnimationComplete(IBinder token) { 6371 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6372 } 6373 6374 @Override 6375 public String getCallingPackage(IBinder token) { 6376 synchronized (this) { 6377 ActivityRecord r = getCallingRecordLocked(token); 6378 return r != null ? r.info.packageName : null; 6379 } 6380 } 6381 6382 @Override 6383 public ComponentName getCallingActivity(IBinder token) { 6384 synchronized (this) { 6385 ActivityRecord r = getCallingRecordLocked(token); 6386 return r != null ? r.intent.getComponent() : null; 6387 } 6388 } 6389 6390 private ActivityRecord getCallingRecordLocked(IBinder token) { 6391 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6392 if (r == null) { 6393 return null; 6394 } 6395 return r.resultTo; 6396 } 6397 6398 @Override 6399 public ComponentName getActivityClassForToken(IBinder token) { 6400 synchronized(this) { 6401 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6402 if (r == null) { 6403 return null; 6404 } 6405 return r.intent.getComponent(); 6406 } 6407 } 6408 6409 @Override 6410 public String getPackageForToken(IBinder token) { 6411 synchronized(this) { 6412 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6413 if (r == null) { 6414 return null; 6415 } 6416 return r.packageName; 6417 } 6418 } 6419 6420 @Override 6421 public IIntentSender getIntentSender(int type, 6422 String packageName, IBinder token, String resultWho, 6423 int requestCode, Intent[] intents, String[] resolvedTypes, 6424 int flags, Bundle options, int userId) { 6425 enforceNotIsolatedCaller("getIntentSender"); 6426 // Refuse possible leaked file descriptors 6427 if (intents != null) { 6428 if (intents.length < 1) { 6429 throw new IllegalArgumentException("Intents array length must be >= 1"); 6430 } 6431 for (int i=0; i<intents.length; i++) { 6432 Intent intent = intents[i]; 6433 if (intent != null) { 6434 if (intent.hasFileDescriptors()) { 6435 throw new IllegalArgumentException("File descriptors passed in Intent"); 6436 } 6437 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6438 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6439 throw new IllegalArgumentException( 6440 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6441 } 6442 intents[i] = new Intent(intent); 6443 } 6444 } 6445 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6446 throw new IllegalArgumentException( 6447 "Intent array length does not match resolvedTypes length"); 6448 } 6449 } 6450 if (options != null) { 6451 if (options.hasFileDescriptors()) { 6452 throw new IllegalArgumentException("File descriptors passed in options"); 6453 } 6454 } 6455 6456 synchronized(this) { 6457 int callingUid = Binder.getCallingUid(); 6458 int origUserId = userId; 6459 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6460 type == ActivityManager.INTENT_SENDER_BROADCAST, 6461 ALLOW_NON_FULL, "getIntentSender", null); 6462 if (origUserId == UserHandle.USER_CURRENT) { 6463 // We don't want to evaluate this until the pending intent is 6464 // actually executed. However, we do want to always do the 6465 // security checking for it above. 6466 userId = UserHandle.USER_CURRENT; 6467 } 6468 try { 6469 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6470 int uid = AppGlobals.getPackageManager() 6471 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6472 if (!UserHandle.isSameApp(callingUid, uid)) { 6473 String msg = "Permission Denial: getIntentSender() from pid=" 6474 + Binder.getCallingPid() 6475 + ", uid=" + Binder.getCallingUid() 6476 + ", (need uid=" + uid + ")" 6477 + " is not allowed to send as package " + packageName; 6478 Slog.w(TAG, msg); 6479 throw new SecurityException(msg); 6480 } 6481 } 6482 6483 return getIntentSenderLocked(type, packageName, callingUid, userId, 6484 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6485 6486 } catch (RemoteException e) { 6487 throw new SecurityException(e); 6488 } 6489 } 6490 } 6491 6492 IIntentSender getIntentSenderLocked(int type, String packageName, 6493 int callingUid, int userId, IBinder token, String resultWho, 6494 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6495 Bundle options) { 6496 if (DEBUG_MU) 6497 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6498 ActivityRecord activity = null; 6499 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6500 activity = ActivityRecord.isInStackLocked(token); 6501 if (activity == null) { 6502 return null; 6503 } 6504 if (activity.finishing) { 6505 return null; 6506 } 6507 } 6508 6509 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6510 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6511 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6512 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6513 |PendingIntent.FLAG_UPDATE_CURRENT); 6514 6515 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6516 type, packageName, activity, resultWho, 6517 requestCode, intents, resolvedTypes, flags, options, userId); 6518 WeakReference<PendingIntentRecord> ref; 6519 ref = mIntentSenderRecords.get(key); 6520 PendingIntentRecord rec = ref != null ? ref.get() : null; 6521 if (rec != null) { 6522 if (!cancelCurrent) { 6523 if (updateCurrent) { 6524 if (rec.key.requestIntent != null) { 6525 rec.key.requestIntent.replaceExtras(intents != null ? 6526 intents[intents.length - 1] : null); 6527 } 6528 if (intents != null) { 6529 intents[intents.length-1] = rec.key.requestIntent; 6530 rec.key.allIntents = intents; 6531 rec.key.allResolvedTypes = resolvedTypes; 6532 } else { 6533 rec.key.allIntents = null; 6534 rec.key.allResolvedTypes = null; 6535 } 6536 } 6537 return rec; 6538 } 6539 rec.canceled = true; 6540 mIntentSenderRecords.remove(key); 6541 } 6542 if (noCreate) { 6543 return rec; 6544 } 6545 rec = new PendingIntentRecord(this, key, callingUid); 6546 mIntentSenderRecords.put(key, rec.ref); 6547 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6548 if (activity.pendingResults == null) { 6549 activity.pendingResults 6550 = new HashSet<WeakReference<PendingIntentRecord>>(); 6551 } 6552 activity.pendingResults.add(rec.ref); 6553 } 6554 return rec; 6555 } 6556 6557 @Override 6558 public void cancelIntentSender(IIntentSender sender) { 6559 if (!(sender instanceof PendingIntentRecord)) { 6560 return; 6561 } 6562 synchronized(this) { 6563 PendingIntentRecord rec = (PendingIntentRecord)sender; 6564 try { 6565 int uid = AppGlobals.getPackageManager() 6566 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6567 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6568 String msg = "Permission Denial: cancelIntentSender() from pid=" 6569 + Binder.getCallingPid() 6570 + ", uid=" + Binder.getCallingUid() 6571 + " is not allowed to cancel packges " 6572 + rec.key.packageName; 6573 Slog.w(TAG, msg); 6574 throw new SecurityException(msg); 6575 } 6576 } catch (RemoteException e) { 6577 throw new SecurityException(e); 6578 } 6579 cancelIntentSenderLocked(rec, true); 6580 } 6581 } 6582 6583 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6584 rec.canceled = true; 6585 mIntentSenderRecords.remove(rec.key); 6586 if (cleanActivity && rec.key.activity != null) { 6587 rec.key.activity.pendingResults.remove(rec.ref); 6588 } 6589 } 6590 6591 @Override 6592 public String getPackageForIntentSender(IIntentSender pendingResult) { 6593 if (!(pendingResult instanceof PendingIntentRecord)) { 6594 return null; 6595 } 6596 try { 6597 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6598 return res.key.packageName; 6599 } catch (ClassCastException e) { 6600 } 6601 return null; 6602 } 6603 6604 @Override 6605 public int getUidForIntentSender(IIntentSender sender) { 6606 if (sender instanceof PendingIntentRecord) { 6607 try { 6608 PendingIntentRecord res = (PendingIntentRecord)sender; 6609 return res.uid; 6610 } catch (ClassCastException e) { 6611 } 6612 } 6613 return -1; 6614 } 6615 6616 @Override 6617 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6618 if (!(pendingResult instanceof PendingIntentRecord)) { 6619 return false; 6620 } 6621 try { 6622 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6623 if (res.key.allIntents == null) { 6624 return false; 6625 } 6626 for (int i=0; i<res.key.allIntents.length; i++) { 6627 Intent intent = res.key.allIntents[i]; 6628 if (intent.getPackage() != null && intent.getComponent() != null) { 6629 return false; 6630 } 6631 } 6632 return true; 6633 } catch (ClassCastException e) { 6634 } 6635 return false; 6636 } 6637 6638 @Override 6639 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6640 if (!(pendingResult instanceof PendingIntentRecord)) { 6641 return false; 6642 } 6643 try { 6644 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6645 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6646 return true; 6647 } 6648 return false; 6649 } catch (ClassCastException e) { 6650 } 6651 return false; 6652 } 6653 6654 @Override 6655 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6656 if (!(pendingResult instanceof PendingIntentRecord)) { 6657 return null; 6658 } 6659 try { 6660 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6661 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6662 } catch (ClassCastException e) { 6663 } 6664 return null; 6665 } 6666 6667 @Override 6668 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6669 if (!(pendingResult instanceof PendingIntentRecord)) { 6670 return null; 6671 } 6672 try { 6673 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6674 Intent intent = res.key.requestIntent; 6675 if (intent != null) { 6676 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6677 || res.lastTagPrefix.equals(prefix))) { 6678 return res.lastTag; 6679 } 6680 res.lastTagPrefix = prefix; 6681 StringBuilder sb = new StringBuilder(128); 6682 if (prefix != null) { 6683 sb.append(prefix); 6684 } 6685 if (intent.getAction() != null) { 6686 sb.append(intent.getAction()); 6687 } else if (intent.getComponent() != null) { 6688 intent.getComponent().appendShortString(sb); 6689 } else { 6690 sb.append("?"); 6691 } 6692 return res.lastTag = sb.toString(); 6693 } 6694 } catch (ClassCastException e) { 6695 } 6696 return null; 6697 } 6698 6699 @Override 6700 public void setProcessLimit(int max) { 6701 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6702 "setProcessLimit()"); 6703 synchronized (this) { 6704 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6705 mProcessLimitOverride = max; 6706 } 6707 trimApplications(); 6708 } 6709 6710 @Override 6711 public int getProcessLimit() { 6712 synchronized (this) { 6713 return mProcessLimitOverride; 6714 } 6715 } 6716 6717 void foregroundTokenDied(ForegroundToken token) { 6718 synchronized (ActivityManagerService.this) { 6719 synchronized (mPidsSelfLocked) { 6720 ForegroundToken cur 6721 = mForegroundProcesses.get(token.pid); 6722 if (cur != token) { 6723 return; 6724 } 6725 mForegroundProcesses.remove(token.pid); 6726 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6727 if (pr == null) { 6728 return; 6729 } 6730 pr.forcingToForeground = null; 6731 updateProcessForegroundLocked(pr, false, false); 6732 } 6733 updateOomAdjLocked(); 6734 } 6735 } 6736 6737 @Override 6738 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6739 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6740 "setProcessForeground()"); 6741 synchronized(this) { 6742 boolean changed = false; 6743 6744 synchronized (mPidsSelfLocked) { 6745 ProcessRecord pr = mPidsSelfLocked.get(pid); 6746 if (pr == null && isForeground) { 6747 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6748 return; 6749 } 6750 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6751 if (oldToken != null) { 6752 oldToken.token.unlinkToDeath(oldToken, 0); 6753 mForegroundProcesses.remove(pid); 6754 if (pr != null) { 6755 pr.forcingToForeground = null; 6756 } 6757 changed = true; 6758 } 6759 if (isForeground && token != null) { 6760 ForegroundToken newToken = new ForegroundToken() { 6761 @Override 6762 public void binderDied() { 6763 foregroundTokenDied(this); 6764 } 6765 }; 6766 newToken.pid = pid; 6767 newToken.token = token; 6768 try { 6769 token.linkToDeath(newToken, 0); 6770 mForegroundProcesses.put(pid, newToken); 6771 pr.forcingToForeground = token; 6772 changed = true; 6773 } catch (RemoteException e) { 6774 // If the process died while doing this, we will later 6775 // do the cleanup with the process death link. 6776 } 6777 } 6778 } 6779 6780 if (changed) { 6781 updateOomAdjLocked(); 6782 } 6783 } 6784 } 6785 6786 // ========================================================= 6787 // PERMISSIONS 6788 // ========================================================= 6789 6790 static class PermissionController extends IPermissionController.Stub { 6791 ActivityManagerService mActivityManagerService; 6792 PermissionController(ActivityManagerService activityManagerService) { 6793 mActivityManagerService = activityManagerService; 6794 } 6795 6796 @Override 6797 public boolean checkPermission(String permission, int pid, int uid) { 6798 return mActivityManagerService.checkPermission(permission, pid, 6799 uid) == PackageManager.PERMISSION_GRANTED; 6800 } 6801 } 6802 6803 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6804 @Override 6805 public int checkComponentPermission(String permission, int pid, int uid, 6806 int owningUid, boolean exported) { 6807 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6808 owningUid, exported); 6809 } 6810 6811 @Override 6812 public Object getAMSLock() { 6813 return ActivityManagerService.this; 6814 } 6815 } 6816 6817 /** 6818 * This can be called with or without the global lock held. 6819 */ 6820 int checkComponentPermission(String permission, int pid, int uid, 6821 int owningUid, boolean exported) { 6822 if (pid == MY_PID) { 6823 return PackageManager.PERMISSION_GRANTED; 6824 } 6825 return ActivityManager.checkComponentPermission(permission, uid, 6826 owningUid, exported); 6827 } 6828 6829 /** 6830 * As the only public entry point for permissions checking, this method 6831 * can enforce the semantic that requesting a check on a null global 6832 * permission is automatically denied. (Internally a null permission 6833 * string is used when calling {@link #checkComponentPermission} in cases 6834 * when only uid-based security is needed.) 6835 * 6836 * This can be called with or without the global lock held. 6837 */ 6838 @Override 6839 public int checkPermission(String permission, int pid, int uid) { 6840 if (permission == null) { 6841 return PackageManager.PERMISSION_DENIED; 6842 } 6843 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6844 } 6845 6846 @Override 6847 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6848 if (permission == null) { 6849 return PackageManager.PERMISSION_DENIED; 6850 } 6851 6852 // We might be performing an operation on behalf of an indirect binder 6853 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6854 // client identity accordingly before proceeding. 6855 Identity tlsIdentity = sCallerIdentity.get(); 6856 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6857 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6858 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6859 uid = tlsIdentity.uid; 6860 pid = tlsIdentity.pid; 6861 } 6862 6863 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6864 } 6865 6866 /** 6867 * Binder IPC calls go through the public entry point. 6868 * This can be called with or without the global lock held. 6869 */ 6870 int checkCallingPermission(String permission) { 6871 return checkPermission(permission, 6872 Binder.getCallingPid(), 6873 UserHandle.getAppId(Binder.getCallingUid())); 6874 } 6875 6876 /** 6877 * This can be called with or without the global lock held. 6878 */ 6879 void enforceCallingPermission(String permission, String func) { 6880 if (checkCallingPermission(permission) 6881 == PackageManager.PERMISSION_GRANTED) { 6882 return; 6883 } 6884 6885 String msg = "Permission Denial: " + func + " from pid=" 6886 + Binder.getCallingPid() 6887 + ", uid=" + Binder.getCallingUid() 6888 + " requires " + permission; 6889 Slog.w(TAG, msg); 6890 throw new SecurityException(msg); 6891 } 6892 6893 /** 6894 * Determine if UID is holding permissions required to access {@link Uri} in 6895 * the given {@link ProviderInfo}. Final permission checking is always done 6896 * in {@link ContentProvider}. 6897 */ 6898 private final boolean checkHoldingPermissionsLocked( 6899 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6900 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6901 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6902 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6903 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6904 != PERMISSION_GRANTED) { 6905 return false; 6906 } 6907 } 6908 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6909 } 6910 6911 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6912 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6913 if (pi.applicationInfo.uid == uid) { 6914 return true; 6915 } else if (!pi.exported) { 6916 return false; 6917 } 6918 6919 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6920 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6921 try { 6922 // check if target holds top-level <provider> permissions 6923 if (!readMet && pi.readPermission != null && considerUidPermissions 6924 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6925 readMet = true; 6926 } 6927 if (!writeMet && pi.writePermission != null && considerUidPermissions 6928 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6929 writeMet = true; 6930 } 6931 6932 // track if unprotected read/write is allowed; any denied 6933 // <path-permission> below removes this ability 6934 boolean allowDefaultRead = pi.readPermission == null; 6935 boolean allowDefaultWrite = pi.writePermission == null; 6936 6937 // check if target holds any <path-permission> that match uri 6938 final PathPermission[] pps = pi.pathPermissions; 6939 if (pps != null) { 6940 final String path = grantUri.uri.getPath(); 6941 int i = pps.length; 6942 while (i > 0 && (!readMet || !writeMet)) { 6943 i--; 6944 PathPermission pp = pps[i]; 6945 if (pp.match(path)) { 6946 if (!readMet) { 6947 final String pprperm = pp.getReadPermission(); 6948 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6949 + pprperm + " for " + pp.getPath() 6950 + ": match=" + pp.match(path) 6951 + " check=" + pm.checkUidPermission(pprperm, uid)); 6952 if (pprperm != null) { 6953 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6954 == PERMISSION_GRANTED) { 6955 readMet = true; 6956 } else { 6957 allowDefaultRead = false; 6958 } 6959 } 6960 } 6961 if (!writeMet) { 6962 final String ppwperm = pp.getWritePermission(); 6963 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6964 + ppwperm + " for " + pp.getPath() 6965 + ": match=" + pp.match(path) 6966 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6967 if (ppwperm != null) { 6968 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6969 == PERMISSION_GRANTED) { 6970 writeMet = true; 6971 } else { 6972 allowDefaultWrite = false; 6973 } 6974 } 6975 } 6976 } 6977 } 6978 } 6979 6980 // grant unprotected <provider> read/write, if not blocked by 6981 // <path-permission> above 6982 if (allowDefaultRead) readMet = true; 6983 if (allowDefaultWrite) writeMet = true; 6984 6985 } catch (RemoteException e) { 6986 return false; 6987 } 6988 6989 return readMet && writeMet; 6990 } 6991 6992 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6993 ProviderInfo pi = null; 6994 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6995 if (cpr != null) { 6996 pi = cpr.info; 6997 } else { 6998 try { 6999 pi = AppGlobals.getPackageManager().resolveContentProvider( 7000 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7001 } catch (RemoteException ex) { 7002 } 7003 } 7004 return pi; 7005 } 7006 7007 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7008 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7009 if (targetUris != null) { 7010 return targetUris.get(grantUri); 7011 } 7012 return null; 7013 } 7014 7015 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7016 String targetPkg, int targetUid, GrantUri grantUri) { 7017 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7018 if (targetUris == null) { 7019 targetUris = Maps.newArrayMap(); 7020 mGrantedUriPermissions.put(targetUid, targetUris); 7021 } 7022 7023 UriPermission perm = targetUris.get(grantUri); 7024 if (perm == null) { 7025 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7026 targetUris.put(grantUri, perm); 7027 } 7028 7029 return perm; 7030 } 7031 7032 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7033 final int modeFlags) { 7034 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7035 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7036 : UriPermission.STRENGTH_OWNED; 7037 7038 // Root gets to do everything. 7039 if (uid == 0) { 7040 return true; 7041 } 7042 7043 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7044 if (perms == null) return false; 7045 7046 // First look for exact match 7047 final UriPermission exactPerm = perms.get(grantUri); 7048 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7049 return true; 7050 } 7051 7052 // No exact match, look for prefixes 7053 final int N = perms.size(); 7054 for (int i = 0; i < N; i++) { 7055 final UriPermission perm = perms.valueAt(i); 7056 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7057 && perm.getStrength(modeFlags) >= minStrength) { 7058 return true; 7059 } 7060 } 7061 7062 return false; 7063 } 7064 7065 /** 7066 * @param uri This uri must NOT contain an embedded userId. 7067 * @param userId The userId in which the uri is to be resolved. 7068 */ 7069 @Override 7070 public int checkUriPermission(Uri uri, int pid, int uid, 7071 final int modeFlags, int userId, IBinder callerToken) { 7072 enforceNotIsolatedCaller("checkUriPermission"); 7073 7074 // Another redirected-binder-call permissions check as in 7075 // {@link checkPermissionWithToken}. 7076 Identity tlsIdentity = sCallerIdentity.get(); 7077 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7078 uid = tlsIdentity.uid; 7079 pid = tlsIdentity.pid; 7080 } 7081 7082 // Our own process gets to do everything. 7083 if (pid == MY_PID) { 7084 return PackageManager.PERMISSION_GRANTED; 7085 } 7086 synchronized (this) { 7087 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7088 ? PackageManager.PERMISSION_GRANTED 7089 : PackageManager.PERMISSION_DENIED; 7090 } 7091 } 7092 7093 /** 7094 * Check if the targetPkg can be granted permission to access uri by 7095 * the callingUid using the given modeFlags. Throws a security exception 7096 * if callingUid is not allowed to do this. Returns the uid of the target 7097 * if the URI permission grant should be performed; returns -1 if it is not 7098 * needed (for example targetPkg already has permission to access the URI). 7099 * If you already know the uid of the target, you can supply it in 7100 * lastTargetUid else set that to -1. 7101 */ 7102 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7103 final int modeFlags, int lastTargetUid) { 7104 if (!Intent.isAccessUriMode(modeFlags)) { 7105 return -1; 7106 } 7107 7108 if (targetPkg != null) { 7109 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7110 "Checking grant " + targetPkg + " permission to " + grantUri); 7111 } 7112 7113 final IPackageManager pm = AppGlobals.getPackageManager(); 7114 7115 // If this is not a content: uri, we can't do anything with it. 7116 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7117 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7118 "Can't grant URI permission for non-content URI: " + grantUri); 7119 return -1; 7120 } 7121 7122 final String authority = grantUri.uri.getAuthority(); 7123 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7124 if (pi == null) { 7125 Slog.w(TAG, "No content provider found for permission check: " + 7126 grantUri.uri.toSafeString()); 7127 return -1; 7128 } 7129 7130 int targetUid = lastTargetUid; 7131 if (targetUid < 0 && targetPkg != null) { 7132 try { 7133 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7134 if (targetUid < 0) { 7135 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7136 "Can't grant URI permission no uid for: " + targetPkg); 7137 return -1; 7138 } 7139 } catch (RemoteException ex) { 7140 return -1; 7141 } 7142 } 7143 7144 if (targetUid >= 0) { 7145 // First... does the target actually need this permission? 7146 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7147 // No need to grant the target this permission. 7148 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7149 "Target " + targetPkg + " already has full permission to " + grantUri); 7150 return -1; 7151 } 7152 } else { 7153 // First... there is no target package, so can anyone access it? 7154 boolean allowed = pi.exported; 7155 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7156 if (pi.readPermission != null) { 7157 allowed = false; 7158 } 7159 } 7160 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7161 if (pi.writePermission != null) { 7162 allowed = false; 7163 } 7164 } 7165 if (allowed) { 7166 return -1; 7167 } 7168 } 7169 7170 /* There is a special cross user grant if: 7171 * - The target is on another user. 7172 * - Apps on the current user can access the uri without any uid permissions. 7173 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7174 * grant uri permissions. 7175 */ 7176 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7177 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7178 modeFlags, false /*without considering the uid permissions*/); 7179 7180 // Second... is the provider allowing granting of URI permissions? 7181 if (!specialCrossUserGrant) { 7182 if (!pi.grantUriPermissions) { 7183 throw new SecurityException("Provider " + pi.packageName 7184 + "/" + pi.name 7185 + " does not allow granting of Uri permissions (uri " 7186 + grantUri + ")"); 7187 } 7188 if (pi.uriPermissionPatterns != null) { 7189 final int N = pi.uriPermissionPatterns.length; 7190 boolean allowed = false; 7191 for (int i=0; i<N; i++) { 7192 if (pi.uriPermissionPatterns[i] != null 7193 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7194 allowed = true; 7195 break; 7196 } 7197 } 7198 if (!allowed) { 7199 throw new SecurityException("Provider " + pi.packageName 7200 + "/" + pi.name 7201 + " does not allow granting of permission to path of Uri " 7202 + grantUri); 7203 } 7204 } 7205 } 7206 7207 // Third... does the caller itself have permission to access 7208 // this uri? 7209 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7210 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7211 // Require they hold a strong enough Uri permission 7212 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7213 throw new SecurityException("Uid " + callingUid 7214 + " does not have permission to uri " + grantUri); 7215 } 7216 } 7217 } 7218 return targetUid; 7219 } 7220 7221 /** 7222 * @param uri This uri must NOT contain an embedded userId. 7223 * @param userId The userId in which the uri is to be resolved. 7224 */ 7225 @Override 7226 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7227 final int modeFlags, int userId) { 7228 enforceNotIsolatedCaller("checkGrantUriPermission"); 7229 synchronized(this) { 7230 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7231 new GrantUri(userId, uri, false), modeFlags, -1); 7232 } 7233 } 7234 7235 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7236 final int modeFlags, UriPermissionOwner owner) { 7237 if (!Intent.isAccessUriMode(modeFlags)) { 7238 return; 7239 } 7240 7241 // So here we are: the caller has the assumed permission 7242 // to the uri, and the target doesn't. Let's now give this to 7243 // the target. 7244 7245 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7246 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7247 7248 final String authority = grantUri.uri.getAuthority(); 7249 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7250 if (pi == null) { 7251 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7252 return; 7253 } 7254 7255 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7256 grantUri.prefix = true; 7257 } 7258 final UriPermission perm = findOrCreateUriPermissionLocked( 7259 pi.packageName, targetPkg, targetUid, grantUri); 7260 perm.grantModes(modeFlags, owner); 7261 } 7262 7263 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7264 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7265 if (targetPkg == null) { 7266 throw new NullPointerException("targetPkg"); 7267 } 7268 int targetUid; 7269 final IPackageManager pm = AppGlobals.getPackageManager(); 7270 try { 7271 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7272 } catch (RemoteException ex) { 7273 return; 7274 } 7275 7276 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7277 targetUid); 7278 if (targetUid < 0) { 7279 return; 7280 } 7281 7282 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7283 owner); 7284 } 7285 7286 static class NeededUriGrants extends ArrayList<GrantUri> { 7287 final String targetPkg; 7288 final int targetUid; 7289 final int flags; 7290 7291 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7292 this.targetPkg = targetPkg; 7293 this.targetUid = targetUid; 7294 this.flags = flags; 7295 } 7296 } 7297 7298 /** 7299 * Like checkGrantUriPermissionLocked, but takes an Intent. 7300 */ 7301 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7302 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7303 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7304 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7305 + " clip=" + (intent != null ? intent.getClipData() : null) 7306 + " from " + intent + "; flags=0x" 7307 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7308 7309 if (targetPkg == null) { 7310 throw new NullPointerException("targetPkg"); 7311 } 7312 7313 if (intent == null) { 7314 return null; 7315 } 7316 Uri data = intent.getData(); 7317 ClipData clip = intent.getClipData(); 7318 if (data == null && clip == null) { 7319 return null; 7320 } 7321 // Default userId for uris in the intent (if they don't specify it themselves) 7322 int contentUserHint = intent.getContentUserHint(); 7323 if (contentUserHint == UserHandle.USER_CURRENT) { 7324 contentUserHint = UserHandle.getUserId(callingUid); 7325 } 7326 final IPackageManager pm = AppGlobals.getPackageManager(); 7327 int targetUid; 7328 if (needed != null) { 7329 targetUid = needed.targetUid; 7330 } else { 7331 try { 7332 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7333 } catch (RemoteException ex) { 7334 return null; 7335 } 7336 if (targetUid < 0) { 7337 if (DEBUG_URI_PERMISSION) { 7338 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7339 + " on user " + targetUserId); 7340 } 7341 return null; 7342 } 7343 } 7344 if (data != null) { 7345 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7346 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7347 targetUid); 7348 if (targetUid > 0) { 7349 if (needed == null) { 7350 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7351 } 7352 needed.add(grantUri); 7353 } 7354 } 7355 if (clip != null) { 7356 for (int i=0; i<clip.getItemCount(); i++) { 7357 Uri uri = clip.getItemAt(i).getUri(); 7358 if (uri != null) { 7359 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7360 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7361 targetUid); 7362 if (targetUid > 0) { 7363 if (needed == null) { 7364 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7365 } 7366 needed.add(grantUri); 7367 } 7368 } else { 7369 Intent clipIntent = clip.getItemAt(i).getIntent(); 7370 if (clipIntent != null) { 7371 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7372 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7373 if (newNeeded != null) { 7374 needed = newNeeded; 7375 } 7376 } 7377 } 7378 } 7379 } 7380 7381 return needed; 7382 } 7383 7384 /** 7385 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7386 */ 7387 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7388 UriPermissionOwner owner) { 7389 if (needed != null) { 7390 for (int i=0; i<needed.size(); i++) { 7391 GrantUri grantUri = needed.get(i); 7392 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7393 grantUri, needed.flags, owner); 7394 } 7395 } 7396 } 7397 7398 void grantUriPermissionFromIntentLocked(int callingUid, 7399 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7400 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7401 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7402 if (needed == null) { 7403 return; 7404 } 7405 7406 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7407 } 7408 7409 /** 7410 * @param uri This uri must NOT contain an embedded userId. 7411 * @param userId The userId in which the uri is to be resolved. 7412 */ 7413 @Override 7414 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7415 final int modeFlags, int userId) { 7416 enforceNotIsolatedCaller("grantUriPermission"); 7417 GrantUri grantUri = new GrantUri(userId, uri, false); 7418 synchronized(this) { 7419 final ProcessRecord r = getRecordForAppLocked(caller); 7420 if (r == null) { 7421 throw new SecurityException("Unable to find app for caller " 7422 + caller 7423 + " when granting permission to uri " + grantUri); 7424 } 7425 if (targetPkg == null) { 7426 throw new IllegalArgumentException("null target"); 7427 } 7428 if (grantUri == null) { 7429 throw new IllegalArgumentException("null uri"); 7430 } 7431 7432 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7433 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7434 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7435 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7436 7437 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7438 UserHandle.getUserId(r.uid)); 7439 } 7440 } 7441 7442 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7443 if (perm.modeFlags == 0) { 7444 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7445 perm.targetUid); 7446 if (perms != null) { 7447 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7448 "Removing " + perm.targetUid + " permission to " + perm.uri); 7449 7450 perms.remove(perm.uri); 7451 if (perms.isEmpty()) { 7452 mGrantedUriPermissions.remove(perm.targetUid); 7453 } 7454 } 7455 } 7456 } 7457 7458 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7459 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7460 7461 final IPackageManager pm = AppGlobals.getPackageManager(); 7462 final String authority = grantUri.uri.getAuthority(); 7463 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7464 if (pi == null) { 7465 Slog.w(TAG, "No content provider found for permission revoke: " 7466 + grantUri.toSafeString()); 7467 return; 7468 } 7469 7470 // Does the caller have this permission on the URI? 7471 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7472 // If they don't have direct access to the URI, then revoke any 7473 // ownerless URI permissions that have been granted to them. 7474 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7475 if (perms != null) { 7476 boolean persistChanged = false; 7477 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7478 final UriPermission perm = it.next(); 7479 if (perm.uri.sourceUserId == grantUri.sourceUserId 7480 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7481 if (DEBUG_URI_PERMISSION) 7482 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7483 " permission to " + perm.uri); 7484 persistChanged |= perm.revokeModes( 7485 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7486 if (perm.modeFlags == 0) { 7487 it.remove(); 7488 } 7489 } 7490 } 7491 if (perms.isEmpty()) { 7492 mGrantedUriPermissions.remove(callingUid); 7493 } 7494 if (persistChanged) { 7495 schedulePersistUriGrants(); 7496 } 7497 } 7498 return; 7499 } 7500 7501 boolean persistChanged = false; 7502 7503 // Go through all of the permissions and remove any that match. 7504 int N = mGrantedUriPermissions.size(); 7505 for (int i = 0; i < N; i++) { 7506 final int targetUid = mGrantedUriPermissions.keyAt(i); 7507 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7508 7509 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7510 final UriPermission perm = it.next(); 7511 if (perm.uri.sourceUserId == grantUri.sourceUserId 7512 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7513 if (DEBUG_URI_PERMISSION) 7514 Slog.v(TAG, 7515 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7516 persistChanged |= perm.revokeModes( 7517 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7518 if (perm.modeFlags == 0) { 7519 it.remove(); 7520 } 7521 } 7522 } 7523 7524 if (perms.isEmpty()) { 7525 mGrantedUriPermissions.remove(targetUid); 7526 N--; 7527 i--; 7528 } 7529 } 7530 7531 if (persistChanged) { 7532 schedulePersistUriGrants(); 7533 } 7534 } 7535 7536 /** 7537 * @param uri This uri must NOT contain an embedded userId. 7538 * @param userId The userId in which the uri is to be resolved. 7539 */ 7540 @Override 7541 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7542 int userId) { 7543 enforceNotIsolatedCaller("revokeUriPermission"); 7544 synchronized(this) { 7545 final ProcessRecord r = getRecordForAppLocked(caller); 7546 if (r == null) { 7547 throw new SecurityException("Unable to find app for caller " 7548 + caller 7549 + " when revoking permission to uri " + uri); 7550 } 7551 if (uri == null) { 7552 Slog.w(TAG, "revokeUriPermission: null uri"); 7553 return; 7554 } 7555 7556 if (!Intent.isAccessUriMode(modeFlags)) { 7557 return; 7558 } 7559 7560 final IPackageManager pm = AppGlobals.getPackageManager(); 7561 final String authority = uri.getAuthority(); 7562 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7563 if (pi == null) { 7564 Slog.w(TAG, "No content provider found for permission revoke: " 7565 + uri.toSafeString()); 7566 return; 7567 } 7568 7569 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7570 } 7571 } 7572 7573 /** 7574 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7575 * given package. 7576 * 7577 * @param packageName Package name to match, or {@code null} to apply to all 7578 * packages. 7579 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7580 * to all users. 7581 * @param persistable If persistable grants should be removed. 7582 */ 7583 private void removeUriPermissionsForPackageLocked( 7584 String packageName, int userHandle, boolean persistable) { 7585 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7586 throw new IllegalArgumentException("Must narrow by either package or user"); 7587 } 7588 7589 boolean persistChanged = false; 7590 7591 int N = mGrantedUriPermissions.size(); 7592 for (int i = 0; i < N; i++) { 7593 final int targetUid = mGrantedUriPermissions.keyAt(i); 7594 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7595 7596 // Only inspect grants matching user 7597 if (userHandle == UserHandle.USER_ALL 7598 || userHandle == UserHandle.getUserId(targetUid)) { 7599 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7600 final UriPermission perm = it.next(); 7601 7602 // Only inspect grants matching package 7603 if (packageName == null || perm.sourcePkg.equals(packageName) 7604 || perm.targetPkg.equals(packageName)) { 7605 persistChanged |= perm.revokeModes(persistable 7606 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7607 7608 // Only remove when no modes remain; any persisted grants 7609 // will keep this alive. 7610 if (perm.modeFlags == 0) { 7611 it.remove(); 7612 } 7613 } 7614 } 7615 7616 if (perms.isEmpty()) { 7617 mGrantedUriPermissions.remove(targetUid); 7618 N--; 7619 i--; 7620 } 7621 } 7622 } 7623 7624 if (persistChanged) { 7625 schedulePersistUriGrants(); 7626 } 7627 } 7628 7629 @Override 7630 public IBinder newUriPermissionOwner(String name) { 7631 enforceNotIsolatedCaller("newUriPermissionOwner"); 7632 synchronized(this) { 7633 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7634 return owner.getExternalTokenLocked(); 7635 } 7636 } 7637 7638 /** 7639 * @param uri This uri must NOT contain an embedded userId. 7640 * @param sourceUserId The userId in which the uri is to be resolved. 7641 * @param targetUserId The userId of the app that receives the grant. 7642 */ 7643 @Override 7644 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7645 final int modeFlags, int sourceUserId, int targetUserId) { 7646 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7647 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7648 synchronized(this) { 7649 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7650 if (owner == null) { 7651 throw new IllegalArgumentException("Unknown owner: " + token); 7652 } 7653 if (fromUid != Binder.getCallingUid()) { 7654 if (Binder.getCallingUid() != Process.myUid()) { 7655 // Only system code can grant URI permissions on behalf 7656 // of other users. 7657 throw new SecurityException("nice try"); 7658 } 7659 } 7660 if (targetPkg == null) { 7661 throw new IllegalArgumentException("null target"); 7662 } 7663 if (uri == null) { 7664 throw new IllegalArgumentException("null uri"); 7665 } 7666 7667 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7668 modeFlags, owner, targetUserId); 7669 } 7670 } 7671 7672 /** 7673 * @param uri This uri must NOT contain an embedded userId. 7674 * @param userId The userId in which the uri is to be resolved. 7675 */ 7676 @Override 7677 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7678 synchronized(this) { 7679 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7680 if (owner == null) { 7681 throw new IllegalArgumentException("Unknown owner: " + token); 7682 } 7683 7684 if (uri == null) { 7685 owner.removeUriPermissionsLocked(mode); 7686 } else { 7687 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7688 } 7689 } 7690 } 7691 7692 private void schedulePersistUriGrants() { 7693 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7694 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7695 10 * DateUtils.SECOND_IN_MILLIS); 7696 } 7697 } 7698 7699 private void writeGrantedUriPermissions() { 7700 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7701 7702 // Snapshot permissions so we can persist without lock 7703 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7704 synchronized (this) { 7705 final int size = mGrantedUriPermissions.size(); 7706 for (int i = 0; i < size; i++) { 7707 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7708 for (UriPermission perm : perms.values()) { 7709 if (perm.persistedModeFlags != 0) { 7710 persist.add(perm.snapshot()); 7711 } 7712 } 7713 } 7714 } 7715 7716 FileOutputStream fos = null; 7717 try { 7718 fos = mGrantFile.startWrite(); 7719 7720 XmlSerializer out = new FastXmlSerializer(); 7721 out.setOutput(fos, "utf-8"); 7722 out.startDocument(null, true); 7723 out.startTag(null, TAG_URI_GRANTS); 7724 for (UriPermission.Snapshot perm : persist) { 7725 out.startTag(null, TAG_URI_GRANT); 7726 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7727 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7728 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7729 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7730 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7731 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7732 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7733 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7734 out.endTag(null, TAG_URI_GRANT); 7735 } 7736 out.endTag(null, TAG_URI_GRANTS); 7737 out.endDocument(); 7738 7739 mGrantFile.finishWrite(fos); 7740 } catch (IOException e) { 7741 if (fos != null) { 7742 mGrantFile.failWrite(fos); 7743 } 7744 } 7745 } 7746 7747 private void readGrantedUriPermissionsLocked() { 7748 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7749 7750 final long now = System.currentTimeMillis(); 7751 7752 FileInputStream fis = null; 7753 try { 7754 fis = mGrantFile.openRead(); 7755 final XmlPullParser in = Xml.newPullParser(); 7756 in.setInput(fis, null); 7757 7758 int type; 7759 while ((type = in.next()) != END_DOCUMENT) { 7760 final String tag = in.getName(); 7761 if (type == START_TAG) { 7762 if (TAG_URI_GRANT.equals(tag)) { 7763 final int sourceUserId; 7764 final int targetUserId; 7765 final int userHandle = readIntAttribute(in, 7766 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7767 if (userHandle != UserHandle.USER_NULL) { 7768 // For backwards compatibility. 7769 sourceUserId = userHandle; 7770 targetUserId = userHandle; 7771 } else { 7772 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7773 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7774 } 7775 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7776 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7777 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7778 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7779 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7780 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7781 7782 // Sanity check that provider still belongs to source package 7783 final ProviderInfo pi = getProviderInfoLocked( 7784 uri.getAuthority(), sourceUserId); 7785 if (pi != null && sourcePkg.equals(pi.packageName)) { 7786 int targetUid = -1; 7787 try { 7788 targetUid = AppGlobals.getPackageManager() 7789 .getPackageUid(targetPkg, targetUserId); 7790 } catch (RemoteException e) { 7791 } 7792 if (targetUid != -1) { 7793 final UriPermission perm = findOrCreateUriPermissionLocked( 7794 sourcePkg, targetPkg, targetUid, 7795 new GrantUri(sourceUserId, uri, prefix)); 7796 perm.initPersistedModes(modeFlags, createdTime); 7797 } 7798 } else { 7799 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7800 + " but instead found " + pi); 7801 } 7802 } 7803 } 7804 } 7805 } catch (FileNotFoundException e) { 7806 // Missing grants is okay 7807 } catch (IOException e) { 7808 Slog.wtf(TAG, "Failed reading Uri grants", e); 7809 } catch (XmlPullParserException e) { 7810 Slog.wtf(TAG, "Failed reading Uri grants", e); 7811 } finally { 7812 IoUtils.closeQuietly(fis); 7813 } 7814 } 7815 7816 /** 7817 * @param uri This uri must NOT contain an embedded userId. 7818 * @param userId The userId in which the uri is to be resolved. 7819 */ 7820 @Override 7821 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7822 enforceNotIsolatedCaller("takePersistableUriPermission"); 7823 7824 Preconditions.checkFlagsArgument(modeFlags, 7825 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7826 7827 synchronized (this) { 7828 final int callingUid = Binder.getCallingUid(); 7829 boolean persistChanged = false; 7830 GrantUri grantUri = new GrantUri(userId, uri, false); 7831 7832 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7833 new GrantUri(userId, uri, false)); 7834 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7835 new GrantUri(userId, uri, true)); 7836 7837 final boolean exactValid = (exactPerm != null) 7838 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7839 final boolean prefixValid = (prefixPerm != null) 7840 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7841 7842 if (!(exactValid || prefixValid)) { 7843 throw new SecurityException("No persistable permission grants found for UID " 7844 + callingUid + " and Uri " + grantUri.toSafeString()); 7845 } 7846 7847 if (exactValid) { 7848 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7849 } 7850 if (prefixValid) { 7851 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7852 } 7853 7854 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7855 7856 if (persistChanged) { 7857 schedulePersistUriGrants(); 7858 } 7859 } 7860 } 7861 7862 /** 7863 * @param uri This uri must NOT contain an embedded userId. 7864 * @param userId The userId in which the uri is to be resolved. 7865 */ 7866 @Override 7867 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7868 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7869 7870 Preconditions.checkFlagsArgument(modeFlags, 7871 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7872 7873 synchronized (this) { 7874 final int callingUid = Binder.getCallingUid(); 7875 boolean persistChanged = false; 7876 7877 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7878 new GrantUri(userId, uri, false)); 7879 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7880 new GrantUri(userId, uri, true)); 7881 if (exactPerm == null && prefixPerm == null) { 7882 throw new SecurityException("No permission grants found for UID " + callingUid 7883 + " and Uri " + uri.toSafeString()); 7884 } 7885 7886 if (exactPerm != null) { 7887 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7888 removeUriPermissionIfNeededLocked(exactPerm); 7889 } 7890 if (prefixPerm != null) { 7891 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7892 removeUriPermissionIfNeededLocked(prefixPerm); 7893 } 7894 7895 if (persistChanged) { 7896 schedulePersistUriGrants(); 7897 } 7898 } 7899 } 7900 7901 /** 7902 * Prune any older {@link UriPermission} for the given UID until outstanding 7903 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7904 * 7905 * @return if any mutations occured that require persisting. 7906 */ 7907 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7908 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7909 if (perms == null) return false; 7910 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7911 7912 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7913 for (UriPermission perm : perms.values()) { 7914 if (perm.persistedModeFlags != 0) { 7915 persisted.add(perm); 7916 } 7917 } 7918 7919 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7920 if (trimCount <= 0) return false; 7921 7922 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7923 for (int i = 0; i < trimCount; i++) { 7924 final UriPermission perm = persisted.get(i); 7925 7926 if (DEBUG_URI_PERMISSION) { 7927 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7928 } 7929 7930 perm.releasePersistableModes(~0); 7931 removeUriPermissionIfNeededLocked(perm); 7932 } 7933 7934 return true; 7935 } 7936 7937 @Override 7938 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7939 String packageName, boolean incoming) { 7940 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7941 Preconditions.checkNotNull(packageName, "packageName"); 7942 7943 final int callingUid = Binder.getCallingUid(); 7944 final IPackageManager pm = AppGlobals.getPackageManager(); 7945 try { 7946 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7947 if (packageUid != callingUid) { 7948 throw new SecurityException( 7949 "Package " + packageName + " does not belong to calling UID " + callingUid); 7950 } 7951 } catch (RemoteException e) { 7952 throw new SecurityException("Failed to verify package name ownership"); 7953 } 7954 7955 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7956 synchronized (this) { 7957 if (incoming) { 7958 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7959 callingUid); 7960 if (perms == null) { 7961 Slog.w(TAG, "No permission grants found for " + packageName); 7962 } else { 7963 for (UriPermission perm : perms.values()) { 7964 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7965 result.add(perm.buildPersistedPublicApiObject()); 7966 } 7967 } 7968 } 7969 } else { 7970 final int size = mGrantedUriPermissions.size(); 7971 for (int i = 0; i < size; i++) { 7972 final ArrayMap<GrantUri, UriPermission> perms = 7973 mGrantedUriPermissions.valueAt(i); 7974 for (UriPermission perm : perms.values()) { 7975 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7976 result.add(perm.buildPersistedPublicApiObject()); 7977 } 7978 } 7979 } 7980 } 7981 } 7982 return new ParceledListSlice<android.content.UriPermission>(result); 7983 } 7984 7985 @Override 7986 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7987 synchronized (this) { 7988 ProcessRecord app = 7989 who != null ? getRecordForAppLocked(who) : null; 7990 if (app == null) return; 7991 7992 Message msg = Message.obtain(); 7993 msg.what = WAIT_FOR_DEBUGGER_MSG; 7994 msg.obj = app; 7995 msg.arg1 = waiting ? 1 : 0; 7996 mHandler.sendMessage(msg); 7997 } 7998 } 7999 8000 @Override 8001 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8002 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8003 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8004 outInfo.availMem = Process.getFreeMemory(); 8005 outInfo.totalMem = Process.getTotalMemory(); 8006 outInfo.threshold = homeAppMem; 8007 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8008 outInfo.hiddenAppThreshold = cachedAppMem; 8009 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8010 ProcessList.SERVICE_ADJ); 8011 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8012 ProcessList.VISIBLE_APP_ADJ); 8013 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8014 ProcessList.FOREGROUND_APP_ADJ); 8015 } 8016 8017 // ========================================================= 8018 // TASK MANAGEMENT 8019 // ========================================================= 8020 8021 @Override 8022 public List<IAppTask> getAppTasks(String callingPackage) { 8023 int callingUid = Binder.getCallingUid(); 8024 long ident = Binder.clearCallingIdentity(); 8025 8026 synchronized(this) { 8027 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8028 try { 8029 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8030 8031 final int N = mRecentTasks.size(); 8032 for (int i = 0; i < N; i++) { 8033 TaskRecord tr = mRecentTasks.get(i); 8034 // Skip tasks that do not match the caller. We don't need to verify 8035 // callingPackage, because we are also limiting to callingUid and know 8036 // that will limit to the correct security sandbox. 8037 if (tr.effectiveUid != callingUid) { 8038 continue; 8039 } 8040 Intent intent = tr.getBaseIntent(); 8041 if (intent == null || 8042 !callingPackage.equals(intent.getComponent().getPackageName())) { 8043 continue; 8044 } 8045 ActivityManager.RecentTaskInfo taskInfo = 8046 createRecentTaskInfoFromTaskRecord(tr); 8047 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8048 list.add(taskImpl); 8049 } 8050 } finally { 8051 Binder.restoreCallingIdentity(ident); 8052 } 8053 return list; 8054 } 8055 } 8056 8057 @Override 8058 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8059 final int callingUid = Binder.getCallingUid(); 8060 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8061 8062 synchronized(this) { 8063 if (localLOGV) Slog.v( 8064 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8065 8066 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8067 callingUid); 8068 8069 // TODO: Improve with MRU list from all ActivityStacks. 8070 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8071 } 8072 8073 return list; 8074 } 8075 8076 /** 8077 * Creates a new RecentTaskInfo from a TaskRecord. 8078 */ 8079 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8080 // Update the task description to reflect any changes in the task stack 8081 tr.updateTaskDescription(); 8082 8083 // Compose the recent task info 8084 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8085 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8086 rti.persistentId = tr.taskId; 8087 rti.baseIntent = new Intent(tr.getBaseIntent()); 8088 rti.origActivity = tr.origActivity; 8089 rti.description = tr.lastDescription; 8090 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8091 rti.userId = tr.userId; 8092 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8093 rti.firstActiveTime = tr.firstActiveTime; 8094 rti.lastActiveTime = tr.lastActiveTime; 8095 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8096 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8097 return rti; 8098 } 8099 8100 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8101 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8102 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8103 if (!allowed) { 8104 if (checkPermission(android.Manifest.permission.GET_TASKS, 8105 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8106 // Temporary compatibility: some existing apps on the system image may 8107 // still be requesting the old permission and not switched to the new 8108 // one; if so, we'll still allow them full access. This means we need 8109 // to see if they are holding the old permission and are a system app. 8110 try { 8111 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8112 allowed = true; 8113 Slog.w(TAG, caller + ": caller " + callingUid 8114 + " is using old GET_TASKS but privileged; allowing"); 8115 } 8116 } catch (RemoteException e) { 8117 } 8118 } 8119 } 8120 if (!allowed) { 8121 Slog.w(TAG, caller + ": caller " + callingUid 8122 + " does not hold GET_TASKS; limiting output"); 8123 } 8124 return allowed; 8125 } 8126 8127 @Override 8128 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8129 final int callingUid = Binder.getCallingUid(); 8130 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8131 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8132 8133 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8134 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8135 synchronized (this) { 8136 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8137 callingUid); 8138 final boolean detailed = checkCallingPermission( 8139 android.Manifest.permission.GET_DETAILED_TASKS) 8140 == PackageManager.PERMISSION_GRANTED; 8141 8142 final int N = mRecentTasks.size(); 8143 ArrayList<ActivityManager.RecentTaskInfo> res 8144 = new ArrayList<ActivityManager.RecentTaskInfo>( 8145 maxNum < N ? maxNum : N); 8146 8147 final Set<Integer> includedUsers; 8148 if (includeProfiles) { 8149 includedUsers = getProfileIdsLocked(userId); 8150 } else { 8151 includedUsers = new HashSet<Integer>(); 8152 } 8153 includedUsers.add(Integer.valueOf(userId)); 8154 8155 for (int i=0; i<N && maxNum > 0; i++) { 8156 TaskRecord tr = mRecentTasks.get(i); 8157 // Only add calling user or related users recent tasks 8158 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8159 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8160 continue; 8161 } 8162 8163 // Return the entry if desired by the caller. We always return 8164 // the first entry, because callers always expect this to be the 8165 // foreground app. We may filter others if the caller has 8166 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8167 // we should exclude the entry. 8168 8169 if (i == 0 8170 || withExcluded 8171 || (tr.intent == null) 8172 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8173 == 0)) { 8174 if (!allowed) { 8175 // If the caller doesn't have the GET_TASKS permission, then only 8176 // allow them to see a small subset of tasks -- their own and home. 8177 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8178 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8179 continue; 8180 } 8181 } 8182 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8183 if (tr.stack != null && tr.stack.isHomeStack()) { 8184 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8185 continue; 8186 } 8187 } 8188 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8189 // Don't include auto remove tasks that are finished or finishing. 8190 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8191 + tr); 8192 continue; 8193 } 8194 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8195 && !tr.isAvailable) { 8196 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8197 continue; 8198 } 8199 8200 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8201 if (!detailed) { 8202 rti.baseIntent.replaceExtras((Bundle)null); 8203 } 8204 8205 res.add(rti); 8206 maxNum--; 8207 } 8208 } 8209 return res; 8210 } 8211 } 8212 8213 TaskRecord recentTaskForIdLocked(int id) { 8214 final int N = mRecentTasks.size(); 8215 for (int i=0; i<N; i++) { 8216 TaskRecord tr = mRecentTasks.get(i); 8217 if (tr.taskId == id) { 8218 return tr; 8219 } 8220 } 8221 return null; 8222 } 8223 8224 @Override 8225 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8226 synchronized (this) { 8227 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8228 "getTaskThumbnail()"); 8229 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8230 if (tr != null) { 8231 return tr.getTaskThumbnailLocked(); 8232 } 8233 } 8234 return null; 8235 } 8236 8237 @Override 8238 public int addAppTask(IBinder activityToken, Intent intent, 8239 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8240 final int callingUid = Binder.getCallingUid(); 8241 final long callingIdent = Binder.clearCallingIdentity(); 8242 8243 try { 8244 synchronized (this) { 8245 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8246 if (r == null) { 8247 throw new IllegalArgumentException("Activity does not exist; token=" 8248 + activityToken); 8249 } 8250 ComponentName comp = intent.getComponent(); 8251 if (comp == null) { 8252 throw new IllegalArgumentException("Intent " + intent 8253 + " must specify explicit component"); 8254 } 8255 if (thumbnail.getWidth() != mThumbnailWidth 8256 || thumbnail.getHeight() != mThumbnailHeight) { 8257 throw new IllegalArgumentException("Bad thumbnail size: got " 8258 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8259 + mThumbnailWidth + "x" + mThumbnailHeight); 8260 } 8261 if (intent.getSelector() != null) { 8262 intent.setSelector(null); 8263 } 8264 if (intent.getSourceBounds() != null) { 8265 intent.setSourceBounds(null); 8266 } 8267 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8268 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8269 // The caller has added this as an auto-remove task... that makes no 8270 // sense, so turn off auto-remove. 8271 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8272 } 8273 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8274 // Must be a new task. 8275 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8276 } 8277 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8278 mLastAddedTaskActivity = null; 8279 } 8280 ActivityInfo ainfo = mLastAddedTaskActivity; 8281 if (ainfo == null) { 8282 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8283 comp, 0, UserHandle.getUserId(callingUid)); 8284 if (ainfo.applicationInfo.uid != callingUid) { 8285 throw new SecurityException( 8286 "Can't add task for another application: target uid=" 8287 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8288 } 8289 } 8290 8291 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8292 intent, description); 8293 8294 int trimIdx = trimRecentsForTaskLocked(task, false); 8295 if (trimIdx >= 0) { 8296 // If this would have caused a trim, then we'll abort because that 8297 // means it would be added at the end of the list but then just removed. 8298 return INVALID_TASK_ID; 8299 } 8300 8301 final int N = mRecentTasks.size(); 8302 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8303 final TaskRecord tr = mRecentTasks.remove(N - 1); 8304 tr.removedFromRecents(); 8305 } 8306 8307 task.inRecents = true; 8308 mRecentTasks.add(task); 8309 r.task.stack.addTask(task, false, false); 8310 8311 task.setLastThumbnail(thumbnail); 8312 task.freeLastThumbnail(); 8313 8314 return task.taskId; 8315 } 8316 } finally { 8317 Binder.restoreCallingIdentity(callingIdent); 8318 } 8319 } 8320 8321 @Override 8322 public Point getAppTaskThumbnailSize() { 8323 synchronized (this) { 8324 return new Point(mThumbnailWidth, mThumbnailHeight); 8325 } 8326 } 8327 8328 @Override 8329 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8330 synchronized (this) { 8331 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8332 if (r != null) { 8333 r.setTaskDescription(td); 8334 r.task.updateTaskDescription(); 8335 } 8336 } 8337 } 8338 8339 @Override 8340 public Bitmap getTaskDescriptionIcon(String filename) { 8341 if (!FileUtils.isValidExtFilename(filename) 8342 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8343 throw new IllegalArgumentException("Bad filename: " + filename); 8344 } 8345 return mTaskPersister.getTaskDescriptionIcon(filename); 8346 } 8347 8348 @Override 8349 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8350 throws RemoteException { 8351 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8352 opts.getCustomInPlaceResId() == 0) { 8353 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8354 "with valid animation"); 8355 } 8356 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8357 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8358 opts.getCustomInPlaceResId()); 8359 mWindowManager.executeAppTransition(); 8360 } 8361 8362 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8363 mRecentTasks.remove(tr); 8364 tr.removedFromRecents(); 8365 ComponentName component = tr.getBaseIntent().getComponent(); 8366 if (component == null) { 8367 Slog.w(TAG, "No component for base intent of task: " + tr); 8368 return; 8369 } 8370 8371 if (!killProcess) { 8372 return; 8373 } 8374 8375 // Determine if the process(es) for this task should be killed. 8376 final String pkg = component.getPackageName(); 8377 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8378 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8379 for (int i = 0; i < pmap.size(); i++) { 8380 8381 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8382 for (int j = 0; j < uids.size(); j++) { 8383 ProcessRecord proc = uids.valueAt(j); 8384 if (proc.userId != tr.userId) { 8385 // Don't kill process for a different user. 8386 continue; 8387 } 8388 if (proc == mHomeProcess) { 8389 // Don't kill the home process along with tasks from the same package. 8390 continue; 8391 } 8392 if (!proc.pkgList.containsKey(pkg)) { 8393 // Don't kill process that is not associated with this task. 8394 continue; 8395 } 8396 8397 for (int k = 0; k < proc.activities.size(); k++) { 8398 TaskRecord otherTask = proc.activities.get(k).task; 8399 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8400 // Don't kill process(es) that has an activity in a different task that is 8401 // also in recents. 8402 return; 8403 } 8404 } 8405 8406 // Add process to kill list. 8407 procsToKill.add(proc); 8408 } 8409 } 8410 8411 // Find any running services associated with this app and stop if needed. 8412 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8413 8414 // Kill the running processes. 8415 for (int i = 0; i < procsToKill.size(); i++) { 8416 ProcessRecord pr = procsToKill.get(i); 8417 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8418 pr.kill("remove task", true); 8419 } else { 8420 pr.waitingToKill = "remove task"; 8421 } 8422 } 8423 } 8424 8425 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8426 // Remove all tasks with activities in the specified package from the list of recent tasks 8427 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8428 TaskRecord tr = mRecentTasks.get(i); 8429 if (tr.userId != userId) continue; 8430 8431 ComponentName cn = tr.intent.getComponent(); 8432 if (cn != null && cn.getPackageName().equals(packageName)) { 8433 // If the package name matches, remove the task. 8434 removeTaskByIdLocked(tr.taskId, true); 8435 } 8436 } 8437 } 8438 8439 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8440 final IPackageManager pm = AppGlobals.getPackageManager(); 8441 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8442 8443 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8444 TaskRecord tr = mRecentTasks.get(i); 8445 if (tr.userId != userId) continue; 8446 8447 ComponentName cn = tr.intent.getComponent(); 8448 if (cn != null && cn.getPackageName().equals(packageName)) { 8449 // Skip if component still exists in the package. 8450 if (componentsKnownToExist.contains(cn)) continue; 8451 8452 try { 8453 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8454 if (info != null) { 8455 componentsKnownToExist.add(cn); 8456 } else { 8457 removeTaskByIdLocked(tr.taskId, false); 8458 } 8459 } catch (RemoteException e) { 8460 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8461 } 8462 } 8463 } 8464 } 8465 8466 /** 8467 * Removes the task with the specified task id. 8468 * 8469 * @param taskId Identifier of the task to be removed. 8470 * @param killProcess Kill any process associated with the task if possible. 8471 * @return Returns true if the given task was found and removed. 8472 */ 8473 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8474 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8475 if (tr != null) { 8476 tr.removeTaskActivitiesLocked(); 8477 cleanUpRemovedTaskLocked(tr, killProcess); 8478 if (tr.isPersistable) { 8479 notifyTaskPersisterLocked(null, true); 8480 } 8481 return true; 8482 } 8483 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8484 return false; 8485 } 8486 8487 @Override 8488 public boolean removeTask(int taskId) { 8489 synchronized (this) { 8490 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8491 "removeTask()"); 8492 long ident = Binder.clearCallingIdentity(); 8493 try { 8494 return removeTaskByIdLocked(taskId, true); 8495 } finally { 8496 Binder.restoreCallingIdentity(ident); 8497 } 8498 } 8499 } 8500 8501 /** 8502 * TODO: Add mController hook 8503 */ 8504 @Override 8505 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8506 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8507 "moveTaskToFront()"); 8508 8509 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8510 synchronized(this) { 8511 moveTaskToFrontLocked(taskId, flags, options); 8512 } 8513 } 8514 8515 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8516 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8517 Binder.getCallingUid(), -1, -1, "Task to front")) { 8518 ActivityOptions.abort(options); 8519 return; 8520 } 8521 final long origId = Binder.clearCallingIdentity(); 8522 try { 8523 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8524 if (task == null) { 8525 Slog.d(TAG, "Could not find task for id: "+ taskId); 8526 return; 8527 } 8528 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8529 mStackSupervisor.showLockTaskToast(); 8530 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8531 return; 8532 } 8533 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8534 if (prev != null && prev.isRecentsActivity()) { 8535 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8536 } 8537 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8538 } finally { 8539 Binder.restoreCallingIdentity(origId); 8540 } 8541 ActivityOptions.abort(options); 8542 } 8543 8544 @Override 8545 public void moveTaskToBack(int taskId) { 8546 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8547 "moveTaskToBack()"); 8548 8549 synchronized(this) { 8550 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8551 if (tr != null) { 8552 if (tr == mStackSupervisor.mLockTaskModeTask) { 8553 mStackSupervisor.showLockTaskToast(); 8554 return; 8555 } 8556 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8557 ActivityStack stack = tr.stack; 8558 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8559 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8560 Binder.getCallingUid(), -1, -1, "Task to back")) { 8561 return; 8562 } 8563 } 8564 final long origId = Binder.clearCallingIdentity(); 8565 try { 8566 stack.moveTaskToBackLocked(taskId, null); 8567 } finally { 8568 Binder.restoreCallingIdentity(origId); 8569 } 8570 } 8571 } 8572 } 8573 8574 /** 8575 * Moves an activity, and all of the other activities within the same task, to the bottom 8576 * of the history stack. The activity's order within the task is unchanged. 8577 * 8578 * @param token A reference to the activity we wish to move 8579 * @param nonRoot If false then this only works if the activity is the root 8580 * of a task; if true it will work for any activity in a task. 8581 * @return Returns true if the move completed, false if not. 8582 */ 8583 @Override 8584 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8585 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8586 synchronized(this) { 8587 final long origId = Binder.clearCallingIdentity(); 8588 try { 8589 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8590 if (taskId >= 0) { 8591 if ((mStackSupervisor.mLockTaskModeTask != null) 8592 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8593 mStackSupervisor.showLockTaskToast(); 8594 return false; 8595 } 8596 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8597 } 8598 } finally { 8599 Binder.restoreCallingIdentity(origId); 8600 } 8601 } 8602 return false; 8603 } 8604 8605 @Override 8606 public void moveTaskBackwards(int task) { 8607 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8608 "moveTaskBackwards()"); 8609 8610 synchronized(this) { 8611 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8612 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8613 return; 8614 } 8615 final long origId = Binder.clearCallingIdentity(); 8616 moveTaskBackwardsLocked(task); 8617 Binder.restoreCallingIdentity(origId); 8618 } 8619 } 8620 8621 private final void moveTaskBackwardsLocked(int task) { 8622 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8623 } 8624 8625 @Override 8626 public IBinder getHomeActivityToken() throws RemoteException { 8627 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8628 "getHomeActivityToken()"); 8629 synchronized (this) { 8630 return mStackSupervisor.getHomeActivityToken(); 8631 } 8632 } 8633 8634 @Override 8635 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8636 IActivityContainerCallback callback) throws RemoteException { 8637 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8638 "createActivityContainer()"); 8639 synchronized (this) { 8640 if (parentActivityToken == null) { 8641 throw new IllegalArgumentException("parent token must not be null"); 8642 } 8643 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8644 if (r == null) { 8645 return null; 8646 } 8647 if (callback == null) { 8648 throw new IllegalArgumentException("callback must not be null"); 8649 } 8650 return mStackSupervisor.createActivityContainer(r, callback); 8651 } 8652 } 8653 8654 @Override 8655 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8656 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8657 "deleteActivityContainer()"); 8658 synchronized (this) { 8659 mStackSupervisor.deleteActivityContainer(container); 8660 } 8661 } 8662 8663 @Override 8664 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8665 throws RemoteException { 8666 synchronized (this) { 8667 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8668 if (stack != null) { 8669 return stack.mActivityContainer; 8670 } 8671 return null; 8672 } 8673 } 8674 8675 @Override 8676 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8677 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8678 "moveTaskToStack()"); 8679 if (stackId == HOME_STACK_ID) { 8680 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8681 new RuntimeException("here").fillInStackTrace()); 8682 } 8683 synchronized (this) { 8684 long ident = Binder.clearCallingIdentity(); 8685 try { 8686 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8687 + stackId + " toTop=" + toTop); 8688 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8689 } finally { 8690 Binder.restoreCallingIdentity(ident); 8691 } 8692 } 8693 } 8694 8695 @Override 8696 public void resizeStack(int stackBoxId, Rect bounds) { 8697 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8698 "resizeStackBox()"); 8699 long ident = Binder.clearCallingIdentity(); 8700 try { 8701 mWindowManager.resizeStack(stackBoxId, bounds); 8702 } finally { 8703 Binder.restoreCallingIdentity(ident); 8704 } 8705 } 8706 8707 @Override 8708 public List<StackInfo> getAllStackInfos() { 8709 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8710 "getAllStackInfos()"); 8711 long ident = Binder.clearCallingIdentity(); 8712 try { 8713 synchronized (this) { 8714 return mStackSupervisor.getAllStackInfosLocked(); 8715 } 8716 } finally { 8717 Binder.restoreCallingIdentity(ident); 8718 } 8719 } 8720 8721 @Override 8722 public StackInfo getStackInfo(int stackId) { 8723 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8724 "getStackInfo()"); 8725 long ident = Binder.clearCallingIdentity(); 8726 try { 8727 synchronized (this) { 8728 return mStackSupervisor.getStackInfoLocked(stackId); 8729 } 8730 } finally { 8731 Binder.restoreCallingIdentity(ident); 8732 } 8733 } 8734 8735 @Override 8736 public boolean isInHomeStack(int taskId) { 8737 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8738 "getStackInfo()"); 8739 long ident = Binder.clearCallingIdentity(); 8740 try { 8741 synchronized (this) { 8742 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8743 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8744 } 8745 } finally { 8746 Binder.restoreCallingIdentity(ident); 8747 } 8748 } 8749 8750 @Override 8751 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8752 synchronized(this) { 8753 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8754 } 8755 } 8756 8757 private boolean isLockTaskAuthorized(String pkg) { 8758 final DevicePolicyManager dpm = (DevicePolicyManager) 8759 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8760 try { 8761 int uid = mContext.getPackageManager().getPackageUid(pkg, 8762 Binder.getCallingUserHandle().getIdentifier()); 8763 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8764 } catch (NameNotFoundException e) { 8765 return false; 8766 } 8767 } 8768 8769 void startLockTaskMode(TaskRecord task) { 8770 final String pkg; 8771 synchronized (this) { 8772 pkg = task.intent.getComponent().getPackageName(); 8773 } 8774 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8775 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8776 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8777 StatusBarManagerInternal.class); 8778 if (statusBarManager != null) { 8779 statusBarManager.showScreenPinningRequest(); 8780 } 8781 return; 8782 } 8783 long ident = Binder.clearCallingIdentity(); 8784 try { 8785 synchronized (this) { 8786 // Since we lost lock on task, make sure it is still there. 8787 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8788 if (task != null) { 8789 if (!isSystemInitiated 8790 && ((mStackSupervisor.getFocusedStack() == null) 8791 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8792 throw new IllegalArgumentException("Invalid task, not in foreground"); 8793 } 8794 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8795 } 8796 } 8797 } finally { 8798 Binder.restoreCallingIdentity(ident); 8799 } 8800 } 8801 8802 @Override 8803 public void startLockTaskMode(int taskId) { 8804 final TaskRecord task; 8805 long ident = Binder.clearCallingIdentity(); 8806 try { 8807 synchronized (this) { 8808 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8809 } 8810 } finally { 8811 Binder.restoreCallingIdentity(ident); 8812 } 8813 if (task != null) { 8814 startLockTaskMode(task); 8815 } 8816 } 8817 8818 @Override 8819 public void startLockTaskMode(IBinder token) { 8820 final TaskRecord task; 8821 long ident = Binder.clearCallingIdentity(); 8822 try { 8823 synchronized (this) { 8824 final ActivityRecord r = ActivityRecord.forToken(token); 8825 if (r == null) { 8826 return; 8827 } 8828 task = r.task; 8829 } 8830 } finally { 8831 Binder.restoreCallingIdentity(ident); 8832 } 8833 if (task != null) { 8834 startLockTaskMode(task); 8835 } 8836 } 8837 8838 @Override 8839 public void startLockTaskModeOnCurrent() throws RemoteException { 8840 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8841 "startLockTaskModeOnCurrent"); 8842 long ident = Binder.clearCallingIdentity(); 8843 try { 8844 ActivityRecord r = null; 8845 synchronized (this) { 8846 r = mStackSupervisor.topRunningActivityLocked(); 8847 } 8848 startLockTaskMode(r.task); 8849 } finally { 8850 Binder.restoreCallingIdentity(ident); 8851 } 8852 } 8853 8854 @Override 8855 public void stopLockTaskMode() { 8856 // Verify that the user matches the package of the intent for the TaskRecord 8857 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8858 // and stopLockTaskMode. 8859 final int callingUid = Binder.getCallingUid(); 8860 if (callingUid != Process.SYSTEM_UID) { 8861 try { 8862 String pkg = 8863 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8864 int uid = mContext.getPackageManager().getPackageUid(pkg, 8865 Binder.getCallingUserHandle().getIdentifier()); 8866 if (uid != callingUid) { 8867 throw new SecurityException("Invalid uid, expected " + uid); 8868 } 8869 } catch (NameNotFoundException e) { 8870 Log.d(TAG, "stopLockTaskMode " + e); 8871 return; 8872 } 8873 } 8874 long ident = Binder.clearCallingIdentity(); 8875 try { 8876 Log.d(TAG, "stopLockTaskMode"); 8877 // Stop lock task 8878 synchronized (this) { 8879 mStackSupervisor.setLockTaskModeLocked(null, false); 8880 } 8881 } finally { 8882 Binder.restoreCallingIdentity(ident); 8883 } 8884 } 8885 8886 @Override 8887 public void stopLockTaskModeOnCurrent() throws RemoteException { 8888 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8889 "stopLockTaskModeOnCurrent"); 8890 long ident = Binder.clearCallingIdentity(); 8891 try { 8892 stopLockTaskMode(); 8893 } finally { 8894 Binder.restoreCallingIdentity(ident); 8895 } 8896 } 8897 8898 @Override 8899 public boolean isInLockTaskMode() { 8900 synchronized (this) { 8901 return mStackSupervisor.isInLockTaskMode(); 8902 } 8903 } 8904 8905 // ========================================================= 8906 // CONTENT PROVIDERS 8907 // ========================================================= 8908 8909 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8910 List<ProviderInfo> providers = null; 8911 try { 8912 providers = AppGlobals.getPackageManager(). 8913 queryContentProviders(app.processName, app.uid, 8914 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8915 } catch (RemoteException ex) { 8916 } 8917 if (DEBUG_MU) 8918 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8919 int userId = app.userId; 8920 if (providers != null) { 8921 int N = providers.size(); 8922 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8923 for (int i=0; i<N; i++) { 8924 ProviderInfo cpi = 8925 (ProviderInfo)providers.get(i); 8926 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8927 cpi.name, cpi.flags); 8928 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8929 // This is a singleton provider, but a user besides the 8930 // default user is asking to initialize a process it runs 8931 // in... well, no, it doesn't actually run in this process, 8932 // it runs in the process of the default user. Get rid of it. 8933 providers.remove(i); 8934 N--; 8935 i--; 8936 continue; 8937 } 8938 8939 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8940 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8941 if (cpr == null) { 8942 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8943 mProviderMap.putProviderByClass(comp, cpr); 8944 } 8945 if (DEBUG_MU) 8946 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8947 app.pubProviders.put(cpi.name, cpr); 8948 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8949 // Don't add this if it is a platform component that is marked 8950 // to run in multiple processes, because this is actually 8951 // part of the framework so doesn't make sense to track as a 8952 // separate apk in the process. 8953 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8954 mProcessStats); 8955 } 8956 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8957 } 8958 } 8959 return providers; 8960 } 8961 8962 /** 8963 * Check if {@link ProcessRecord} has a possible chance at accessing the 8964 * given {@link ProviderInfo}. Final permission checking is always done 8965 * in {@link ContentProvider}. 8966 */ 8967 private final String checkContentProviderPermissionLocked( 8968 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8969 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8970 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8971 boolean checkedGrants = false; 8972 if (checkUser) { 8973 // Looking for cross-user grants before enforcing the typical cross-users permissions 8974 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8975 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8976 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8977 return null; 8978 } 8979 checkedGrants = true; 8980 } 8981 userId = handleIncomingUser(callingPid, callingUid, userId, 8982 false, ALLOW_NON_FULL, 8983 "checkContentProviderPermissionLocked " + cpi.authority, null); 8984 if (userId != tmpTargetUserId) { 8985 // When we actually went to determine the final targer user ID, this ended 8986 // up different than our initial check for the authority. This is because 8987 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8988 // SELF. So we need to re-check the grants again. 8989 checkedGrants = false; 8990 } 8991 } 8992 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8993 cpi.applicationInfo.uid, cpi.exported) 8994 == PackageManager.PERMISSION_GRANTED) { 8995 return null; 8996 } 8997 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8998 cpi.applicationInfo.uid, cpi.exported) 8999 == PackageManager.PERMISSION_GRANTED) { 9000 return null; 9001 } 9002 9003 PathPermission[] pps = cpi.pathPermissions; 9004 if (pps != null) { 9005 int i = pps.length; 9006 while (i > 0) { 9007 i--; 9008 PathPermission pp = pps[i]; 9009 String pprperm = pp.getReadPermission(); 9010 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9011 cpi.applicationInfo.uid, cpi.exported) 9012 == PackageManager.PERMISSION_GRANTED) { 9013 return null; 9014 } 9015 String ppwperm = pp.getWritePermission(); 9016 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9017 cpi.applicationInfo.uid, cpi.exported) 9018 == PackageManager.PERMISSION_GRANTED) { 9019 return null; 9020 } 9021 } 9022 } 9023 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9024 return null; 9025 } 9026 9027 String msg; 9028 if (!cpi.exported) { 9029 msg = "Permission Denial: opening provider " + cpi.name 9030 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9031 + ", uid=" + callingUid + ") that is not exported from uid " 9032 + cpi.applicationInfo.uid; 9033 } else { 9034 msg = "Permission Denial: opening provider " + cpi.name 9035 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9036 + ", uid=" + callingUid + ") requires " 9037 + cpi.readPermission + " or " + cpi.writePermission; 9038 } 9039 Slog.w(TAG, msg); 9040 return msg; 9041 } 9042 9043 /** 9044 * Returns if the ContentProvider has granted a uri to callingUid 9045 */ 9046 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9047 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9048 if (perms != null) { 9049 for (int i=perms.size()-1; i>=0; i--) { 9050 GrantUri grantUri = perms.keyAt(i); 9051 if (grantUri.sourceUserId == userId || !checkUser) { 9052 if (matchesProvider(grantUri.uri, cpi)) { 9053 return true; 9054 } 9055 } 9056 } 9057 } 9058 return false; 9059 } 9060 9061 /** 9062 * Returns true if the uri authority is one of the authorities specified in the provider. 9063 */ 9064 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9065 String uriAuth = uri.getAuthority(); 9066 String cpiAuth = cpi.authority; 9067 if (cpiAuth.indexOf(';') == -1) { 9068 return cpiAuth.equals(uriAuth); 9069 } 9070 String[] cpiAuths = cpiAuth.split(";"); 9071 int length = cpiAuths.length; 9072 for (int i = 0; i < length; i++) { 9073 if (cpiAuths[i].equals(uriAuth)) return true; 9074 } 9075 return false; 9076 } 9077 9078 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9079 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9080 if (r != null) { 9081 for (int i=0; i<r.conProviders.size(); i++) { 9082 ContentProviderConnection conn = r.conProviders.get(i); 9083 if (conn.provider == cpr) { 9084 if (DEBUG_PROVIDER) Slog.v(TAG, 9085 "Adding provider requested by " 9086 + r.processName + " from process " 9087 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9088 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9089 if (stable) { 9090 conn.stableCount++; 9091 conn.numStableIncs++; 9092 } else { 9093 conn.unstableCount++; 9094 conn.numUnstableIncs++; 9095 } 9096 return conn; 9097 } 9098 } 9099 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9100 if (stable) { 9101 conn.stableCount = 1; 9102 conn.numStableIncs = 1; 9103 } else { 9104 conn.unstableCount = 1; 9105 conn.numUnstableIncs = 1; 9106 } 9107 cpr.connections.add(conn); 9108 r.conProviders.add(conn); 9109 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9110 return conn; 9111 } 9112 cpr.addExternalProcessHandleLocked(externalProcessToken); 9113 return null; 9114 } 9115 9116 boolean decProviderCountLocked(ContentProviderConnection conn, 9117 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9118 if (conn != null) { 9119 cpr = conn.provider; 9120 if (DEBUG_PROVIDER) Slog.v(TAG, 9121 "Removing provider requested by " 9122 + conn.client.processName + " from process " 9123 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9124 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9125 if (stable) { 9126 conn.stableCount--; 9127 } else { 9128 conn.unstableCount--; 9129 } 9130 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9131 cpr.connections.remove(conn); 9132 conn.client.conProviders.remove(conn); 9133 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9134 return true; 9135 } 9136 return false; 9137 } 9138 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9139 return false; 9140 } 9141 9142 private void checkTime(long startTime, String where) { 9143 long now = SystemClock.elapsedRealtime(); 9144 if ((now-startTime) > 1000) { 9145 // If we are taking more than a second, log about it. 9146 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9147 } 9148 } 9149 9150 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9151 String name, IBinder token, boolean stable, int userId) { 9152 ContentProviderRecord cpr; 9153 ContentProviderConnection conn = null; 9154 ProviderInfo cpi = null; 9155 9156 synchronized(this) { 9157 long startTime = SystemClock.elapsedRealtime(); 9158 9159 ProcessRecord r = null; 9160 if (caller != null) { 9161 r = getRecordForAppLocked(caller); 9162 if (r == null) { 9163 throw new SecurityException( 9164 "Unable to find app for caller " + caller 9165 + " (pid=" + Binder.getCallingPid() 9166 + ") when getting content provider " + name); 9167 } 9168 } 9169 9170 boolean checkCrossUser = true; 9171 9172 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9173 9174 // First check if this content provider has been published... 9175 cpr = mProviderMap.getProviderByName(name, userId); 9176 // If that didn't work, check if it exists for user 0 and then 9177 // verify that it's a singleton provider before using it. 9178 if (cpr == null && userId != UserHandle.USER_OWNER) { 9179 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9180 if (cpr != null) { 9181 cpi = cpr.info; 9182 if (isSingleton(cpi.processName, cpi.applicationInfo, 9183 cpi.name, cpi.flags) 9184 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9185 userId = UserHandle.USER_OWNER; 9186 checkCrossUser = false; 9187 } else { 9188 cpr = null; 9189 cpi = null; 9190 } 9191 } 9192 } 9193 9194 boolean providerRunning = cpr != null; 9195 if (providerRunning) { 9196 cpi = cpr.info; 9197 String msg; 9198 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9199 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9200 != null) { 9201 throw new SecurityException(msg); 9202 } 9203 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9204 9205 if (r != null && cpr.canRunHere(r)) { 9206 // This provider has been published or is in the process 9207 // of being published... but it is also allowed to run 9208 // in the caller's process, so don't make a connection 9209 // and just let the caller instantiate its own instance. 9210 ContentProviderHolder holder = cpr.newHolder(null); 9211 // don't give caller the provider object, it needs 9212 // to make its own. 9213 holder.provider = null; 9214 return holder; 9215 } 9216 9217 final long origId = Binder.clearCallingIdentity(); 9218 9219 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9220 9221 // In this case the provider instance already exists, so we can 9222 // return it right away. 9223 conn = incProviderCountLocked(r, cpr, token, stable); 9224 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9225 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9226 // If this is a perceptible app accessing the provider, 9227 // make sure to count it as being accessed and thus 9228 // back up on the LRU list. This is good because 9229 // content providers are often expensive to start. 9230 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9231 updateLruProcessLocked(cpr.proc, false, null); 9232 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9233 } 9234 } 9235 9236 if (cpr.proc != null) { 9237 if (false) { 9238 if (cpr.name.flattenToShortString().equals( 9239 "com.android.providers.calendar/.CalendarProvider2")) { 9240 Slog.v(TAG, "****************** KILLING " 9241 + cpr.name.flattenToShortString()); 9242 Process.killProcess(cpr.proc.pid); 9243 } 9244 } 9245 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9246 boolean success = updateOomAdjLocked(cpr.proc); 9247 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9248 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9249 // NOTE: there is still a race here where a signal could be 9250 // pending on the process even though we managed to update its 9251 // adj level. Not sure what to do about this, but at least 9252 // the race is now smaller. 9253 if (!success) { 9254 // Uh oh... it looks like the provider's process 9255 // has been killed on us. We need to wait for a new 9256 // process to be started, and make sure its death 9257 // doesn't kill our process. 9258 Slog.i(TAG, 9259 "Existing provider " + cpr.name.flattenToShortString() 9260 + " is crashing; detaching " + r); 9261 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9262 checkTime(startTime, "getContentProviderImpl: before appDied"); 9263 appDiedLocked(cpr.proc); 9264 checkTime(startTime, "getContentProviderImpl: after appDied"); 9265 if (!lastRef) { 9266 // This wasn't the last ref our process had on 9267 // the provider... we have now been killed, bail. 9268 return null; 9269 } 9270 providerRunning = false; 9271 conn = null; 9272 } 9273 } 9274 9275 Binder.restoreCallingIdentity(origId); 9276 } 9277 9278 boolean singleton; 9279 if (!providerRunning) { 9280 try { 9281 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9282 cpi = AppGlobals.getPackageManager(). 9283 resolveContentProvider(name, 9284 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9285 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9286 } catch (RemoteException ex) { 9287 } 9288 if (cpi == null) { 9289 return null; 9290 } 9291 // If the provider is a singleton AND 9292 // (it's a call within the same user || the provider is a 9293 // privileged app) 9294 // Then allow connecting to the singleton provider 9295 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9296 cpi.name, cpi.flags) 9297 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9298 if (singleton) { 9299 userId = UserHandle.USER_OWNER; 9300 } 9301 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9302 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9303 9304 String msg; 9305 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9306 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9307 != null) { 9308 throw new SecurityException(msg); 9309 } 9310 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9311 9312 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9313 && !cpi.processName.equals("system")) { 9314 // If this content provider does not run in the system 9315 // process, and the system is not yet ready to run other 9316 // processes, then fail fast instead of hanging. 9317 throw new IllegalArgumentException( 9318 "Attempt to launch content provider before system ready"); 9319 } 9320 9321 // Make sure that the user who owns this provider is running. If not, 9322 // we don't want to allow it to run. 9323 if (!isUserRunningLocked(userId, false)) { 9324 Slog.w(TAG, "Unable to launch app " 9325 + cpi.applicationInfo.packageName + "/" 9326 + cpi.applicationInfo.uid + " for provider " 9327 + name + ": user " + userId + " is stopped"); 9328 return null; 9329 } 9330 9331 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9332 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9333 cpr = mProviderMap.getProviderByClass(comp, userId); 9334 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9335 final boolean firstClass = cpr == null; 9336 if (firstClass) { 9337 final long ident = Binder.clearCallingIdentity(); 9338 try { 9339 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9340 ApplicationInfo ai = 9341 AppGlobals.getPackageManager(). 9342 getApplicationInfo( 9343 cpi.applicationInfo.packageName, 9344 STOCK_PM_FLAGS, userId); 9345 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9346 if (ai == null) { 9347 Slog.w(TAG, "No package info for content provider " 9348 + cpi.name); 9349 return null; 9350 } 9351 ai = getAppInfoForUser(ai, userId); 9352 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9353 } catch (RemoteException ex) { 9354 // pm is in same process, this will never happen. 9355 } finally { 9356 Binder.restoreCallingIdentity(ident); 9357 } 9358 } 9359 9360 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9361 9362 if (r != null && cpr.canRunHere(r)) { 9363 // If this is a multiprocess provider, then just return its 9364 // info and allow the caller to instantiate it. Only do 9365 // this if the provider is the same user as the caller's 9366 // process, or can run as root (so can be in any process). 9367 return cpr.newHolder(null); 9368 } 9369 9370 if (DEBUG_PROVIDER) { 9371 RuntimeException e = new RuntimeException("here"); 9372 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9373 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9374 } 9375 9376 // This is single process, and our app is now connecting to it. 9377 // See if we are already in the process of launching this 9378 // provider. 9379 final int N = mLaunchingProviders.size(); 9380 int i; 9381 for (i=0; i<N; i++) { 9382 if (mLaunchingProviders.get(i) == cpr) { 9383 break; 9384 } 9385 } 9386 9387 // If the provider is not already being launched, then get it 9388 // started. 9389 if (i >= N) { 9390 final long origId = Binder.clearCallingIdentity(); 9391 9392 try { 9393 // Content provider is now in use, its package can't be stopped. 9394 try { 9395 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9396 AppGlobals.getPackageManager().setPackageStoppedState( 9397 cpr.appInfo.packageName, false, userId); 9398 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9399 } catch (RemoteException e) { 9400 } catch (IllegalArgumentException e) { 9401 Slog.w(TAG, "Failed trying to unstop package " 9402 + cpr.appInfo.packageName + ": " + e); 9403 } 9404 9405 // Use existing process if already started 9406 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9407 ProcessRecord proc = getProcessRecordLocked( 9408 cpi.processName, cpr.appInfo.uid, false); 9409 if (proc != null && proc.thread != null) { 9410 if (DEBUG_PROVIDER) { 9411 Slog.d(TAG, "Installing in existing process " + proc); 9412 } 9413 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9414 proc.pubProviders.put(cpi.name, cpr); 9415 try { 9416 proc.thread.scheduleInstallProvider(cpi); 9417 } catch (RemoteException e) { 9418 } 9419 } else { 9420 checkTime(startTime, "getContentProviderImpl: before start process"); 9421 proc = startProcessLocked(cpi.processName, 9422 cpr.appInfo, false, 0, "content provider", 9423 new ComponentName(cpi.applicationInfo.packageName, 9424 cpi.name), false, false, false); 9425 checkTime(startTime, "getContentProviderImpl: after start process"); 9426 if (proc == null) { 9427 Slog.w(TAG, "Unable to launch app " 9428 + cpi.applicationInfo.packageName + "/" 9429 + cpi.applicationInfo.uid + " for provider " 9430 + name + ": process is bad"); 9431 return null; 9432 } 9433 } 9434 cpr.launchingApp = proc; 9435 mLaunchingProviders.add(cpr); 9436 } finally { 9437 Binder.restoreCallingIdentity(origId); 9438 } 9439 } 9440 9441 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9442 9443 // Make sure the provider is published (the same provider class 9444 // may be published under multiple names). 9445 if (firstClass) { 9446 mProviderMap.putProviderByClass(comp, cpr); 9447 } 9448 9449 mProviderMap.putProviderByName(name, cpr); 9450 conn = incProviderCountLocked(r, cpr, token, stable); 9451 if (conn != null) { 9452 conn.waiting = true; 9453 } 9454 } 9455 checkTime(startTime, "getContentProviderImpl: done!"); 9456 } 9457 9458 // Wait for the provider to be published... 9459 synchronized (cpr) { 9460 while (cpr.provider == null) { 9461 if (cpr.launchingApp == null) { 9462 Slog.w(TAG, "Unable to launch app " 9463 + cpi.applicationInfo.packageName + "/" 9464 + cpi.applicationInfo.uid + " for provider " 9465 + name + ": launching app became null"); 9466 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9467 UserHandle.getUserId(cpi.applicationInfo.uid), 9468 cpi.applicationInfo.packageName, 9469 cpi.applicationInfo.uid, name); 9470 return null; 9471 } 9472 try { 9473 if (DEBUG_MU) { 9474 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9475 + cpr.launchingApp); 9476 } 9477 if (conn != null) { 9478 conn.waiting = true; 9479 } 9480 cpr.wait(); 9481 } catch (InterruptedException ex) { 9482 } finally { 9483 if (conn != null) { 9484 conn.waiting = false; 9485 } 9486 } 9487 } 9488 } 9489 return cpr != null ? cpr.newHolder(conn) : null; 9490 } 9491 9492 @Override 9493 public final ContentProviderHolder getContentProvider( 9494 IApplicationThread caller, String name, int userId, boolean stable) { 9495 enforceNotIsolatedCaller("getContentProvider"); 9496 if (caller == null) { 9497 String msg = "null IApplicationThread when getting content provider " 9498 + name; 9499 Slog.w(TAG, msg); 9500 throw new SecurityException(msg); 9501 } 9502 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9503 // with cross-user grant. 9504 return getContentProviderImpl(caller, name, null, stable, userId); 9505 } 9506 9507 public ContentProviderHolder getContentProviderExternal( 9508 String name, int userId, IBinder token) { 9509 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9510 "Do not have permission in call getContentProviderExternal()"); 9511 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9512 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9513 return getContentProviderExternalUnchecked(name, token, userId); 9514 } 9515 9516 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9517 IBinder token, int userId) { 9518 return getContentProviderImpl(null, name, token, true, userId); 9519 } 9520 9521 /** 9522 * Drop a content provider from a ProcessRecord's bookkeeping 9523 */ 9524 public void removeContentProvider(IBinder connection, boolean stable) { 9525 enforceNotIsolatedCaller("removeContentProvider"); 9526 long ident = Binder.clearCallingIdentity(); 9527 try { 9528 synchronized (this) { 9529 ContentProviderConnection conn; 9530 try { 9531 conn = (ContentProviderConnection)connection; 9532 } catch (ClassCastException e) { 9533 String msg ="removeContentProvider: " + connection 9534 + " not a ContentProviderConnection"; 9535 Slog.w(TAG, msg); 9536 throw new IllegalArgumentException(msg); 9537 } 9538 if (conn == null) { 9539 throw new NullPointerException("connection is null"); 9540 } 9541 if (decProviderCountLocked(conn, null, null, stable)) { 9542 updateOomAdjLocked(); 9543 } 9544 } 9545 } finally { 9546 Binder.restoreCallingIdentity(ident); 9547 } 9548 } 9549 9550 public void removeContentProviderExternal(String name, IBinder token) { 9551 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9552 "Do not have permission in call removeContentProviderExternal()"); 9553 int userId = UserHandle.getCallingUserId(); 9554 long ident = Binder.clearCallingIdentity(); 9555 try { 9556 removeContentProviderExternalUnchecked(name, token, userId); 9557 } finally { 9558 Binder.restoreCallingIdentity(ident); 9559 } 9560 } 9561 9562 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9563 synchronized (this) { 9564 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9565 if(cpr == null) { 9566 //remove from mProvidersByClass 9567 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9568 return; 9569 } 9570 9571 //update content provider record entry info 9572 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9573 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9574 if (localCpr.hasExternalProcessHandles()) { 9575 if (localCpr.removeExternalProcessHandleLocked(token)) { 9576 updateOomAdjLocked(); 9577 } else { 9578 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9579 + " with no external reference for token: " 9580 + token + "."); 9581 } 9582 } else { 9583 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9584 + " with no external references."); 9585 } 9586 } 9587 } 9588 9589 public final void publishContentProviders(IApplicationThread caller, 9590 List<ContentProviderHolder> providers) { 9591 if (providers == null) { 9592 return; 9593 } 9594 9595 enforceNotIsolatedCaller("publishContentProviders"); 9596 synchronized (this) { 9597 final ProcessRecord r = getRecordForAppLocked(caller); 9598 if (DEBUG_MU) 9599 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9600 if (r == null) { 9601 throw new SecurityException( 9602 "Unable to find app for caller " + caller 9603 + " (pid=" + Binder.getCallingPid() 9604 + ") when publishing content providers"); 9605 } 9606 9607 final long origId = Binder.clearCallingIdentity(); 9608 9609 final int N = providers.size(); 9610 for (int i=0; i<N; i++) { 9611 ContentProviderHolder src = providers.get(i); 9612 if (src == null || src.info == null || src.provider == null) { 9613 continue; 9614 } 9615 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9616 if (DEBUG_MU) 9617 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9618 if (dst != null) { 9619 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9620 mProviderMap.putProviderByClass(comp, dst); 9621 String names[] = dst.info.authority.split(";"); 9622 for (int j = 0; j < names.length; j++) { 9623 mProviderMap.putProviderByName(names[j], dst); 9624 } 9625 9626 int NL = mLaunchingProviders.size(); 9627 int j; 9628 for (j=0; j<NL; j++) { 9629 if (mLaunchingProviders.get(j) == dst) { 9630 mLaunchingProviders.remove(j); 9631 j--; 9632 NL--; 9633 } 9634 } 9635 synchronized (dst) { 9636 dst.provider = src.provider; 9637 dst.proc = r; 9638 dst.notifyAll(); 9639 } 9640 updateOomAdjLocked(r); 9641 } 9642 } 9643 9644 Binder.restoreCallingIdentity(origId); 9645 } 9646 } 9647 9648 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9649 ContentProviderConnection conn; 9650 try { 9651 conn = (ContentProviderConnection)connection; 9652 } catch (ClassCastException e) { 9653 String msg ="refContentProvider: " + connection 9654 + " not a ContentProviderConnection"; 9655 Slog.w(TAG, msg); 9656 throw new IllegalArgumentException(msg); 9657 } 9658 if (conn == null) { 9659 throw new NullPointerException("connection is null"); 9660 } 9661 9662 synchronized (this) { 9663 if (stable > 0) { 9664 conn.numStableIncs += stable; 9665 } 9666 stable = conn.stableCount + stable; 9667 if (stable < 0) { 9668 throw new IllegalStateException("stableCount < 0: " + stable); 9669 } 9670 9671 if (unstable > 0) { 9672 conn.numUnstableIncs += unstable; 9673 } 9674 unstable = conn.unstableCount + unstable; 9675 if (unstable < 0) { 9676 throw new IllegalStateException("unstableCount < 0: " + unstable); 9677 } 9678 9679 if ((stable+unstable) <= 0) { 9680 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9681 + stable + " unstable=" + unstable); 9682 } 9683 conn.stableCount = stable; 9684 conn.unstableCount = unstable; 9685 return !conn.dead; 9686 } 9687 } 9688 9689 public void unstableProviderDied(IBinder connection) { 9690 ContentProviderConnection conn; 9691 try { 9692 conn = (ContentProviderConnection)connection; 9693 } catch (ClassCastException e) { 9694 String msg ="refContentProvider: " + connection 9695 + " not a ContentProviderConnection"; 9696 Slog.w(TAG, msg); 9697 throw new IllegalArgumentException(msg); 9698 } 9699 if (conn == null) { 9700 throw new NullPointerException("connection is null"); 9701 } 9702 9703 // Safely retrieve the content provider associated with the connection. 9704 IContentProvider provider; 9705 synchronized (this) { 9706 provider = conn.provider.provider; 9707 } 9708 9709 if (provider == null) { 9710 // Um, yeah, we're way ahead of you. 9711 return; 9712 } 9713 9714 // Make sure the caller is being honest with us. 9715 if (provider.asBinder().pingBinder()) { 9716 // Er, no, still looks good to us. 9717 synchronized (this) { 9718 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9719 + " says " + conn + " died, but we don't agree"); 9720 return; 9721 } 9722 } 9723 9724 // Well look at that! It's dead! 9725 synchronized (this) { 9726 if (conn.provider.provider != provider) { 9727 // But something changed... good enough. 9728 return; 9729 } 9730 9731 ProcessRecord proc = conn.provider.proc; 9732 if (proc == null || proc.thread == null) { 9733 // Seems like the process is already cleaned up. 9734 return; 9735 } 9736 9737 // As far as we're concerned, this is just like receiving a 9738 // death notification... just a bit prematurely. 9739 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9740 + ") early provider death"); 9741 final long ident = Binder.clearCallingIdentity(); 9742 try { 9743 appDiedLocked(proc); 9744 } finally { 9745 Binder.restoreCallingIdentity(ident); 9746 } 9747 } 9748 } 9749 9750 @Override 9751 public void appNotRespondingViaProvider(IBinder connection) { 9752 enforceCallingPermission( 9753 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9754 9755 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9756 if (conn == null) { 9757 Slog.w(TAG, "ContentProviderConnection is null"); 9758 return; 9759 } 9760 9761 final ProcessRecord host = conn.provider.proc; 9762 if (host == null) { 9763 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9764 return; 9765 } 9766 9767 final long token = Binder.clearCallingIdentity(); 9768 try { 9769 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9770 } finally { 9771 Binder.restoreCallingIdentity(token); 9772 } 9773 } 9774 9775 public final void installSystemProviders() { 9776 List<ProviderInfo> providers; 9777 synchronized (this) { 9778 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9779 providers = generateApplicationProvidersLocked(app); 9780 if (providers != null) { 9781 for (int i=providers.size()-1; i>=0; i--) { 9782 ProviderInfo pi = (ProviderInfo)providers.get(i); 9783 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9784 Slog.w(TAG, "Not installing system proc provider " + pi.name 9785 + ": not system .apk"); 9786 providers.remove(i); 9787 } 9788 } 9789 } 9790 } 9791 if (providers != null) { 9792 mSystemThread.installSystemProviders(providers); 9793 } 9794 9795 mCoreSettingsObserver = new CoreSettingsObserver(this); 9796 9797 //mUsageStatsService.monitorPackages(); 9798 } 9799 9800 /** 9801 * Allows apps to retrieve the MIME type of a URI. 9802 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9803 * users, then it does not need permission to access the ContentProvider. 9804 * Either, it needs cross-user uri grants. 9805 * 9806 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9807 * 9808 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9809 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9810 */ 9811 public String getProviderMimeType(Uri uri, int userId) { 9812 enforceNotIsolatedCaller("getProviderMimeType"); 9813 final String name = uri.getAuthority(); 9814 int callingUid = Binder.getCallingUid(); 9815 int callingPid = Binder.getCallingPid(); 9816 long ident = 0; 9817 boolean clearedIdentity = false; 9818 userId = unsafeConvertIncomingUser(userId); 9819 if (canClearIdentity(callingPid, callingUid, userId)) { 9820 clearedIdentity = true; 9821 ident = Binder.clearCallingIdentity(); 9822 } 9823 ContentProviderHolder holder = null; 9824 try { 9825 holder = getContentProviderExternalUnchecked(name, null, userId); 9826 if (holder != null) { 9827 return holder.provider.getType(uri); 9828 } 9829 } catch (RemoteException e) { 9830 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9831 return null; 9832 } finally { 9833 // We need to clear the identity to call removeContentProviderExternalUnchecked 9834 if (!clearedIdentity) { 9835 ident = Binder.clearCallingIdentity(); 9836 } 9837 try { 9838 if (holder != null) { 9839 removeContentProviderExternalUnchecked(name, null, userId); 9840 } 9841 } finally { 9842 Binder.restoreCallingIdentity(ident); 9843 } 9844 } 9845 9846 return null; 9847 } 9848 9849 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9850 if (UserHandle.getUserId(callingUid) == userId) { 9851 return true; 9852 } 9853 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9854 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9855 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9856 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9857 return true; 9858 } 9859 return false; 9860 } 9861 9862 // ========================================================= 9863 // GLOBAL MANAGEMENT 9864 // ========================================================= 9865 9866 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9867 boolean isolated, int isolatedUid) { 9868 String proc = customProcess != null ? customProcess : info.processName; 9869 BatteryStatsImpl.Uid.Proc ps = null; 9870 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9871 int uid = info.uid; 9872 if (isolated) { 9873 if (isolatedUid == 0) { 9874 int userId = UserHandle.getUserId(uid); 9875 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9876 while (true) { 9877 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9878 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9879 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9880 } 9881 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9882 mNextIsolatedProcessUid++; 9883 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9884 // No process for this uid, use it. 9885 break; 9886 } 9887 stepsLeft--; 9888 if (stepsLeft <= 0) { 9889 return null; 9890 } 9891 } 9892 } else { 9893 // Special case for startIsolatedProcess (internal only), where 9894 // the uid of the isolated process is specified by the caller. 9895 uid = isolatedUid; 9896 } 9897 } 9898 return new ProcessRecord(stats, info, proc, uid); 9899 } 9900 9901 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9902 String abiOverride) { 9903 ProcessRecord app; 9904 if (!isolated) { 9905 app = getProcessRecordLocked(info.processName, info.uid, true); 9906 } else { 9907 app = null; 9908 } 9909 9910 if (app == null) { 9911 app = newProcessRecordLocked(info, null, isolated, 0); 9912 mProcessNames.put(info.processName, app.uid, app); 9913 if (isolated) { 9914 mIsolatedProcesses.put(app.uid, app); 9915 } 9916 updateLruProcessLocked(app, false, null); 9917 updateOomAdjLocked(); 9918 } 9919 9920 // This package really, really can not be stopped. 9921 try { 9922 AppGlobals.getPackageManager().setPackageStoppedState( 9923 info.packageName, false, UserHandle.getUserId(app.uid)); 9924 } catch (RemoteException e) { 9925 } catch (IllegalArgumentException e) { 9926 Slog.w(TAG, "Failed trying to unstop package " 9927 + info.packageName + ": " + e); 9928 } 9929 9930 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9931 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9932 app.persistent = true; 9933 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9934 } 9935 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9936 mPersistentStartingProcesses.add(app); 9937 startProcessLocked(app, "added application", app.processName, abiOverride, 9938 null /* entryPoint */, null /* entryPointArgs */); 9939 } 9940 9941 return app; 9942 } 9943 9944 public void unhandledBack() { 9945 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9946 "unhandledBack()"); 9947 9948 synchronized(this) { 9949 final long origId = Binder.clearCallingIdentity(); 9950 try { 9951 getFocusedStack().unhandledBackLocked(); 9952 } finally { 9953 Binder.restoreCallingIdentity(origId); 9954 } 9955 } 9956 } 9957 9958 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9959 enforceNotIsolatedCaller("openContentUri"); 9960 final int userId = UserHandle.getCallingUserId(); 9961 String name = uri.getAuthority(); 9962 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9963 ParcelFileDescriptor pfd = null; 9964 if (cph != null) { 9965 // We record the binder invoker's uid in thread-local storage before 9966 // going to the content provider to open the file. Later, in the code 9967 // that handles all permissions checks, we look for this uid and use 9968 // that rather than the Activity Manager's own uid. The effect is that 9969 // we do the check against the caller's permissions even though it looks 9970 // to the content provider like the Activity Manager itself is making 9971 // the request. 9972 Binder token = new Binder(); 9973 sCallerIdentity.set(new Identity( 9974 token, Binder.getCallingPid(), Binder.getCallingUid())); 9975 try { 9976 pfd = cph.provider.openFile(null, uri, "r", null, token); 9977 } catch (FileNotFoundException e) { 9978 // do nothing; pfd will be returned null 9979 } finally { 9980 // Ensure that whatever happens, we clean up the identity state 9981 sCallerIdentity.remove(); 9982 } 9983 9984 // We've got the fd now, so we're done with the provider. 9985 removeContentProviderExternalUnchecked(name, null, userId); 9986 } else { 9987 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9988 } 9989 return pfd; 9990 } 9991 9992 // Actually is sleeping or shutting down or whatever else in the future 9993 // is an inactive state. 9994 public boolean isSleepingOrShuttingDown() { 9995 return isSleeping() || mShuttingDown; 9996 } 9997 9998 public boolean isSleeping() { 9999 return mSleeping; 10000 } 10001 10002 void onWakefulnessChanged(int wakefulness) { 10003 synchronized(this) { 10004 mWakefulness = wakefulness; 10005 updateSleepIfNeededLocked(); 10006 } 10007 } 10008 10009 void finishRunningVoiceLocked() { 10010 if (mRunningVoice) { 10011 mRunningVoice = false; 10012 updateSleepIfNeededLocked(); 10013 } 10014 } 10015 10016 void updateSleepIfNeededLocked() { 10017 if (mSleeping && !shouldSleepLocked()) { 10018 mSleeping = false; 10019 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10020 } else if (!mSleeping && shouldSleepLocked()) { 10021 mSleeping = true; 10022 mStackSupervisor.goingToSleepLocked(); 10023 10024 // Initialize the wake times of all processes. 10025 checkExcessivePowerUsageLocked(false); 10026 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10027 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10028 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10029 } 10030 } 10031 10032 private boolean shouldSleepLocked() { 10033 // Resume applications while running a voice interactor. 10034 if (mRunningVoice) { 10035 return false; 10036 } 10037 10038 switch (mWakefulness) { 10039 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10040 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10041 // If we're interactive but applications are already paused then defer 10042 // resuming them until the lock screen is hidden. 10043 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10044 case PowerManagerInternal.WAKEFULNESS_DOZING: 10045 // If we're dozing then pause applications whenever the lock screen is shown. 10046 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10047 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10048 default: 10049 // If we're asleep then pause applications unconditionally. 10050 return true; 10051 } 10052 } 10053 10054 /** Pokes the task persister. */ 10055 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10056 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10057 // Never persist the home stack. 10058 return; 10059 } 10060 mTaskPersister.wakeup(task, flush); 10061 } 10062 10063 /** Notifies all listeners when the task stack has changed. */ 10064 void notifyTaskStackChangedLocked() { 10065 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10066 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10067 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10068 } 10069 10070 @Override 10071 public boolean shutdown(int timeout) { 10072 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10073 != PackageManager.PERMISSION_GRANTED) { 10074 throw new SecurityException("Requires permission " 10075 + android.Manifest.permission.SHUTDOWN); 10076 } 10077 10078 boolean timedout = false; 10079 10080 synchronized(this) { 10081 mShuttingDown = true; 10082 updateEventDispatchingLocked(); 10083 timedout = mStackSupervisor.shutdownLocked(timeout); 10084 } 10085 10086 mAppOpsService.shutdown(); 10087 if (mUsageStatsService != null) { 10088 mUsageStatsService.prepareShutdown(); 10089 } 10090 mBatteryStatsService.shutdown(); 10091 synchronized (this) { 10092 mProcessStats.shutdownLocked(); 10093 notifyTaskPersisterLocked(null, true); 10094 } 10095 10096 return timedout; 10097 } 10098 10099 public final void activitySlept(IBinder token) { 10100 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10101 10102 final long origId = Binder.clearCallingIdentity(); 10103 10104 synchronized (this) { 10105 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10106 if (r != null) { 10107 mStackSupervisor.activitySleptLocked(r); 10108 } 10109 } 10110 10111 Binder.restoreCallingIdentity(origId); 10112 } 10113 10114 private String lockScreenShownToString() { 10115 switch (mLockScreenShown) { 10116 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10117 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10118 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10119 default: return "Unknown=" + mLockScreenShown; 10120 } 10121 } 10122 10123 void logLockScreen(String msg) { 10124 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10125 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10126 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10127 + " mSleeping=" + mSleeping); 10128 } 10129 10130 void startRunningVoiceLocked() { 10131 if (!mRunningVoice) { 10132 mRunningVoice = true; 10133 updateSleepIfNeededLocked(); 10134 } 10135 } 10136 10137 private void updateEventDispatchingLocked() { 10138 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10139 } 10140 10141 public void setLockScreenShown(boolean shown) { 10142 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10143 != PackageManager.PERMISSION_GRANTED) { 10144 throw new SecurityException("Requires permission " 10145 + android.Manifest.permission.DEVICE_POWER); 10146 } 10147 10148 synchronized(this) { 10149 long ident = Binder.clearCallingIdentity(); 10150 try { 10151 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10152 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10153 updateSleepIfNeededLocked(); 10154 } finally { 10155 Binder.restoreCallingIdentity(ident); 10156 } 10157 } 10158 } 10159 10160 @Override 10161 public void stopAppSwitches() { 10162 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10163 != PackageManager.PERMISSION_GRANTED) { 10164 throw new SecurityException("Requires permission " 10165 + android.Manifest.permission.STOP_APP_SWITCHES); 10166 } 10167 10168 synchronized(this) { 10169 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10170 + APP_SWITCH_DELAY_TIME; 10171 mDidAppSwitch = false; 10172 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10173 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10174 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10175 } 10176 } 10177 10178 public void resumeAppSwitches() { 10179 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10180 != PackageManager.PERMISSION_GRANTED) { 10181 throw new SecurityException("Requires permission " 10182 + android.Manifest.permission.STOP_APP_SWITCHES); 10183 } 10184 10185 synchronized(this) { 10186 // Note that we don't execute any pending app switches... we will 10187 // let those wait until either the timeout, or the next start 10188 // activity request. 10189 mAppSwitchesAllowedTime = 0; 10190 } 10191 } 10192 10193 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10194 int callingPid, int callingUid, String name) { 10195 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10196 return true; 10197 } 10198 10199 int perm = checkComponentPermission( 10200 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10201 sourceUid, -1, true); 10202 if (perm == PackageManager.PERMISSION_GRANTED) { 10203 return true; 10204 } 10205 10206 // If the actual IPC caller is different from the logical source, then 10207 // also see if they are allowed to control app switches. 10208 if (callingUid != -1 && callingUid != sourceUid) { 10209 perm = checkComponentPermission( 10210 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10211 callingUid, -1, true); 10212 if (perm == PackageManager.PERMISSION_GRANTED) { 10213 return true; 10214 } 10215 } 10216 10217 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10218 return false; 10219 } 10220 10221 public void setDebugApp(String packageName, boolean waitForDebugger, 10222 boolean persistent) { 10223 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10224 "setDebugApp()"); 10225 10226 long ident = Binder.clearCallingIdentity(); 10227 try { 10228 // Note that this is not really thread safe if there are multiple 10229 // callers into it at the same time, but that's not a situation we 10230 // care about. 10231 if (persistent) { 10232 final ContentResolver resolver = mContext.getContentResolver(); 10233 Settings.Global.putString( 10234 resolver, Settings.Global.DEBUG_APP, 10235 packageName); 10236 Settings.Global.putInt( 10237 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10238 waitForDebugger ? 1 : 0); 10239 } 10240 10241 synchronized (this) { 10242 if (!persistent) { 10243 mOrigDebugApp = mDebugApp; 10244 mOrigWaitForDebugger = mWaitForDebugger; 10245 } 10246 mDebugApp = packageName; 10247 mWaitForDebugger = waitForDebugger; 10248 mDebugTransient = !persistent; 10249 if (packageName != null) { 10250 forceStopPackageLocked(packageName, -1, false, false, true, true, 10251 false, UserHandle.USER_ALL, "set debug app"); 10252 } 10253 } 10254 } finally { 10255 Binder.restoreCallingIdentity(ident); 10256 } 10257 } 10258 10259 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10260 synchronized (this) { 10261 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10262 if (!isDebuggable) { 10263 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10264 throw new SecurityException("Process not debuggable: " + app.packageName); 10265 } 10266 } 10267 10268 mOpenGlTraceApp = processName; 10269 } 10270 } 10271 10272 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10273 synchronized (this) { 10274 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10275 if (!isDebuggable) { 10276 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10277 throw new SecurityException("Process not debuggable: " + app.packageName); 10278 } 10279 } 10280 mProfileApp = processName; 10281 mProfileFile = profilerInfo.profileFile; 10282 if (mProfileFd != null) { 10283 try { 10284 mProfileFd.close(); 10285 } catch (IOException e) { 10286 } 10287 mProfileFd = null; 10288 } 10289 mProfileFd = profilerInfo.profileFd; 10290 mSamplingInterval = profilerInfo.samplingInterval; 10291 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10292 mProfileType = 0; 10293 } 10294 } 10295 10296 @Override 10297 public void setAlwaysFinish(boolean enabled) { 10298 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10299 "setAlwaysFinish()"); 10300 10301 Settings.Global.putInt( 10302 mContext.getContentResolver(), 10303 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10304 10305 synchronized (this) { 10306 mAlwaysFinishActivities = enabled; 10307 } 10308 } 10309 10310 @Override 10311 public void setActivityController(IActivityController controller) { 10312 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10313 "setActivityController()"); 10314 synchronized (this) { 10315 mController = controller; 10316 Watchdog.getInstance().setActivityController(controller); 10317 } 10318 } 10319 10320 @Override 10321 public void setUserIsMonkey(boolean userIsMonkey) { 10322 synchronized (this) { 10323 synchronized (mPidsSelfLocked) { 10324 final int callingPid = Binder.getCallingPid(); 10325 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10326 if (precessRecord == null) { 10327 throw new SecurityException("Unknown process: " + callingPid); 10328 } 10329 if (precessRecord.instrumentationUiAutomationConnection == null) { 10330 throw new SecurityException("Only an instrumentation process " 10331 + "with a UiAutomation can call setUserIsMonkey"); 10332 } 10333 } 10334 mUserIsMonkey = userIsMonkey; 10335 } 10336 } 10337 10338 @Override 10339 public boolean isUserAMonkey() { 10340 synchronized (this) { 10341 // If there is a controller also implies the user is a monkey. 10342 return (mUserIsMonkey || mController != null); 10343 } 10344 } 10345 10346 public void requestBugReport() { 10347 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10348 SystemProperties.set("ctl.start", "bugreport"); 10349 } 10350 10351 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10352 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10353 } 10354 10355 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10356 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10357 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10358 } 10359 return KEY_DISPATCHING_TIMEOUT; 10360 } 10361 10362 @Override 10363 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10364 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10365 != PackageManager.PERMISSION_GRANTED) { 10366 throw new SecurityException("Requires permission " 10367 + android.Manifest.permission.FILTER_EVENTS); 10368 } 10369 ProcessRecord proc; 10370 long timeout; 10371 synchronized (this) { 10372 synchronized (mPidsSelfLocked) { 10373 proc = mPidsSelfLocked.get(pid); 10374 } 10375 timeout = getInputDispatchingTimeoutLocked(proc); 10376 } 10377 10378 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10379 return -1; 10380 } 10381 10382 return timeout; 10383 } 10384 10385 /** 10386 * Handle input dispatching timeouts. 10387 * Returns whether input dispatching should be aborted or not. 10388 */ 10389 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10390 final ActivityRecord activity, final ActivityRecord parent, 10391 final boolean aboveSystem, String reason) { 10392 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10393 != PackageManager.PERMISSION_GRANTED) { 10394 throw new SecurityException("Requires permission " 10395 + android.Manifest.permission.FILTER_EVENTS); 10396 } 10397 10398 final String annotation; 10399 if (reason == null) { 10400 annotation = "Input dispatching timed out"; 10401 } else { 10402 annotation = "Input dispatching timed out (" + reason + ")"; 10403 } 10404 10405 if (proc != null) { 10406 synchronized (this) { 10407 if (proc.debugging) { 10408 return false; 10409 } 10410 10411 if (mDidDexOpt) { 10412 // Give more time since we were dexopting. 10413 mDidDexOpt = false; 10414 return false; 10415 } 10416 10417 if (proc.instrumentationClass != null) { 10418 Bundle info = new Bundle(); 10419 info.putString("shortMsg", "keyDispatchingTimedOut"); 10420 info.putString("longMsg", annotation); 10421 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10422 return true; 10423 } 10424 } 10425 mHandler.post(new Runnable() { 10426 @Override 10427 public void run() { 10428 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10429 } 10430 }); 10431 } 10432 10433 return true; 10434 } 10435 10436 public Bundle getAssistContextExtras(int requestType) { 10437 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10438 UserHandle.getCallingUserId()); 10439 if (pae == null) { 10440 return null; 10441 } 10442 synchronized (pae) { 10443 while (!pae.haveResult) { 10444 try { 10445 pae.wait(); 10446 } catch (InterruptedException e) { 10447 } 10448 } 10449 if (pae.result != null) { 10450 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10451 } 10452 } 10453 synchronized (this) { 10454 mPendingAssistExtras.remove(pae); 10455 mHandler.removeCallbacks(pae); 10456 } 10457 return pae.extras; 10458 } 10459 10460 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10461 int userHandle) { 10462 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10463 "getAssistContextExtras()"); 10464 PendingAssistExtras pae; 10465 Bundle extras = new Bundle(); 10466 synchronized (this) { 10467 ActivityRecord activity = getFocusedStack().mResumedActivity; 10468 if (activity == null) { 10469 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10470 return null; 10471 } 10472 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10473 if (activity.app == null || activity.app.thread == null) { 10474 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10475 return null; 10476 } 10477 if (activity.app.pid == Binder.getCallingPid()) { 10478 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10479 return null; 10480 } 10481 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10482 try { 10483 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10484 requestType); 10485 mPendingAssistExtras.add(pae); 10486 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10487 } catch (RemoteException e) { 10488 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10489 return null; 10490 } 10491 return pae; 10492 } 10493 } 10494 10495 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10496 PendingAssistExtras pae = (PendingAssistExtras)token; 10497 synchronized (pae) { 10498 pae.result = extras; 10499 pae.haveResult = true; 10500 pae.notifyAll(); 10501 if (pae.intent == null) { 10502 // Caller is just waiting for the result. 10503 return; 10504 } 10505 } 10506 10507 // We are now ready to launch the assist activity. 10508 synchronized (this) { 10509 boolean exists = mPendingAssistExtras.remove(pae); 10510 mHandler.removeCallbacks(pae); 10511 if (!exists) { 10512 // Timed out. 10513 return; 10514 } 10515 } 10516 pae.intent.replaceExtras(extras); 10517 if (pae.hint != null) { 10518 pae.intent.putExtra(pae.hint, true); 10519 } 10520 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10521 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10522 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10523 closeSystemDialogs("assist"); 10524 try { 10525 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10526 } catch (ActivityNotFoundException e) { 10527 Slog.w(TAG, "No activity to handle assist action.", e); 10528 } 10529 } 10530 10531 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10532 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10533 } 10534 10535 public void registerProcessObserver(IProcessObserver observer) { 10536 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10537 "registerProcessObserver()"); 10538 synchronized (this) { 10539 mProcessObservers.register(observer); 10540 } 10541 } 10542 10543 @Override 10544 public void unregisterProcessObserver(IProcessObserver observer) { 10545 synchronized (this) { 10546 mProcessObservers.unregister(observer); 10547 } 10548 } 10549 10550 @Override 10551 public boolean convertFromTranslucent(IBinder token) { 10552 final long origId = Binder.clearCallingIdentity(); 10553 try { 10554 synchronized (this) { 10555 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10556 if (r == null) { 10557 return false; 10558 } 10559 final boolean translucentChanged = r.changeWindowTranslucency(true); 10560 if (translucentChanged) { 10561 r.task.stack.releaseBackgroundResources(); 10562 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10563 } 10564 mWindowManager.setAppFullscreen(token, true); 10565 return translucentChanged; 10566 } 10567 } finally { 10568 Binder.restoreCallingIdentity(origId); 10569 } 10570 } 10571 10572 @Override 10573 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10574 final long origId = Binder.clearCallingIdentity(); 10575 try { 10576 synchronized (this) { 10577 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10578 if (r == null) { 10579 return false; 10580 } 10581 int index = r.task.mActivities.lastIndexOf(r); 10582 if (index > 0) { 10583 ActivityRecord under = r.task.mActivities.get(index - 1); 10584 under.returningOptions = options; 10585 } 10586 final boolean translucentChanged = r.changeWindowTranslucency(false); 10587 if (translucentChanged) { 10588 r.task.stack.convertToTranslucent(r); 10589 } 10590 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10591 mWindowManager.setAppFullscreen(token, false); 10592 return translucentChanged; 10593 } 10594 } finally { 10595 Binder.restoreCallingIdentity(origId); 10596 } 10597 } 10598 10599 @Override 10600 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10601 final long origId = Binder.clearCallingIdentity(); 10602 try { 10603 synchronized (this) { 10604 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10605 if (r != null) { 10606 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10607 } 10608 } 10609 return false; 10610 } finally { 10611 Binder.restoreCallingIdentity(origId); 10612 } 10613 } 10614 10615 @Override 10616 public boolean isBackgroundVisibleBehind(IBinder token) { 10617 final long origId = Binder.clearCallingIdentity(); 10618 try { 10619 synchronized (this) { 10620 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10621 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10622 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10623 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10624 return visible; 10625 } 10626 } finally { 10627 Binder.restoreCallingIdentity(origId); 10628 } 10629 } 10630 10631 @Override 10632 public ActivityOptions getActivityOptions(IBinder token) { 10633 final long origId = Binder.clearCallingIdentity(); 10634 try { 10635 synchronized (this) { 10636 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10637 if (r != null) { 10638 final ActivityOptions activityOptions = r.pendingOptions; 10639 r.pendingOptions = null; 10640 return activityOptions; 10641 } 10642 return null; 10643 } 10644 } finally { 10645 Binder.restoreCallingIdentity(origId); 10646 } 10647 } 10648 10649 @Override 10650 public void setImmersive(IBinder token, boolean immersive) { 10651 synchronized(this) { 10652 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10653 if (r == null) { 10654 throw new IllegalArgumentException(); 10655 } 10656 r.immersive = immersive; 10657 10658 // update associated state if we're frontmost 10659 if (r == mFocusedActivity) { 10660 if (DEBUG_IMMERSIVE) { 10661 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10662 } 10663 applyUpdateLockStateLocked(r); 10664 } 10665 } 10666 } 10667 10668 @Override 10669 public boolean isImmersive(IBinder token) { 10670 synchronized (this) { 10671 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10672 if (r == null) { 10673 throw new IllegalArgumentException(); 10674 } 10675 return r.immersive; 10676 } 10677 } 10678 10679 public boolean isTopActivityImmersive() { 10680 enforceNotIsolatedCaller("startActivity"); 10681 synchronized (this) { 10682 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10683 return (r != null) ? r.immersive : false; 10684 } 10685 } 10686 10687 @Override 10688 public boolean isTopOfTask(IBinder token) { 10689 synchronized (this) { 10690 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10691 if (r == null) { 10692 throw new IllegalArgumentException(); 10693 } 10694 return r.task.getTopActivity() == r; 10695 } 10696 } 10697 10698 public final void enterSafeMode() { 10699 synchronized(this) { 10700 // It only makes sense to do this before the system is ready 10701 // and started launching other packages. 10702 if (!mSystemReady) { 10703 try { 10704 AppGlobals.getPackageManager().enterSafeMode(); 10705 } catch (RemoteException e) { 10706 } 10707 } 10708 10709 mSafeMode = true; 10710 } 10711 } 10712 10713 public final void showSafeModeOverlay() { 10714 View v = LayoutInflater.from(mContext).inflate( 10715 com.android.internal.R.layout.safe_mode, null); 10716 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10717 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10718 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10719 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10720 lp.gravity = Gravity.BOTTOM | Gravity.START; 10721 lp.format = v.getBackground().getOpacity(); 10722 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10723 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10724 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10725 ((WindowManager)mContext.getSystemService( 10726 Context.WINDOW_SERVICE)).addView(v, lp); 10727 } 10728 10729 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10730 if (!(sender instanceof PendingIntentRecord)) { 10731 return; 10732 } 10733 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10734 synchronized (stats) { 10735 if (mBatteryStatsService.isOnBattery()) { 10736 mBatteryStatsService.enforceCallingPermission(); 10737 PendingIntentRecord rec = (PendingIntentRecord)sender; 10738 int MY_UID = Binder.getCallingUid(); 10739 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10740 BatteryStatsImpl.Uid.Pkg pkg = 10741 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10742 sourcePkg != null ? sourcePkg : rec.key.packageName); 10743 pkg.incWakeupsLocked(); 10744 } 10745 } 10746 } 10747 10748 public boolean killPids(int[] pids, String pReason, boolean secure) { 10749 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10750 throw new SecurityException("killPids only available to the system"); 10751 } 10752 String reason = (pReason == null) ? "Unknown" : pReason; 10753 // XXX Note: don't acquire main activity lock here, because the window 10754 // manager calls in with its locks held. 10755 10756 boolean killed = false; 10757 synchronized (mPidsSelfLocked) { 10758 int[] types = new int[pids.length]; 10759 int worstType = 0; 10760 for (int i=0; i<pids.length; i++) { 10761 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10762 if (proc != null) { 10763 int type = proc.setAdj; 10764 types[i] = type; 10765 if (type > worstType) { 10766 worstType = type; 10767 } 10768 } 10769 } 10770 10771 // If the worst oom_adj is somewhere in the cached proc LRU range, 10772 // then constrain it so we will kill all cached procs. 10773 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10774 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10775 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10776 } 10777 10778 // If this is not a secure call, don't let it kill processes that 10779 // are important. 10780 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10781 worstType = ProcessList.SERVICE_ADJ; 10782 } 10783 10784 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10785 for (int i=0; i<pids.length; i++) { 10786 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10787 if (proc == null) { 10788 continue; 10789 } 10790 int adj = proc.setAdj; 10791 if (adj >= worstType && !proc.killedByAm) { 10792 proc.kill(reason, true); 10793 killed = true; 10794 } 10795 } 10796 } 10797 return killed; 10798 } 10799 10800 @Override 10801 public void killUid(int uid, String reason) { 10802 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10803 throw new SecurityException("killUid only available to the system"); 10804 } 10805 synchronized (this) { 10806 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10807 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10808 reason != null ? reason : "kill uid"); 10809 } 10810 } 10811 10812 @Override 10813 public boolean killProcessesBelowForeground(String reason) { 10814 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10815 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10816 } 10817 10818 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10819 } 10820 10821 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10822 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10823 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10824 } 10825 10826 boolean killed = false; 10827 synchronized (mPidsSelfLocked) { 10828 final int size = mPidsSelfLocked.size(); 10829 for (int i = 0; i < size; i++) { 10830 final int pid = mPidsSelfLocked.keyAt(i); 10831 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10832 if (proc == null) continue; 10833 10834 final int adj = proc.setAdj; 10835 if (adj > belowAdj && !proc.killedByAm) { 10836 proc.kill(reason, true); 10837 killed = true; 10838 } 10839 } 10840 } 10841 return killed; 10842 } 10843 10844 @Override 10845 public void hang(final IBinder who, boolean allowRestart) { 10846 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10847 != PackageManager.PERMISSION_GRANTED) { 10848 throw new SecurityException("Requires permission " 10849 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10850 } 10851 10852 final IBinder.DeathRecipient death = new DeathRecipient() { 10853 @Override 10854 public void binderDied() { 10855 synchronized (this) { 10856 notifyAll(); 10857 } 10858 } 10859 }; 10860 10861 try { 10862 who.linkToDeath(death, 0); 10863 } catch (RemoteException e) { 10864 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10865 return; 10866 } 10867 10868 synchronized (this) { 10869 Watchdog.getInstance().setAllowRestart(allowRestart); 10870 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10871 synchronized (death) { 10872 while (who.isBinderAlive()) { 10873 try { 10874 death.wait(); 10875 } catch (InterruptedException e) { 10876 } 10877 } 10878 } 10879 Watchdog.getInstance().setAllowRestart(true); 10880 } 10881 } 10882 10883 @Override 10884 public void restart() { 10885 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10886 != PackageManager.PERMISSION_GRANTED) { 10887 throw new SecurityException("Requires permission " 10888 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10889 } 10890 10891 Log.i(TAG, "Sending shutdown broadcast..."); 10892 10893 BroadcastReceiver br = new BroadcastReceiver() { 10894 @Override public void onReceive(Context context, Intent intent) { 10895 // Now the broadcast is done, finish up the low-level shutdown. 10896 Log.i(TAG, "Shutting down activity manager..."); 10897 shutdown(10000); 10898 Log.i(TAG, "Shutdown complete, restarting!"); 10899 Process.killProcess(Process.myPid()); 10900 System.exit(10); 10901 } 10902 }; 10903 10904 // First send the high-level shut down broadcast. 10905 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10906 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10907 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10908 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10909 mContext.sendOrderedBroadcastAsUser(intent, 10910 UserHandle.ALL, null, br, mHandler, 0, null, null); 10911 */ 10912 br.onReceive(mContext, intent); 10913 } 10914 10915 private long getLowRamTimeSinceIdle(long now) { 10916 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10917 } 10918 10919 @Override 10920 public void performIdleMaintenance() { 10921 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10922 != PackageManager.PERMISSION_GRANTED) { 10923 throw new SecurityException("Requires permission " 10924 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10925 } 10926 10927 synchronized (this) { 10928 final long now = SystemClock.uptimeMillis(); 10929 final long timeSinceLastIdle = now - mLastIdleTime; 10930 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10931 mLastIdleTime = now; 10932 mLowRamTimeSinceLastIdle = 0; 10933 if (mLowRamStartTime != 0) { 10934 mLowRamStartTime = now; 10935 } 10936 10937 StringBuilder sb = new StringBuilder(128); 10938 sb.append("Idle maintenance over "); 10939 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10940 sb.append(" low RAM for "); 10941 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10942 Slog.i(TAG, sb.toString()); 10943 10944 // If at least 1/3 of our time since the last idle period has been spent 10945 // with RAM low, then we want to kill processes. 10946 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10947 10948 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10949 ProcessRecord proc = mLruProcesses.get(i); 10950 if (proc.notCachedSinceIdle) { 10951 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10952 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10953 if (doKilling && proc.initialIdlePss != 0 10954 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10955 sb = new StringBuilder(128); 10956 sb.append("Kill"); 10957 sb.append(proc.processName); 10958 sb.append(" in idle maint: pss="); 10959 sb.append(proc.lastPss); 10960 sb.append(", initialPss="); 10961 sb.append(proc.initialIdlePss); 10962 sb.append(", period="); 10963 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10964 sb.append(", lowRamPeriod="); 10965 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10966 Slog.wtfQuiet(TAG, sb.toString()); 10967 proc.kill("idle maint (pss " + proc.lastPss 10968 + " from " + proc.initialIdlePss + ")", true); 10969 } 10970 } 10971 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10972 proc.notCachedSinceIdle = true; 10973 proc.initialIdlePss = 0; 10974 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10975 mTestPssMode, isSleeping(), now); 10976 } 10977 } 10978 10979 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10980 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10981 } 10982 } 10983 10984 private void retrieveSettings() { 10985 final ContentResolver resolver = mContext.getContentResolver(); 10986 String debugApp = Settings.Global.getString( 10987 resolver, Settings.Global.DEBUG_APP); 10988 boolean waitForDebugger = Settings.Global.getInt( 10989 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10990 boolean alwaysFinishActivities = Settings.Global.getInt( 10991 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10992 boolean forceRtl = Settings.Global.getInt( 10993 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10994 // Transfer any global setting for forcing RTL layout, into a System Property 10995 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10996 10997 Configuration configuration = new Configuration(); 10998 Settings.System.getConfiguration(resolver, configuration); 10999 if (forceRtl) { 11000 // This will take care of setting the correct layout direction flags 11001 configuration.setLayoutDirection(configuration.locale); 11002 } 11003 11004 synchronized (this) { 11005 mDebugApp = mOrigDebugApp = debugApp; 11006 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11007 mAlwaysFinishActivities = alwaysFinishActivities; 11008 // This happens before any activities are started, so we can 11009 // change mConfiguration in-place. 11010 updateConfigurationLocked(configuration, null, false, true); 11011 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11012 } 11013 } 11014 11015 /** Loads resources after the current configuration has been set. */ 11016 private void loadResourcesOnSystemReady() { 11017 final Resources res = mContext.getResources(); 11018 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11019 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11020 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11021 } 11022 11023 public boolean testIsSystemReady() { 11024 // no need to synchronize(this) just to read & return the value 11025 return mSystemReady; 11026 } 11027 11028 private static File getCalledPreBootReceiversFile() { 11029 File dataDir = Environment.getDataDirectory(); 11030 File systemDir = new File(dataDir, "system"); 11031 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11032 return fname; 11033 } 11034 11035 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11036 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11037 File file = getCalledPreBootReceiversFile(); 11038 FileInputStream fis = null; 11039 try { 11040 fis = new FileInputStream(file); 11041 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11042 int fvers = dis.readInt(); 11043 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11044 String vers = dis.readUTF(); 11045 String codename = dis.readUTF(); 11046 String build = dis.readUTF(); 11047 if (android.os.Build.VERSION.RELEASE.equals(vers) 11048 && android.os.Build.VERSION.CODENAME.equals(codename) 11049 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11050 int num = dis.readInt(); 11051 while (num > 0) { 11052 num--; 11053 String pkg = dis.readUTF(); 11054 String cls = dis.readUTF(); 11055 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11056 } 11057 } 11058 } 11059 } catch (FileNotFoundException e) { 11060 } catch (IOException e) { 11061 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11062 } finally { 11063 if (fis != null) { 11064 try { 11065 fis.close(); 11066 } catch (IOException e) { 11067 } 11068 } 11069 } 11070 return lastDoneReceivers; 11071 } 11072 11073 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11074 File file = getCalledPreBootReceiversFile(); 11075 FileOutputStream fos = null; 11076 DataOutputStream dos = null; 11077 try { 11078 fos = new FileOutputStream(file); 11079 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11080 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11081 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11082 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11083 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11084 dos.writeInt(list.size()); 11085 for (int i=0; i<list.size(); i++) { 11086 dos.writeUTF(list.get(i).getPackageName()); 11087 dos.writeUTF(list.get(i).getClassName()); 11088 } 11089 } catch (IOException e) { 11090 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11091 file.delete(); 11092 } finally { 11093 FileUtils.sync(fos); 11094 if (dos != null) { 11095 try { 11096 dos.close(); 11097 } catch (IOException e) { 11098 // TODO Auto-generated catch block 11099 e.printStackTrace(); 11100 } 11101 } 11102 } 11103 } 11104 11105 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11106 ArrayList<ComponentName> doneReceivers, int userId) { 11107 boolean waitingUpdate = false; 11108 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11109 List<ResolveInfo> ris = null; 11110 try { 11111 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11112 intent, null, 0, userId); 11113 } catch (RemoteException e) { 11114 } 11115 if (ris != null) { 11116 for (int i=ris.size()-1; i>=0; i--) { 11117 if ((ris.get(i).activityInfo.applicationInfo.flags 11118 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11119 ris.remove(i); 11120 } 11121 } 11122 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11123 11124 // For User 0, load the version number. When delivering to a new user, deliver 11125 // to all receivers. 11126 if (userId == UserHandle.USER_OWNER) { 11127 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11128 for (int i=0; i<ris.size(); i++) { 11129 ActivityInfo ai = ris.get(i).activityInfo; 11130 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11131 if (lastDoneReceivers.contains(comp)) { 11132 // We already did the pre boot receiver for this app with the current 11133 // platform version, so don't do it again... 11134 ris.remove(i); 11135 i--; 11136 // ...however, do keep it as one that has been done, so we don't 11137 // forget about it when rewriting the file of last done receivers. 11138 doneReceivers.add(comp); 11139 } 11140 } 11141 } 11142 11143 // If primary user, send broadcast to all available users, else just to userId 11144 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11145 : new int[] { userId }; 11146 for (int i = 0; i < ris.size(); i++) { 11147 ActivityInfo ai = ris.get(i).activityInfo; 11148 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11149 doneReceivers.add(comp); 11150 intent.setComponent(comp); 11151 for (int j=0; j<users.length; j++) { 11152 IIntentReceiver finisher = null; 11153 // On last receiver and user, set up a completion callback 11154 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11155 finisher = new IIntentReceiver.Stub() { 11156 public void performReceive(Intent intent, int resultCode, 11157 String data, Bundle extras, boolean ordered, 11158 boolean sticky, int sendingUser) { 11159 // The raw IIntentReceiver interface is called 11160 // with the AM lock held, so redispatch to 11161 // execute our code without the lock. 11162 mHandler.post(onFinishCallback); 11163 } 11164 }; 11165 } 11166 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11167 + " for user " + users[j]); 11168 broadcastIntentLocked(null, null, intent, null, finisher, 11169 0, null, null, null, AppOpsManager.OP_NONE, 11170 true, false, MY_PID, Process.SYSTEM_UID, 11171 users[j]); 11172 if (finisher != null) { 11173 waitingUpdate = true; 11174 } 11175 } 11176 } 11177 } 11178 11179 return waitingUpdate; 11180 } 11181 11182 public void systemReady(final Runnable goingCallback) { 11183 synchronized(this) { 11184 if (mSystemReady) { 11185 // If we're done calling all the receivers, run the next "boot phase" passed in 11186 // by the SystemServer 11187 if (goingCallback != null) { 11188 goingCallback.run(); 11189 } 11190 return; 11191 } 11192 11193 // Make sure we have the current profile info, since it is needed for 11194 // security checks. 11195 updateCurrentProfileIdsLocked(); 11196 11197 if (mRecentTasks == null) { 11198 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11199 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11200 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11201 mTaskPersister.startPersisting(); 11202 } 11203 11204 // Check to see if there are any update receivers to run. 11205 if (!mDidUpdate) { 11206 if (mWaitingUpdate) { 11207 return; 11208 } 11209 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11210 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11211 public void run() { 11212 synchronized (ActivityManagerService.this) { 11213 mDidUpdate = true; 11214 } 11215 writeLastDonePreBootReceivers(doneReceivers); 11216 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11217 false); 11218 systemReady(goingCallback); 11219 } 11220 }, doneReceivers, UserHandle.USER_OWNER); 11221 11222 if (mWaitingUpdate) { 11223 return; 11224 } 11225 mDidUpdate = true; 11226 } 11227 11228 mAppOpsService.systemReady(); 11229 mSystemReady = true; 11230 } 11231 11232 ArrayList<ProcessRecord> procsToKill = null; 11233 synchronized(mPidsSelfLocked) { 11234 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11235 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11236 if (!isAllowedWhileBooting(proc.info)){ 11237 if (procsToKill == null) { 11238 procsToKill = new ArrayList<ProcessRecord>(); 11239 } 11240 procsToKill.add(proc); 11241 } 11242 } 11243 } 11244 11245 synchronized(this) { 11246 if (procsToKill != null) { 11247 for (int i=procsToKill.size()-1; i>=0; i--) { 11248 ProcessRecord proc = procsToKill.get(i); 11249 Slog.i(TAG, "Removing system update proc: " + proc); 11250 removeProcessLocked(proc, true, false, "system update done"); 11251 } 11252 } 11253 11254 // Now that we have cleaned up any update processes, we 11255 // are ready to start launching real processes and know that 11256 // we won't trample on them any more. 11257 mProcessesReady = true; 11258 } 11259 11260 Slog.i(TAG, "System now ready"); 11261 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11262 SystemClock.uptimeMillis()); 11263 11264 synchronized(this) { 11265 // Make sure we have no pre-ready processes sitting around. 11266 11267 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11268 ResolveInfo ri = mContext.getPackageManager() 11269 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11270 STOCK_PM_FLAGS); 11271 CharSequence errorMsg = null; 11272 if (ri != null) { 11273 ActivityInfo ai = ri.activityInfo; 11274 ApplicationInfo app = ai.applicationInfo; 11275 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11276 mTopAction = Intent.ACTION_FACTORY_TEST; 11277 mTopData = null; 11278 mTopComponent = new ComponentName(app.packageName, 11279 ai.name); 11280 } else { 11281 errorMsg = mContext.getResources().getText( 11282 com.android.internal.R.string.factorytest_not_system); 11283 } 11284 } else { 11285 errorMsg = mContext.getResources().getText( 11286 com.android.internal.R.string.factorytest_no_action); 11287 } 11288 if (errorMsg != null) { 11289 mTopAction = null; 11290 mTopData = null; 11291 mTopComponent = null; 11292 Message msg = Message.obtain(); 11293 msg.what = SHOW_FACTORY_ERROR_MSG; 11294 msg.getData().putCharSequence("msg", errorMsg); 11295 mHandler.sendMessage(msg); 11296 } 11297 } 11298 } 11299 11300 retrieveSettings(); 11301 loadResourcesOnSystemReady(); 11302 11303 synchronized (this) { 11304 readGrantedUriPermissionsLocked(); 11305 } 11306 11307 if (goingCallback != null) goingCallback.run(); 11308 11309 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11310 Integer.toString(mCurrentUserId), mCurrentUserId); 11311 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11312 Integer.toString(mCurrentUserId), mCurrentUserId); 11313 mSystemServiceManager.startUser(mCurrentUserId); 11314 11315 synchronized (this) { 11316 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11317 try { 11318 List apps = AppGlobals.getPackageManager(). 11319 getPersistentApplications(STOCK_PM_FLAGS); 11320 if (apps != null) { 11321 int N = apps.size(); 11322 int i; 11323 for (i=0; i<N; i++) { 11324 ApplicationInfo info 11325 = (ApplicationInfo)apps.get(i); 11326 if (info != null && 11327 !info.packageName.equals("android")) { 11328 addAppLocked(info, false, null /* ABI override */); 11329 } 11330 } 11331 } 11332 } catch (RemoteException ex) { 11333 // pm is in same process, this will never happen. 11334 } 11335 } 11336 11337 // Start up initial activity. 11338 mBooting = true; 11339 startHomeActivityLocked(mCurrentUserId); 11340 11341 try { 11342 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11343 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11344 + " data partition or your device will be unstable."); 11345 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11346 } 11347 } catch (RemoteException e) { 11348 } 11349 11350 if (!Build.isFingerprintConsistent()) { 11351 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11352 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11353 } 11354 11355 long ident = Binder.clearCallingIdentity(); 11356 try { 11357 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11358 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11359 | Intent.FLAG_RECEIVER_FOREGROUND); 11360 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11361 broadcastIntentLocked(null, null, intent, 11362 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11363 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11364 intent = new Intent(Intent.ACTION_USER_STARTING); 11365 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11366 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11367 broadcastIntentLocked(null, null, intent, 11368 null, new IIntentReceiver.Stub() { 11369 @Override 11370 public void performReceive(Intent intent, int resultCode, String data, 11371 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11372 throws RemoteException { 11373 } 11374 }, 0, null, null, 11375 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11376 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11377 } catch (Throwable t) { 11378 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11379 } finally { 11380 Binder.restoreCallingIdentity(ident); 11381 } 11382 mStackSupervisor.resumeTopActivitiesLocked(); 11383 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11384 } 11385 } 11386 11387 private boolean makeAppCrashingLocked(ProcessRecord app, 11388 String shortMsg, String longMsg, String stackTrace) { 11389 app.crashing = true; 11390 app.crashingReport = generateProcessError(app, 11391 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11392 startAppProblemLocked(app); 11393 app.stopFreezingAllLocked(); 11394 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11395 } 11396 11397 private void makeAppNotRespondingLocked(ProcessRecord app, 11398 String activity, String shortMsg, String longMsg) { 11399 app.notResponding = true; 11400 app.notRespondingReport = generateProcessError(app, 11401 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11402 activity, shortMsg, longMsg, null); 11403 startAppProblemLocked(app); 11404 app.stopFreezingAllLocked(); 11405 } 11406 11407 /** 11408 * Generate a process error record, suitable for attachment to a ProcessRecord. 11409 * 11410 * @param app The ProcessRecord in which the error occurred. 11411 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11412 * ActivityManager.AppErrorStateInfo 11413 * @param activity The activity associated with the crash, if known. 11414 * @param shortMsg Short message describing the crash. 11415 * @param longMsg Long message describing the crash. 11416 * @param stackTrace Full crash stack trace, may be null. 11417 * 11418 * @return Returns a fully-formed AppErrorStateInfo record. 11419 */ 11420 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11421 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11422 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11423 11424 report.condition = condition; 11425 report.processName = app.processName; 11426 report.pid = app.pid; 11427 report.uid = app.info.uid; 11428 report.tag = activity; 11429 report.shortMsg = shortMsg; 11430 report.longMsg = longMsg; 11431 report.stackTrace = stackTrace; 11432 11433 return report; 11434 } 11435 11436 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11437 synchronized (this) { 11438 app.crashing = false; 11439 app.crashingReport = null; 11440 app.notResponding = false; 11441 app.notRespondingReport = null; 11442 if (app.anrDialog == fromDialog) { 11443 app.anrDialog = null; 11444 } 11445 if (app.waitDialog == fromDialog) { 11446 app.waitDialog = null; 11447 } 11448 if (app.pid > 0 && app.pid != MY_PID) { 11449 handleAppCrashLocked(app, null, null, null); 11450 app.kill("user request after error", true); 11451 } 11452 } 11453 } 11454 11455 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11456 String stackTrace) { 11457 long now = SystemClock.uptimeMillis(); 11458 11459 Long crashTime; 11460 if (!app.isolated) { 11461 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11462 } else { 11463 crashTime = null; 11464 } 11465 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11466 // This process loses! 11467 Slog.w(TAG, "Process " + app.info.processName 11468 + " has crashed too many times: killing!"); 11469 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11470 app.userId, app.info.processName, app.uid); 11471 mStackSupervisor.handleAppCrashLocked(app); 11472 if (!app.persistent) { 11473 // We don't want to start this process again until the user 11474 // explicitly does so... but for persistent process, we really 11475 // need to keep it running. If a persistent process is actually 11476 // repeatedly crashing, then badness for everyone. 11477 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11478 app.info.processName); 11479 if (!app.isolated) { 11480 // XXX We don't have a way to mark isolated processes 11481 // as bad, since they don't have a peristent identity. 11482 mBadProcesses.put(app.info.processName, app.uid, 11483 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11484 mProcessCrashTimes.remove(app.info.processName, app.uid); 11485 } 11486 app.bad = true; 11487 app.removed = true; 11488 // Don't let services in this process be restarted and potentially 11489 // annoy the user repeatedly. Unless it is persistent, since those 11490 // processes run critical code. 11491 removeProcessLocked(app, false, false, "crash"); 11492 mStackSupervisor.resumeTopActivitiesLocked(); 11493 return false; 11494 } 11495 mStackSupervisor.resumeTopActivitiesLocked(); 11496 } else { 11497 mStackSupervisor.finishTopRunningActivityLocked(app); 11498 } 11499 11500 // Bump up the crash count of any services currently running in the proc. 11501 for (int i=app.services.size()-1; i>=0; i--) { 11502 // Any services running in the application need to be placed 11503 // back in the pending list. 11504 ServiceRecord sr = app.services.valueAt(i); 11505 sr.crashCount++; 11506 } 11507 11508 // If the crashing process is what we consider to be the "home process" and it has been 11509 // replaced by a third-party app, clear the package preferred activities from packages 11510 // with a home activity running in the process to prevent a repeatedly crashing app 11511 // from blocking the user to manually clear the list. 11512 final ArrayList<ActivityRecord> activities = app.activities; 11513 if (app == mHomeProcess && activities.size() > 0 11514 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11515 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11516 final ActivityRecord r = activities.get(activityNdx); 11517 if (r.isHomeActivity()) { 11518 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11519 try { 11520 ActivityThread.getPackageManager() 11521 .clearPackagePreferredActivities(r.packageName); 11522 } catch (RemoteException c) { 11523 // pm is in same process, this will never happen. 11524 } 11525 } 11526 } 11527 } 11528 11529 if (!app.isolated) { 11530 // XXX Can't keep track of crash times for isolated processes, 11531 // because they don't have a perisistent identity. 11532 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11533 } 11534 11535 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11536 return true; 11537 } 11538 11539 void startAppProblemLocked(ProcessRecord app) { 11540 // If this app is not running under the current user, then we 11541 // can't give it a report button because that would require 11542 // launching the report UI under a different user. 11543 app.errorReportReceiver = null; 11544 11545 for (int userId : mCurrentProfileIds) { 11546 if (app.userId == userId) { 11547 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11548 mContext, app.info.packageName, app.info.flags); 11549 } 11550 } 11551 skipCurrentReceiverLocked(app); 11552 } 11553 11554 void skipCurrentReceiverLocked(ProcessRecord app) { 11555 for (BroadcastQueue queue : mBroadcastQueues) { 11556 queue.skipCurrentReceiverLocked(app); 11557 } 11558 } 11559 11560 /** 11561 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11562 * The application process will exit immediately after this call returns. 11563 * @param app object of the crashing app, null for the system server 11564 * @param crashInfo describing the exception 11565 */ 11566 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11567 ProcessRecord r = findAppProcess(app, "Crash"); 11568 final String processName = app == null ? "system_server" 11569 : (r == null ? "unknown" : r.processName); 11570 11571 handleApplicationCrashInner("crash", r, processName, crashInfo); 11572 } 11573 11574 /* Native crash reporting uses this inner version because it needs to be somewhat 11575 * decoupled from the AM-managed cleanup lifecycle 11576 */ 11577 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11578 ApplicationErrorReport.CrashInfo crashInfo) { 11579 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11580 UserHandle.getUserId(Binder.getCallingUid()), processName, 11581 r == null ? -1 : r.info.flags, 11582 crashInfo.exceptionClassName, 11583 crashInfo.exceptionMessage, 11584 crashInfo.throwFileName, 11585 crashInfo.throwLineNumber); 11586 11587 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11588 11589 crashApplication(r, crashInfo); 11590 } 11591 11592 public void handleApplicationStrictModeViolation( 11593 IBinder app, 11594 int violationMask, 11595 StrictMode.ViolationInfo info) { 11596 ProcessRecord r = findAppProcess(app, "StrictMode"); 11597 if (r == null) { 11598 return; 11599 } 11600 11601 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11602 Integer stackFingerprint = info.hashCode(); 11603 boolean logIt = true; 11604 synchronized (mAlreadyLoggedViolatedStacks) { 11605 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11606 logIt = false; 11607 // TODO: sub-sample into EventLog for these, with 11608 // the info.durationMillis? Then we'd get 11609 // the relative pain numbers, without logging all 11610 // the stack traces repeatedly. We'd want to do 11611 // likewise in the client code, which also does 11612 // dup suppression, before the Binder call. 11613 } else { 11614 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11615 mAlreadyLoggedViolatedStacks.clear(); 11616 } 11617 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11618 } 11619 } 11620 if (logIt) { 11621 logStrictModeViolationToDropBox(r, info); 11622 } 11623 } 11624 11625 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11626 AppErrorResult result = new AppErrorResult(); 11627 synchronized (this) { 11628 final long origId = Binder.clearCallingIdentity(); 11629 11630 Message msg = Message.obtain(); 11631 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11632 HashMap<String, Object> data = new HashMap<String, Object>(); 11633 data.put("result", result); 11634 data.put("app", r); 11635 data.put("violationMask", violationMask); 11636 data.put("info", info); 11637 msg.obj = data; 11638 mHandler.sendMessage(msg); 11639 11640 Binder.restoreCallingIdentity(origId); 11641 } 11642 int res = result.get(); 11643 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11644 } 11645 } 11646 11647 // Depending on the policy in effect, there could be a bunch of 11648 // these in quick succession so we try to batch these together to 11649 // minimize disk writes, number of dropbox entries, and maximize 11650 // compression, by having more fewer, larger records. 11651 private void logStrictModeViolationToDropBox( 11652 ProcessRecord process, 11653 StrictMode.ViolationInfo info) { 11654 if (info == null) { 11655 return; 11656 } 11657 final boolean isSystemApp = process == null || 11658 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11659 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11660 final String processName = process == null ? "unknown" : process.processName; 11661 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11662 final DropBoxManager dbox = (DropBoxManager) 11663 mContext.getSystemService(Context.DROPBOX_SERVICE); 11664 11665 // Exit early if the dropbox isn't configured to accept this report type. 11666 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11667 11668 boolean bufferWasEmpty; 11669 boolean needsFlush; 11670 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11671 synchronized (sb) { 11672 bufferWasEmpty = sb.length() == 0; 11673 appendDropBoxProcessHeaders(process, processName, sb); 11674 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11675 sb.append("System-App: ").append(isSystemApp).append("\n"); 11676 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11677 if (info.violationNumThisLoop != 0) { 11678 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11679 } 11680 if (info.numAnimationsRunning != 0) { 11681 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11682 } 11683 if (info.broadcastIntentAction != null) { 11684 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11685 } 11686 if (info.durationMillis != -1) { 11687 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11688 } 11689 if (info.numInstances != -1) { 11690 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11691 } 11692 if (info.tags != null) { 11693 for (String tag : info.tags) { 11694 sb.append("Span-Tag: ").append(tag).append("\n"); 11695 } 11696 } 11697 sb.append("\n"); 11698 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11699 sb.append(info.crashInfo.stackTrace); 11700 } 11701 sb.append("\n"); 11702 11703 // Only buffer up to ~64k. Various logging bits truncate 11704 // things at 128k. 11705 needsFlush = (sb.length() > 64 * 1024); 11706 } 11707 11708 // Flush immediately if the buffer's grown too large, or this 11709 // is a non-system app. Non-system apps are isolated with a 11710 // different tag & policy and not batched. 11711 // 11712 // Batching is useful during internal testing with 11713 // StrictMode settings turned up high. Without batching, 11714 // thousands of separate files could be created on boot. 11715 if (!isSystemApp || needsFlush) { 11716 new Thread("Error dump: " + dropboxTag) { 11717 @Override 11718 public void run() { 11719 String report; 11720 synchronized (sb) { 11721 report = sb.toString(); 11722 sb.delete(0, sb.length()); 11723 sb.trimToSize(); 11724 } 11725 if (report.length() != 0) { 11726 dbox.addText(dropboxTag, report); 11727 } 11728 } 11729 }.start(); 11730 return; 11731 } 11732 11733 // System app batching: 11734 if (!bufferWasEmpty) { 11735 // An existing dropbox-writing thread is outstanding, so 11736 // we don't need to start it up. The existing thread will 11737 // catch the buffer appends we just did. 11738 return; 11739 } 11740 11741 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11742 // (After this point, we shouldn't access AMS internal data structures.) 11743 new Thread("Error dump: " + dropboxTag) { 11744 @Override 11745 public void run() { 11746 // 5 second sleep to let stacks arrive and be batched together 11747 try { 11748 Thread.sleep(5000); // 5 seconds 11749 } catch (InterruptedException e) {} 11750 11751 String errorReport; 11752 synchronized (mStrictModeBuffer) { 11753 errorReport = mStrictModeBuffer.toString(); 11754 if (errorReport.length() == 0) { 11755 return; 11756 } 11757 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11758 mStrictModeBuffer.trimToSize(); 11759 } 11760 dbox.addText(dropboxTag, errorReport); 11761 } 11762 }.start(); 11763 } 11764 11765 /** 11766 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11767 * @param app object of the crashing app, null for the system server 11768 * @param tag reported by the caller 11769 * @param system whether this wtf is coming from the system 11770 * @param crashInfo describing the context of the error 11771 * @return true if the process should exit immediately (WTF is fatal) 11772 */ 11773 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11774 final ApplicationErrorReport.CrashInfo crashInfo) { 11775 final int callingUid = Binder.getCallingUid(); 11776 final int callingPid = Binder.getCallingPid(); 11777 11778 if (system) { 11779 // If this is coming from the system, we could very well have low-level 11780 // system locks held, so we want to do this all asynchronously. And we 11781 // never want this to become fatal, so there is that too. 11782 mHandler.post(new Runnable() { 11783 @Override public void run() { 11784 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11785 } 11786 }); 11787 return false; 11788 } 11789 11790 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11791 crashInfo); 11792 11793 if (r != null && r.pid != Process.myPid() && 11794 Settings.Global.getInt(mContext.getContentResolver(), 11795 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11796 crashApplication(r, crashInfo); 11797 return true; 11798 } else { 11799 return false; 11800 } 11801 } 11802 11803 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11804 final ApplicationErrorReport.CrashInfo crashInfo) { 11805 final ProcessRecord r = findAppProcess(app, "WTF"); 11806 final String processName = app == null ? "system_server" 11807 : (r == null ? "unknown" : r.processName); 11808 11809 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11810 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11811 11812 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11813 11814 return r; 11815 } 11816 11817 /** 11818 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11819 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11820 */ 11821 private ProcessRecord findAppProcess(IBinder app, String reason) { 11822 if (app == null) { 11823 return null; 11824 } 11825 11826 synchronized (this) { 11827 final int NP = mProcessNames.getMap().size(); 11828 for (int ip=0; ip<NP; ip++) { 11829 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11830 final int NA = apps.size(); 11831 for (int ia=0; ia<NA; ia++) { 11832 ProcessRecord p = apps.valueAt(ia); 11833 if (p.thread != null && p.thread.asBinder() == app) { 11834 return p; 11835 } 11836 } 11837 } 11838 11839 Slog.w(TAG, "Can't find mystery application for " + reason 11840 + " from pid=" + Binder.getCallingPid() 11841 + " uid=" + Binder.getCallingUid() + ": " + app); 11842 return null; 11843 } 11844 } 11845 11846 /** 11847 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11848 * to append various headers to the dropbox log text. 11849 */ 11850 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11851 StringBuilder sb) { 11852 // Watchdog thread ends up invoking this function (with 11853 // a null ProcessRecord) to add the stack file to dropbox. 11854 // Do not acquire a lock on this (am) in such cases, as it 11855 // could cause a potential deadlock, if and when watchdog 11856 // is invoked due to unavailability of lock on am and it 11857 // would prevent watchdog from killing system_server. 11858 if (process == null) { 11859 sb.append("Process: ").append(processName).append("\n"); 11860 return; 11861 } 11862 // Note: ProcessRecord 'process' is guarded by the service 11863 // instance. (notably process.pkgList, which could otherwise change 11864 // concurrently during execution of this method) 11865 synchronized (this) { 11866 sb.append("Process: ").append(processName).append("\n"); 11867 int flags = process.info.flags; 11868 IPackageManager pm = AppGlobals.getPackageManager(); 11869 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11870 for (int ip=0; ip<process.pkgList.size(); ip++) { 11871 String pkg = process.pkgList.keyAt(ip); 11872 sb.append("Package: ").append(pkg); 11873 try { 11874 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11875 if (pi != null) { 11876 sb.append(" v").append(pi.versionCode); 11877 if (pi.versionName != null) { 11878 sb.append(" (").append(pi.versionName).append(")"); 11879 } 11880 } 11881 } catch (RemoteException e) { 11882 Slog.e(TAG, "Error getting package info: " + pkg, e); 11883 } 11884 sb.append("\n"); 11885 } 11886 } 11887 } 11888 11889 private static String processClass(ProcessRecord process) { 11890 if (process == null || process.pid == MY_PID) { 11891 return "system_server"; 11892 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11893 return "system_app"; 11894 } else { 11895 return "data_app"; 11896 } 11897 } 11898 11899 /** 11900 * Write a description of an error (crash, WTF, ANR) to the drop box. 11901 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11902 * @param process which caused the error, null means the system server 11903 * @param activity which triggered the error, null if unknown 11904 * @param parent activity related to the error, null if unknown 11905 * @param subject line related to the error, null if absent 11906 * @param report in long form describing the error, null if absent 11907 * @param logFile to include in the report, null if none 11908 * @param crashInfo giving an application stack trace, null if absent 11909 */ 11910 public void addErrorToDropBox(String eventType, 11911 ProcessRecord process, String processName, ActivityRecord activity, 11912 ActivityRecord parent, String subject, 11913 final String report, final File logFile, 11914 final ApplicationErrorReport.CrashInfo crashInfo) { 11915 // NOTE -- this must never acquire the ActivityManagerService lock, 11916 // otherwise the watchdog may be prevented from resetting the system. 11917 11918 final String dropboxTag = processClass(process) + "_" + eventType; 11919 final DropBoxManager dbox = (DropBoxManager) 11920 mContext.getSystemService(Context.DROPBOX_SERVICE); 11921 11922 // Exit early if the dropbox isn't configured to accept this report type. 11923 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11924 11925 final StringBuilder sb = new StringBuilder(1024); 11926 appendDropBoxProcessHeaders(process, processName, sb); 11927 if (activity != null) { 11928 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11929 } 11930 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11931 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11932 } 11933 if (parent != null && parent != activity) { 11934 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11935 } 11936 if (subject != null) { 11937 sb.append("Subject: ").append(subject).append("\n"); 11938 } 11939 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11940 if (Debug.isDebuggerConnected()) { 11941 sb.append("Debugger: Connected\n"); 11942 } 11943 sb.append("\n"); 11944 11945 // Do the rest in a worker thread to avoid blocking the caller on I/O 11946 // (After this point, we shouldn't access AMS internal data structures.) 11947 Thread worker = new Thread("Error dump: " + dropboxTag) { 11948 @Override 11949 public void run() { 11950 if (report != null) { 11951 sb.append(report); 11952 } 11953 if (logFile != null) { 11954 try { 11955 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11956 "\n\n[[TRUNCATED]]")); 11957 } catch (IOException e) { 11958 Slog.e(TAG, "Error reading " + logFile, e); 11959 } 11960 } 11961 if (crashInfo != null && crashInfo.stackTrace != null) { 11962 sb.append(crashInfo.stackTrace); 11963 } 11964 11965 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11966 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11967 if (lines > 0) { 11968 sb.append("\n"); 11969 11970 // Merge several logcat streams, and take the last N lines 11971 InputStreamReader input = null; 11972 try { 11973 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11974 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11975 "-b", "crash", 11976 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11977 11978 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11979 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11980 input = new InputStreamReader(logcat.getInputStream()); 11981 11982 int num; 11983 char[] buf = new char[8192]; 11984 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11985 } catch (IOException e) { 11986 Slog.e(TAG, "Error running logcat", e); 11987 } finally { 11988 if (input != null) try { input.close(); } catch (IOException e) {} 11989 } 11990 } 11991 11992 dbox.addText(dropboxTag, sb.toString()); 11993 } 11994 }; 11995 11996 if (process == null) { 11997 // If process is null, we are being called from some internal code 11998 // and may be about to die -- run this synchronously. 11999 worker.run(); 12000 } else { 12001 worker.start(); 12002 } 12003 } 12004 12005 /** 12006 * Bring up the "unexpected error" dialog box for a crashing app. 12007 * Deal with edge cases (intercepts from instrumented applications, 12008 * ActivityController, error intent receivers, that sort of thing). 12009 * @param r the application crashing 12010 * @param crashInfo describing the failure 12011 */ 12012 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12013 long timeMillis = System.currentTimeMillis(); 12014 String shortMsg = crashInfo.exceptionClassName; 12015 String longMsg = crashInfo.exceptionMessage; 12016 String stackTrace = crashInfo.stackTrace; 12017 if (shortMsg != null && longMsg != null) { 12018 longMsg = shortMsg + ": " + longMsg; 12019 } else if (shortMsg != null) { 12020 longMsg = shortMsg; 12021 } 12022 12023 AppErrorResult result = new AppErrorResult(); 12024 synchronized (this) { 12025 if (mController != null) { 12026 try { 12027 String name = r != null ? r.processName : null; 12028 int pid = r != null ? r.pid : Binder.getCallingPid(); 12029 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12030 if (!mController.appCrashed(name, pid, 12031 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12032 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12033 && "Native crash".equals(crashInfo.exceptionClassName)) { 12034 Slog.w(TAG, "Skip killing native crashed app " + name 12035 + "(" + pid + ") during testing"); 12036 } else { 12037 Slog.w(TAG, "Force-killing crashed app " + name 12038 + " at watcher's request"); 12039 if (r != null) { 12040 r.kill("crash", true); 12041 } else { 12042 // Huh. 12043 Process.killProcess(pid); 12044 Process.killProcessGroup(uid, pid); 12045 } 12046 } 12047 return; 12048 } 12049 } catch (RemoteException e) { 12050 mController = null; 12051 Watchdog.getInstance().setActivityController(null); 12052 } 12053 } 12054 12055 final long origId = Binder.clearCallingIdentity(); 12056 12057 // If this process is running instrumentation, finish it. 12058 if (r != null && r.instrumentationClass != null) { 12059 Slog.w(TAG, "Error in app " + r.processName 12060 + " running instrumentation " + r.instrumentationClass + ":"); 12061 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12062 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12063 Bundle info = new Bundle(); 12064 info.putString("shortMsg", shortMsg); 12065 info.putString("longMsg", longMsg); 12066 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12067 Binder.restoreCallingIdentity(origId); 12068 return; 12069 } 12070 12071 // Log crash in battery stats. 12072 if (r != null) { 12073 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12074 } 12075 12076 // If we can't identify the process or it's already exceeded its crash quota, 12077 // quit right away without showing a crash dialog. 12078 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12079 Binder.restoreCallingIdentity(origId); 12080 return; 12081 } 12082 12083 Message msg = Message.obtain(); 12084 msg.what = SHOW_ERROR_MSG; 12085 HashMap data = new HashMap(); 12086 data.put("result", result); 12087 data.put("app", r); 12088 msg.obj = data; 12089 mHandler.sendMessage(msg); 12090 12091 Binder.restoreCallingIdentity(origId); 12092 } 12093 12094 int res = result.get(); 12095 12096 Intent appErrorIntent = null; 12097 synchronized (this) { 12098 if (r != null && !r.isolated) { 12099 // XXX Can't keep track of crash time for isolated processes, 12100 // since they don't have a persistent identity. 12101 mProcessCrashTimes.put(r.info.processName, r.uid, 12102 SystemClock.uptimeMillis()); 12103 } 12104 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12105 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12106 } 12107 } 12108 12109 if (appErrorIntent != null) { 12110 try { 12111 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12112 } catch (ActivityNotFoundException e) { 12113 Slog.w(TAG, "bug report receiver dissappeared", e); 12114 } 12115 } 12116 } 12117 12118 Intent createAppErrorIntentLocked(ProcessRecord r, 12119 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12120 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12121 if (report == null) { 12122 return null; 12123 } 12124 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12125 result.setComponent(r.errorReportReceiver); 12126 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12127 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12128 return result; 12129 } 12130 12131 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12132 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12133 if (r.errorReportReceiver == null) { 12134 return null; 12135 } 12136 12137 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12138 return null; 12139 } 12140 12141 ApplicationErrorReport report = new ApplicationErrorReport(); 12142 report.packageName = r.info.packageName; 12143 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12144 report.processName = r.processName; 12145 report.time = timeMillis; 12146 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12147 12148 if (r.crashing || r.forceCrashReport) { 12149 report.type = ApplicationErrorReport.TYPE_CRASH; 12150 report.crashInfo = crashInfo; 12151 } else if (r.notResponding) { 12152 report.type = ApplicationErrorReport.TYPE_ANR; 12153 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12154 12155 report.anrInfo.activity = r.notRespondingReport.tag; 12156 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12157 report.anrInfo.info = r.notRespondingReport.longMsg; 12158 } 12159 12160 return report; 12161 } 12162 12163 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12164 enforceNotIsolatedCaller("getProcessesInErrorState"); 12165 // assume our apps are happy - lazy create the list 12166 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12167 12168 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12169 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12170 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12171 12172 synchronized (this) { 12173 12174 // iterate across all processes 12175 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12176 ProcessRecord app = mLruProcesses.get(i); 12177 if (!allUsers && app.userId != userId) { 12178 continue; 12179 } 12180 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12181 // This one's in trouble, so we'll generate a report for it 12182 // crashes are higher priority (in case there's a crash *and* an anr) 12183 ActivityManager.ProcessErrorStateInfo report = null; 12184 if (app.crashing) { 12185 report = app.crashingReport; 12186 } else if (app.notResponding) { 12187 report = app.notRespondingReport; 12188 } 12189 12190 if (report != null) { 12191 if (errList == null) { 12192 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12193 } 12194 errList.add(report); 12195 } else { 12196 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12197 " crashing = " + app.crashing + 12198 " notResponding = " + app.notResponding); 12199 } 12200 } 12201 } 12202 } 12203 12204 return errList; 12205 } 12206 12207 static int procStateToImportance(int procState, int memAdj, 12208 ActivityManager.RunningAppProcessInfo currApp) { 12209 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12210 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12211 currApp.lru = memAdj; 12212 } else { 12213 currApp.lru = 0; 12214 } 12215 return imp; 12216 } 12217 12218 private void fillInProcMemInfo(ProcessRecord app, 12219 ActivityManager.RunningAppProcessInfo outInfo) { 12220 outInfo.pid = app.pid; 12221 outInfo.uid = app.info.uid; 12222 if (mHeavyWeightProcess == app) { 12223 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12224 } 12225 if (app.persistent) { 12226 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12227 } 12228 if (app.activities.size() > 0) { 12229 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12230 } 12231 outInfo.lastTrimLevel = app.trimMemoryLevel; 12232 int adj = app.curAdj; 12233 int procState = app.curProcState; 12234 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12235 outInfo.importanceReasonCode = app.adjTypeCode; 12236 outInfo.processState = app.curProcState; 12237 } 12238 12239 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12240 enforceNotIsolatedCaller("getRunningAppProcesses"); 12241 // Lazy instantiation of list 12242 List<ActivityManager.RunningAppProcessInfo> runList = null; 12243 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12244 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12245 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12246 synchronized (this) { 12247 // Iterate across all processes 12248 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12249 ProcessRecord app = mLruProcesses.get(i); 12250 if (!allUsers && app.userId != userId) { 12251 continue; 12252 } 12253 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12254 // Generate process state info for running application 12255 ActivityManager.RunningAppProcessInfo currApp = 12256 new ActivityManager.RunningAppProcessInfo(app.processName, 12257 app.pid, app.getPackageList()); 12258 fillInProcMemInfo(app, currApp); 12259 if (app.adjSource instanceof ProcessRecord) { 12260 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12261 currApp.importanceReasonImportance = 12262 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12263 app.adjSourceProcState); 12264 } else if (app.adjSource instanceof ActivityRecord) { 12265 ActivityRecord r = (ActivityRecord)app.adjSource; 12266 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12267 } 12268 if (app.adjTarget instanceof ComponentName) { 12269 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12270 } 12271 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12272 // + " lru=" + currApp.lru); 12273 if (runList == null) { 12274 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12275 } 12276 runList.add(currApp); 12277 } 12278 } 12279 } 12280 return runList; 12281 } 12282 12283 public List<ApplicationInfo> getRunningExternalApplications() { 12284 enforceNotIsolatedCaller("getRunningExternalApplications"); 12285 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12286 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12287 if (runningApps != null && runningApps.size() > 0) { 12288 Set<String> extList = new HashSet<String>(); 12289 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12290 if (app.pkgList != null) { 12291 for (String pkg : app.pkgList) { 12292 extList.add(pkg); 12293 } 12294 } 12295 } 12296 IPackageManager pm = AppGlobals.getPackageManager(); 12297 for (String pkg : extList) { 12298 try { 12299 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12300 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12301 retList.add(info); 12302 } 12303 } catch (RemoteException e) { 12304 } 12305 } 12306 } 12307 return retList; 12308 } 12309 12310 @Override 12311 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12312 enforceNotIsolatedCaller("getMyMemoryState"); 12313 synchronized (this) { 12314 ProcessRecord proc; 12315 synchronized (mPidsSelfLocked) { 12316 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12317 } 12318 fillInProcMemInfo(proc, outInfo); 12319 } 12320 } 12321 12322 @Override 12323 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12324 if (checkCallingPermission(android.Manifest.permission.DUMP) 12325 != PackageManager.PERMISSION_GRANTED) { 12326 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12327 + Binder.getCallingPid() 12328 + ", uid=" + Binder.getCallingUid() 12329 + " without permission " 12330 + android.Manifest.permission.DUMP); 12331 return; 12332 } 12333 12334 boolean dumpAll = false; 12335 boolean dumpClient = false; 12336 String dumpPackage = null; 12337 12338 int opti = 0; 12339 while (opti < args.length) { 12340 String opt = args[opti]; 12341 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12342 break; 12343 } 12344 opti++; 12345 if ("-a".equals(opt)) { 12346 dumpAll = true; 12347 } else if ("-c".equals(opt)) { 12348 dumpClient = true; 12349 } else if ("-p".equals(opt)) { 12350 if (opti < args.length) { 12351 dumpPackage = args[opti]; 12352 opti++; 12353 } else { 12354 pw.println("Error: -p option requires package argument"); 12355 return; 12356 } 12357 dumpClient = true; 12358 } else if ("-h".equals(opt)) { 12359 pw.println("Activity manager dump options:"); 12360 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12361 pw.println(" cmd may be one of:"); 12362 pw.println(" a[ctivities]: activity stack state"); 12363 pw.println(" r[recents]: recent activities state"); 12364 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12365 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12366 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12367 pw.println(" o[om]: out of memory management"); 12368 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12369 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12370 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12371 pw.println(" as[sociations]: tracked app associations"); 12372 pw.println(" service [COMP_SPEC]: service client-side state"); 12373 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12374 pw.println(" all: dump all activities"); 12375 pw.println(" top: dump the top activity"); 12376 pw.println(" write: write all pending state to storage"); 12377 pw.println(" track-associations: enable association tracking"); 12378 pw.println(" untrack-associations: disable and clear association tracking"); 12379 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12380 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12381 pw.println(" a partial substring in a component name, a"); 12382 pw.println(" hex object identifier."); 12383 pw.println(" -a: include all available server state."); 12384 pw.println(" -c: include client state."); 12385 pw.println(" -p: limit output to given package."); 12386 return; 12387 } else { 12388 pw.println("Unknown argument: " + opt + "; use -h for help"); 12389 } 12390 } 12391 12392 long origId = Binder.clearCallingIdentity(); 12393 boolean more = false; 12394 // Is the caller requesting to dump a particular piece of data? 12395 if (opti < args.length) { 12396 String cmd = args[opti]; 12397 opti++; 12398 if ("activities".equals(cmd) || "a".equals(cmd)) { 12399 synchronized (this) { 12400 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12401 } 12402 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12403 synchronized (this) { 12404 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12405 } 12406 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12407 String[] newArgs; 12408 String name; 12409 if (opti >= args.length) { 12410 name = null; 12411 newArgs = EMPTY_STRING_ARRAY; 12412 } else { 12413 dumpPackage = args[opti]; 12414 opti++; 12415 newArgs = new String[args.length - opti]; 12416 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12417 args.length - opti); 12418 } 12419 synchronized (this) { 12420 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12421 } 12422 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12423 String[] newArgs; 12424 String name; 12425 if (opti >= args.length) { 12426 name = null; 12427 newArgs = EMPTY_STRING_ARRAY; 12428 } else { 12429 dumpPackage = args[opti]; 12430 opti++; 12431 newArgs = new String[args.length - opti]; 12432 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12433 args.length - opti); 12434 } 12435 synchronized (this) { 12436 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12437 } 12438 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12439 String[] newArgs; 12440 String name; 12441 if (opti >= args.length) { 12442 name = null; 12443 newArgs = EMPTY_STRING_ARRAY; 12444 } else { 12445 dumpPackage = args[opti]; 12446 opti++; 12447 newArgs = new String[args.length - opti]; 12448 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12449 args.length - opti); 12450 } 12451 synchronized (this) { 12452 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12453 } 12454 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12455 synchronized (this) { 12456 dumpOomLocked(fd, pw, args, opti, true); 12457 } 12458 } else if ("provider".equals(cmd)) { 12459 String[] newArgs; 12460 String name; 12461 if (opti >= args.length) { 12462 name = null; 12463 newArgs = EMPTY_STRING_ARRAY; 12464 } else { 12465 name = args[opti]; 12466 opti++; 12467 newArgs = new String[args.length - opti]; 12468 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12469 } 12470 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12471 pw.println("No providers match: " + name); 12472 pw.println("Use -h for help."); 12473 } 12474 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12475 synchronized (this) { 12476 dumpProvidersLocked(fd, pw, args, opti, true, null); 12477 } 12478 } else if ("service".equals(cmd)) { 12479 String[] newArgs; 12480 String name; 12481 if (opti >= args.length) { 12482 name = null; 12483 newArgs = EMPTY_STRING_ARRAY; 12484 } else { 12485 name = args[opti]; 12486 opti++; 12487 newArgs = new String[args.length - opti]; 12488 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12489 args.length - opti); 12490 } 12491 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12492 pw.println("No services match: " + name); 12493 pw.println("Use -h for help."); 12494 } 12495 } else if ("package".equals(cmd)) { 12496 String[] newArgs; 12497 if (opti >= args.length) { 12498 pw.println("package: no package name specified"); 12499 pw.println("Use -h for help."); 12500 } else { 12501 dumpPackage = args[opti]; 12502 opti++; 12503 newArgs = new String[args.length - opti]; 12504 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12505 args.length - opti); 12506 args = newArgs; 12507 opti = 0; 12508 more = true; 12509 } 12510 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12511 synchronized (this) { 12512 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12513 } 12514 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12515 synchronized (this) { 12516 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12517 } 12518 } else if ("write".equals(cmd)) { 12519 mTaskPersister.flush(); 12520 pw.println("All tasks persisted."); 12521 return; 12522 } else if ("track-associations".equals(cmd)) { 12523 synchronized (this) { 12524 if (!mTrackingAssociations) { 12525 mTrackingAssociations = true; 12526 pw.println("Association tracking started."); 12527 } else { 12528 pw.println("Association tracking already enabled."); 12529 } 12530 } 12531 return; 12532 } else if ("untrack-associations".equals(cmd)) { 12533 synchronized (this) { 12534 if (mTrackingAssociations) { 12535 mTrackingAssociations = false; 12536 mAssociations.clear(); 12537 pw.println("Association tracking stopped."); 12538 } else { 12539 pw.println("Association tracking not running."); 12540 } 12541 } 12542 return; 12543 } else { 12544 // Dumping a single activity? 12545 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12546 pw.println("Bad activity command, or no activities match: " + cmd); 12547 pw.println("Use -h for help."); 12548 } 12549 } 12550 if (!more) { 12551 Binder.restoreCallingIdentity(origId); 12552 return; 12553 } 12554 } 12555 12556 // No piece of data specified, dump everything. 12557 synchronized (this) { 12558 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12559 pw.println(); 12560 if (dumpAll) { 12561 pw.println("-------------------------------------------------------------------------------"); 12562 } 12563 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12564 pw.println(); 12565 if (dumpAll) { 12566 pw.println("-------------------------------------------------------------------------------"); 12567 } 12568 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12569 pw.println(); 12570 if (dumpAll) { 12571 pw.println("-------------------------------------------------------------------------------"); 12572 } 12573 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12574 pw.println(); 12575 if (dumpAll) { 12576 pw.println("-------------------------------------------------------------------------------"); 12577 } 12578 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12579 pw.println(); 12580 if (dumpAll) { 12581 pw.println("-------------------------------------------------------------------------------"); 12582 } 12583 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12584 if (mAssociations.size() > 0) { 12585 pw.println(); 12586 if (dumpAll) { 12587 pw.println("-------------------------------------------------------------------------------"); 12588 } 12589 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12590 } 12591 pw.println(); 12592 if (dumpAll) { 12593 pw.println("-------------------------------------------------------------------------------"); 12594 } 12595 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12596 } 12597 Binder.restoreCallingIdentity(origId); 12598 } 12599 12600 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12601 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12602 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12603 12604 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12605 dumpPackage); 12606 boolean needSep = printedAnything; 12607 12608 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12609 dumpPackage, needSep, " mFocusedActivity: "); 12610 if (printed) { 12611 printedAnything = true; 12612 needSep = false; 12613 } 12614 12615 if (dumpPackage == null) { 12616 if (needSep) { 12617 pw.println(); 12618 } 12619 needSep = true; 12620 printedAnything = true; 12621 mStackSupervisor.dump(pw, " "); 12622 } 12623 12624 if (!printedAnything) { 12625 pw.println(" (nothing)"); 12626 } 12627 } 12628 12629 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12630 int opti, boolean dumpAll, String dumpPackage) { 12631 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12632 12633 boolean printedAnything = false; 12634 12635 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12636 boolean printedHeader = false; 12637 12638 final int N = mRecentTasks.size(); 12639 for (int i=0; i<N; i++) { 12640 TaskRecord tr = mRecentTasks.get(i); 12641 if (dumpPackage != null) { 12642 if (tr.realActivity == null || 12643 !dumpPackage.equals(tr.realActivity)) { 12644 continue; 12645 } 12646 } 12647 if (!printedHeader) { 12648 pw.println(" Recent tasks:"); 12649 printedHeader = true; 12650 printedAnything = true; 12651 } 12652 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12653 pw.println(tr); 12654 if (dumpAll) { 12655 mRecentTasks.get(i).dump(pw, " "); 12656 } 12657 } 12658 } 12659 12660 if (!printedAnything) { 12661 pw.println(" (nothing)"); 12662 } 12663 } 12664 12665 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12666 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12667 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12668 12669 int dumpUid = 0; 12670 if (dumpPackage != null) { 12671 IPackageManager pm = AppGlobals.getPackageManager(); 12672 try { 12673 dumpUid = pm.getPackageUid(dumpPackage, 0); 12674 } catch (RemoteException e) { 12675 } 12676 } 12677 12678 boolean printedAnything = false; 12679 12680 final long now = SystemClock.uptimeMillis(); 12681 12682 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12683 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12684 = mAssociations.valueAt(i1); 12685 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12686 SparseArray<ArrayMap<String, Association>> sourceUids 12687 = targetComponents.valueAt(i2); 12688 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12689 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12690 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12691 Association ass = sourceProcesses.valueAt(i4); 12692 if (dumpPackage != null) { 12693 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12694 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12695 continue; 12696 } 12697 } 12698 printedAnything = true; 12699 pw.print(" "); 12700 pw.print(ass.mTargetProcess); 12701 pw.print("/"); 12702 UserHandle.formatUid(pw, ass.mTargetUid); 12703 pw.print(" <- "); 12704 pw.print(ass.mSourceProcess); 12705 pw.print("/"); 12706 UserHandle.formatUid(pw, ass.mSourceUid); 12707 pw.println(); 12708 pw.print(" via "); 12709 pw.print(ass.mTargetComponent.flattenToShortString()); 12710 pw.println(); 12711 pw.print(" "); 12712 long dur = ass.mTime; 12713 if (ass.mNesting > 0) { 12714 dur += now - ass.mStartTime; 12715 } 12716 TimeUtils.formatDuration(dur, pw); 12717 pw.print(" ("); 12718 pw.print(ass.mCount); 12719 pw.println(" times)"); 12720 if (ass.mNesting > 0) { 12721 pw.print(" "); 12722 pw.print(" Currently active: "); 12723 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12724 pw.println(); 12725 } 12726 } 12727 } 12728 } 12729 12730 } 12731 12732 if (!printedAnything) { 12733 pw.println(" (nothing)"); 12734 } 12735 } 12736 12737 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12738 int opti, boolean dumpAll, String dumpPackage) { 12739 boolean needSep = false; 12740 boolean printedAnything = false; 12741 int numPers = 0; 12742 12743 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12744 12745 if (dumpAll) { 12746 final int NP = mProcessNames.getMap().size(); 12747 for (int ip=0; ip<NP; ip++) { 12748 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12749 final int NA = procs.size(); 12750 for (int ia=0; ia<NA; ia++) { 12751 ProcessRecord r = procs.valueAt(ia); 12752 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12753 continue; 12754 } 12755 if (!needSep) { 12756 pw.println(" All known processes:"); 12757 needSep = true; 12758 printedAnything = true; 12759 } 12760 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12761 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12762 pw.print(" "); pw.println(r); 12763 r.dump(pw, " "); 12764 if (r.persistent) { 12765 numPers++; 12766 } 12767 } 12768 } 12769 } 12770 12771 if (mIsolatedProcesses.size() > 0) { 12772 boolean printed = false; 12773 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12774 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12775 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12776 continue; 12777 } 12778 if (!printed) { 12779 if (needSep) { 12780 pw.println(); 12781 } 12782 pw.println(" Isolated process list (sorted by uid):"); 12783 printedAnything = true; 12784 printed = true; 12785 needSep = true; 12786 } 12787 pw.println(String.format("%sIsolated #%2d: %s", 12788 " ", i, r.toString())); 12789 } 12790 } 12791 12792 if (mLruProcesses.size() > 0) { 12793 if (needSep) { 12794 pw.println(); 12795 } 12796 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12797 pw.print(" total, non-act at "); 12798 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12799 pw.print(", non-svc at "); 12800 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12801 pw.println("):"); 12802 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12803 needSep = true; 12804 printedAnything = true; 12805 } 12806 12807 if (dumpAll || dumpPackage != null) { 12808 synchronized (mPidsSelfLocked) { 12809 boolean printed = false; 12810 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12811 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12812 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12813 continue; 12814 } 12815 if (!printed) { 12816 if (needSep) pw.println(); 12817 needSep = true; 12818 pw.println(" PID mappings:"); 12819 printed = true; 12820 printedAnything = true; 12821 } 12822 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12823 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12824 } 12825 } 12826 } 12827 12828 if (mForegroundProcesses.size() > 0) { 12829 synchronized (mPidsSelfLocked) { 12830 boolean printed = false; 12831 for (int i=0; i<mForegroundProcesses.size(); i++) { 12832 ProcessRecord r = mPidsSelfLocked.get( 12833 mForegroundProcesses.valueAt(i).pid); 12834 if (dumpPackage != null && (r == null 12835 || !r.pkgList.containsKey(dumpPackage))) { 12836 continue; 12837 } 12838 if (!printed) { 12839 if (needSep) pw.println(); 12840 needSep = true; 12841 pw.println(" Foreground Processes:"); 12842 printed = true; 12843 printedAnything = true; 12844 } 12845 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12846 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12847 } 12848 } 12849 } 12850 12851 if (mPersistentStartingProcesses.size() > 0) { 12852 if (needSep) pw.println(); 12853 needSep = true; 12854 printedAnything = true; 12855 pw.println(" Persisent processes that are starting:"); 12856 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12857 "Starting Norm", "Restarting PERS", dumpPackage); 12858 } 12859 12860 if (mRemovedProcesses.size() > 0) { 12861 if (needSep) pw.println(); 12862 needSep = true; 12863 printedAnything = true; 12864 pw.println(" Processes that are being removed:"); 12865 dumpProcessList(pw, this, mRemovedProcesses, " ", 12866 "Removed Norm", "Removed PERS", dumpPackage); 12867 } 12868 12869 if (mProcessesOnHold.size() > 0) { 12870 if (needSep) pw.println(); 12871 needSep = true; 12872 printedAnything = true; 12873 pw.println(" Processes that are on old until the system is ready:"); 12874 dumpProcessList(pw, this, mProcessesOnHold, " ", 12875 "OnHold Norm", "OnHold PERS", dumpPackage); 12876 } 12877 12878 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12879 12880 if (mProcessCrashTimes.getMap().size() > 0) { 12881 boolean printed = false; 12882 long now = SystemClock.uptimeMillis(); 12883 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12884 final int NP = pmap.size(); 12885 for (int ip=0; ip<NP; ip++) { 12886 String pname = pmap.keyAt(ip); 12887 SparseArray<Long> uids = pmap.valueAt(ip); 12888 final int N = uids.size(); 12889 for (int i=0; i<N; i++) { 12890 int puid = uids.keyAt(i); 12891 ProcessRecord r = mProcessNames.get(pname, puid); 12892 if (dumpPackage != null && (r == null 12893 || !r.pkgList.containsKey(dumpPackage))) { 12894 continue; 12895 } 12896 if (!printed) { 12897 if (needSep) pw.println(); 12898 needSep = true; 12899 pw.println(" Time since processes crashed:"); 12900 printed = true; 12901 printedAnything = true; 12902 } 12903 pw.print(" Process "); pw.print(pname); 12904 pw.print(" uid "); pw.print(puid); 12905 pw.print(": last crashed "); 12906 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12907 pw.println(" ago"); 12908 } 12909 } 12910 } 12911 12912 if (mBadProcesses.getMap().size() > 0) { 12913 boolean printed = false; 12914 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12915 final int NP = pmap.size(); 12916 for (int ip=0; ip<NP; ip++) { 12917 String pname = pmap.keyAt(ip); 12918 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12919 final int N = uids.size(); 12920 for (int i=0; i<N; i++) { 12921 int puid = uids.keyAt(i); 12922 ProcessRecord r = mProcessNames.get(pname, puid); 12923 if (dumpPackage != null && (r == null 12924 || !r.pkgList.containsKey(dumpPackage))) { 12925 continue; 12926 } 12927 if (!printed) { 12928 if (needSep) pw.println(); 12929 needSep = true; 12930 pw.println(" Bad processes:"); 12931 printedAnything = true; 12932 } 12933 BadProcessInfo info = uids.valueAt(i); 12934 pw.print(" Bad process "); pw.print(pname); 12935 pw.print(" uid "); pw.print(puid); 12936 pw.print(": crashed at time "); pw.println(info.time); 12937 if (info.shortMsg != null) { 12938 pw.print(" Short msg: "); pw.println(info.shortMsg); 12939 } 12940 if (info.longMsg != null) { 12941 pw.print(" Long msg: "); pw.println(info.longMsg); 12942 } 12943 if (info.stack != null) { 12944 pw.println(" Stack:"); 12945 int lastPos = 0; 12946 for (int pos=0; pos<info.stack.length(); pos++) { 12947 if (info.stack.charAt(pos) == '\n') { 12948 pw.print(" "); 12949 pw.write(info.stack, lastPos, pos-lastPos); 12950 pw.println(); 12951 lastPos = pos+1; 12952 } 12953 } 12954 if (lastPos < info.stack.length()) { 12955 pw.print(" "); 12956 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12957 pw.println(); 12958 } 12959 } 12960 } 12961 } 12962 } 12963 12964 if (dumpPackage == null) { 12965 pw.println(); 12966 needSep = false; 12967 pw.println(" mStartedUsers:"); 12968 for (int i=0; i<mStartedUsers.size(); i++) { 12969 UserStartedState uss = mStartedUsers.valueAt(i); 12970 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12971 pw.print(": "); uss.dump("", pw); 12972 } 12973 pw.print(" mStartedUserArray: ["); 12974 for (int i=0; i<mStartedUserArray.length; i++) { 12975 if (i > 0) pw.print(", "); 12976 pw.print(mStartedUserArray[i]); 12977 } 12978 pw.println("]"); 12979 pw.print(" mUserLru: ["); 12980 for (int i=0; i<mUserLru.size(); i++) { 12981 if (i > 0) pw.print(", "); 12982 pw.print(mUserLru.get(i)); 12983 } 12984 pw.println("]"); 12985 if (dumpAll) { 12986 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12987 } 12988 synchronized (mUserProfileGroupIdsSelfLocked) { 12989 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12990 pw.println(" mUserProfileGroupIds:"); 12991 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12992 pw.print(" User #"); 12993 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12994 pw.print(" -> profile #"); 12995 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12996 } 12997 } 12998 } 12999 } 13000 if (mHomeProcess != null && (dumpPackage == null 13001 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13002 if (needSep) { 13003 pw.println(); 13004 needSep = false; 13005 } 13006 pw.println(" mHomeProcess: " + mHomeProcess); 13007 } 13008 if (mPreviousProcess != null && (dumpPackage == null 13009 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13010 if (needSep) { 13011 pw.println(); 13012 needSep = false; 13013 } 13014 pw.println(" mPreviousProcess: " + mPreviousProcess); 13015 } 13016 if (dumpAll) { 13017 StringBuilder sb = new StringBuilder(128); 13018 sb.append(" mPreviousProcessVisibleTime: "); 13019 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13020 pw.println(sb); 13021 } 13022 if (mHeavyWeightProcess != null && (dumpPackage == null 13023 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13024 if (needSep) { 13025 pw.println(); 13026 needSep = false; 13027 } 13028 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13029 } 13030 if (dumpPackage == null) { 13031 pw.println(" mConfiguration: " + mConfiguration); 13032 } 13033 if (dumpAll) { 13034 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13035 if (mCompatModePackages.getPackages().size() > 0) { 13036 boolean printed = false; 13037 for (Map.Entry<String, Integer> entry 13038 : mCompatModePackages.getPackages().entrySet()) { 13039 String pkg = entry.getKey(); 13040 int mode = entry.getValue(); 13041 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13042 continue; 13043 } 13044 if (!printed) { 13045 pw.println(" mScreenCompatPackages:"); 13046 printed = true; 13047 } 13048 pw.print(" "); pw.print(pkg); pw.print(": "); 13049 pw.print(mode); pw.println(); 13050 } 13051 } 13052 } 13053 if (dumpPackage == null) { 13054 pw.println(" mWakefulness=" 13055 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13056 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13057 + lockScreenShownToString()); 13058 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13059 + " mTestPssMode=" + mTestPssMode); 13060 } 13061 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13062 || mOrigWaitForDebugger) { 13063 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13064 || dumpPackage.equals(mOrigDebugApp)) { 13065 if (needSep) { 13066 pw.println(); 13067 needSep = false; 13068 } 13069 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13070 + " mDebugTransient=" + mDebugTransient 13071 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13072 } 13073 } 13074 if (mOpenGlTraceApp != null) { 13075 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13076 if (needSep) { 13077 pw.println(); 13078 needSep = false; 13079 } 13080 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13081 } 13082 } 13083 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13084 || mProfileFd != null) { 13085 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13086 if (needSep) { 13087 pw.println(); 13088 needSep = false; 13089 } 13090 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13091 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13092 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13093 + mAutoStopProfiler); 13094 pw.println(" mProfileType=" + mProfileType); 13095 } 13096 } 13097 if (dumpPackage == null) { 13098 if (mAlwaysFinishActivities || mController != null) { 13099 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13100 + " mController=" + mController); 13101 } 13102 if (dumpAll) { 13103 pw.println(" Total persistent processes: " + numPers); 13104 pw.println(" mProcessesReady=" + mProcessesReady 13105 + " mSystemReady=" + mSystemReady 13106 + " mBooted=" + mBooted 13107 + " mFactoryTest=" + mFactoryTest); 13108 pw.println(" mBooting=" + mBooting 13109 + " mCallFinishBooting=" + mCallFinishBooting 13110 + " mBootAnimationComplete=" + mBootAnimationComplete); 13111 pw.print(" mLastPowerCheckRealtime="); 13112 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13113 pw.println(""); 13114 pw.print(" mLastPowerCheckUptime="); 13115 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13116 pw.println(""); 13117 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13118 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13119 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13120 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13121 + " (" + mLruProcesses.size() + " total)" 13122 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13123 + " mNumServiceProcs=" + mNumServiceProcs 13124 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13125 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13126 + " mLastMemoryLevel" + mLastMemoryLevel 13127 + " mLastNumProcesses" + mLastNumProcesses); 13128 long now = SystemClock.uptimeMillis(); 13129 pw.print(" mLastIdleTime="); 13130 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13131 pw.print(" mLowRamSinceLastIdle="); 13132 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13133 pw.println(); 13134 } 13135 } 13136 13137 if (!printedAnything) { 13138 pw.println(" (nothing)"); 13139 } 13140 } 13141 13142 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13143 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13144 if (mProcessesToGc.size() > 0) { 13145 boolean printed = false; 13146 long now = SystemClock.uptimeMillis(); 13147 for (int i=0; i<mProcessesToGc.size(); i++) { 13148 ProcessRecord proc = mProcessesToGc.get(i); 13149 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13150 continue; 13151 } 13152 if (!printed) { 13153 if (needSep) pw.println(); 13154 needSep = true; 13155 pw.println(" Processes that are waiting to GC:"); 13156 printed = true; 13157 } 13158 pw.print(" Process "); pw.println(proc); 13159 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13160 pw.print(", last gced="); 13161 pw.print(now-proc.lastRequestedGc); 13162 pw.print(" ms ago, last lowMem="); 13163 pw.print(now-proc.lastLowMemory); 13164 pw.println(" ms ago"); 13165 13166 } 13167 } 13168 return needSep; 13169 } 13170 13171 void printOomLevel(PrintWriter pw, String name, int adj) { 13172 pw.print(" "); 13173 if (adj >= 0) { 13174 pw.print(' '); 13175 if (adj < 10) pw.print(' '); 13176 } else { 13177 if (adj > -10) pw.print(' '); 13178 } 13179 pw.print(adj); 13180 pw.print(": "); 13181 pw.print(name); 13182 pw.print(" ("); 13183 pw.print(mProcessList.getMemLevel(adj)/1024); 13184 pw.println(" kB)"); 13185 } 13186 13187 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13188 int opti, boolean dumpAll) { 13189 boolean needSep = false; 13190 13191 if (mLruProcesses.size() > 0) { 13192 if (needSep) pw.println(); 13193 needSep = true; 13194 pw.println(" OOM levels:"); 13195 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13196 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13197 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13198 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13199 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13200 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13201 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13202 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13203 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13204 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13205 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13206 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13207 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13208 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13209 13210 if (needSep) pw.println(); 13211 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13212 pw.print(" total, non-act at "); 13213 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13214 pw.print(", non-svc at "); 13215 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13216 pw.println("):"); 13217 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13218 needSep = true; 13219 } 13220 13221 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13222 13223 pw.println(); 13224 pw.println(" mHomeProcess: " + mHomeProcess); 13225 pw.println(" mPreviousProcess: " + mPreviousProcess); 13226 if (mHeavyWeightProcess != null) { 13227 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13228 } 13229 13230 return true; 13231 } 13232 13233 /** 13234 * There are three ways to call this: 13235 * - no provider specified: dump all the providers 13236 * - a flattened component name that matched an existing provider was specified as the 13237 * first arg: dump that one provider 13238 * - the first arg isn't the flattened component name of an existing provider: 13239 * dump all providers whose component contains the first arg as a substring 13240 */ 13241 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13242 int opti, boolean dumpAll) { 13243 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13244 } 13245 13246 static class ItemMatcher { 13247 ArrayList<ComponentName> components; 13248 ArrayList<String> strings; 13249 ArrayList<Integer> objects; 13250 boolean all; 13251 13252 ItemMatcher() { 13253 all = true; 13254 } 13255 13256 void build(String name) { 13257 ComponentName componentName = ComponentName.unflattenFromString(name); 13258 if (componentName != null) { 13259 if (components == null) { 13260 components = new ArrayList<ComponentName>(); 13261 } 13262 components.add(componentName); 13263 all = false; 13264 } else { 13265 int objectId = 0; 13266 // Not a '/' separated full component name; maybe an object ID? 13267 try { 13268 objectId = Integer.parseInt(name, 16); 13269 if (objects == null) { 13270 objects = new ArrayList<Integer>(); 13271 } 13272 objects.add(objectId); 13273 all = false; 13274 } catch (RuntimeException e) { 13275 // Not an integer; just do string match. 13276 if (strings == null) { 13277 strings = new ArrayList<String>(); 13278 } 13279 strings.add(name); 13280 all = false; 13281 } 13282 } 13283 } 13284 13285 int build(String[] args, int opti) { 13286 for (; opti<args.length; opti++) { 13287 String name = args[opti]; 13288 if ("--".equals(name)) { 13289 return opti+1; 13290 } 13291 build(name); 13292 } 13293 return opti; 13294 } 13295 13296 boolean match(Object object, ComponentName comp) { 13297 if (all) { 13298 return true; 13299 } 13300 if (components != null) { 13301 for (int i=0; i<components.size(); i++) { 13302 if (components.get(i).equals(comp)) { 13303 return true; 13304 } 13305 } 13306 } 13307 if (objects != null) { 13308 for (int i=0; i<objects.size(); i++) { 13309 if (System.identityHashCode(object) == objects.get(i)) { 13310 return true; 13311 } 13312 } 13313 } 13314 if (strings != null) { 13315 String flat = comp.flattenToString(); 13316 for (int i=0; i<strings.size(); i++) { 13317 if (flat.contains(strings.get(i))) { 13318 return true; 13319 } 13320 } 13321 } 13322 return false; 13323 } 13324 } 13325 13326 /** 13327 * There are three things that cmd can be: 13328 * - a flattened component name that matches an existing activity 13329 * - the cmd arg isn't the flattened component name of an existing activity: 13330 * dump all activity whose component contains the cmd as a substring 13331 * - A hex number of the ActivityRecord object instance. 13332 */ 13333 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13334 int opti, boolean dumpAll) { 13335 ArrayList<ActivityRecord> activities; 13336 13337 synchronized (this) { 13338 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13339 } 13340 13341 if (activities.size() <= 0) { 13342 return false; 13343 } 13344 13345 String[] newArgs = new String[args.length - opti]; 13346 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13347 13348 TaskRecord lastTask = null; 13349 boolean needSep = false; 13350 for (int i=activities.size()-1; i>=0; i--) { 13351 ActivityRecord r = activities.get(i); 13352 if (needSep) { 13353 pw.println(); 13354 } 13355 needSep = true; 13356 synchronized (this) { 13357 if (lastTask != r.task) { 13358 lastTask = r.task; 13359 pw.print("TASK "); pw.print(lastTask.affinity); 13360 pw.print(" id="); pw.println(lastTask.taskId); 13361 if (dumpAll) { 13362 lastTask.dump(pw, " "); 13363 } 13364 } 13365 } 13366 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13367 } 13368 return true; 13369 } 13370 13371 /** 13372 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13373 * there is a thread associated with the activity. 13374 */ 13375 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13376 final ActivityRecord r, String[] args, boolean dumpAll) { 13377 String innerPrefix = prefix + " "; 13378 synchronized (this) { 13379 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13380 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13381 pw.print(" pid="); 13382 if (r.app != null) pw.println(r.app.pid); 13383 else pw.println("(not running)"); 13384 if (dumpAll) { 13385 r.dump(pw, innerPrefix); 13386 } 13387 } 13388 if (r.app != null && r.app.thread != null) { 13389 // flush anything that is already in the PrintWriter since the thread is going 13390 // to write to the file descriptor directly 13391 pw.flush(); 13392 try { 13393 TransferPipe tp = new TransferPipe(); 13394 try { 13395 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13396 r.appToken, innerPrefix, args); 13397 tp.go(fd); 13398 } finally { 13399 tp.kill(); 13400 } 13401 } catch (IOException e) { 13402 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13403 } catch (RemoteException e) { 13404 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13405 } 13406 } 13407 } 13408 13409 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13410 int opti, boolean dumpAll, String dumpPackage) { 13411 boolean needSep = false; 13412 boolean onlyHistory = false; 13413 boolean printedAnything = false; 13414 13415 if ("history".equals(dumpPackage)) { 13416 if (opti < args.length && "-s".equals(args[opti])) { 13417 dumpAll = false; 13418 } 13419 onlyHistory = true; 13420 dumpPackage = null; 13421 } 13422 13423 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13424 if (!onlyHistory && dumpAll) { 13425 if (mRegisteredReceivers.size() > 0) { 13426 boolean printed = false; 13427 Iterator it = mRegisteredReceivers.values().iterator(); 13428 while (it.hasNext()) { 13429 ReceiverList r = (ReceiverList)it.next(); 13430 if (dumpPackage != null && (r.app == null || 13431 !dumpPackage.equals(r.app.info.packageName))) { 13432 continue; 13433 } 13434 if (!printed) { 13435 pw.println(" Registered Receivers:"); 13436 needSep = true; 13437 printed = true; 13438 printedAnything = true; 13439 } 13440 pw.print(" * "); pw.println(r); 13441 r.dump(pw, " "); 13442 } 13443 } 13444 13445 if (mReceiverResolver.dump(pw, needSep ? 13446 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13447 " ", dumpPackage, false, false)) { 13448 needSep = true; 13449 printedAnything = true; 13450 } 13451 } 13452 13453 for (BroadcastQueue q : mBroadcastQueues) { 13454 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13455 printedAnything |= needSep; 13456 } 13457 13458 needSep = true; 13459 13460 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13461 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13462 if (needSep) { 13463 pw.println(); 13464 } 13465 needSep = true; 13466 printedAnything = true; 13467 pw.print(" Sticky broadcasts for user "); 13468 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13469 StringBuilder sb = new StringBuilder(128); 13470 for (Map.Entry<String, ArrayList<Intent>> ent 13471 : mStickyBroadcasts.valueAt(user).entrySet()) { 13472 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13473 if (dumpAll) { 13474 pw.println(":"); 13475 ArrayList<Intent> intents = ent.getValue(); 13476 final int N = intents.size(); 13477 for (int i=0; i<N; i++) { 13478 sb.setLength(0); 13479 sb.append(" Intent: "); 13480 intents.get(i).toShortString(sb, false, true, false, false); 13481 pw.println(sb.toString()); 13482 Bundle bundle = intents.get(i).getExtras(); 13483 if (bundle != null) { 13484 pw.print(" "); 13485 pw.println(bundle.toString()); 13486 } 13487 } 13488 } else { 13489 pw.println(""); 13490 } 13491 } 13492 } 13493 } 13494 13495 if (!onlyHistory && dumpAll) { 13496 pw.println(); 13497 for (BroadcastQueue queue : mBroadcastQueues) { 13498 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13499 + queue.mBroadcastsScheduled); 13500 } 13501 pw.println(" mHandler:"); 13502 mHandler.dump(new PrintWriterPrinter(pw), " "); 13503 needSep = true; 13504 printedAnything = true; 13505 } 13506 13507 if (!printedAnything) { 13508 pw.println(" (nothing)"); 13509 } 13510 } 13511 13512 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13513 int opti, boolean dumpAll, String dumpPackage) { 13514 boolean needSep; 13515 boolean printedAnything = false; 13516 13517 ItemMatcher matcher = new ItemMatcher(); 13518 matcher.build(args, opti); 13519 13520 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13521 13522 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13523 printedAnything |= needSep; 13524 13525 if (mLaunchingProviders.size() > 0) { 13526 boolean printed = false; 13527 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13528 ContentProviderRecord r = mLaunchingProviders.get(i); 13529 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13530 continue; 13531 } 13532 if (!printed) { 13533 if (needSep) pw.println(); 13534 needSep = true; 13535 pw.println(" Launching content providers:"); 13536 printed = true; 13537 printedAnything = true; 13538 } 13539 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13540 pw.println(r); 13541 } 13542 } 13543 13544 if (mGrantedUriPermissions.size() > 0) { 13545 boolean printed = false; 13546 int dumpUid = -2; 13547 if (dumpPackage != null) { 13548 try { 13549 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13550 } catch (NameNotFoundException e) { 13551 dumpUid = -1; 13552 } 13553 } 13554 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13555 int uid = mGrantedUriPermissions.keyAt(i); 13556 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13557 continue; 13558 } 13559 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13560 if (!printed) { 13561 if (needSep) pw.println(); 13562 needSep = true; 13563 pw.println(" Granted Uri Permissions:"); 13564 printed = true; 13565 printedAnything = true; 13566 } 13567 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13568 for (UriPermission perm : perms.values()) { 13569 pw.print(" "); pw.println(perm); 13570 if (dumpAll) { 13571 perm.dump(pw, " "); 13572 } 13573 } 13574 } 13575 } 13576 13577 if (!printedAnything) { 13578 pw.println(" (nothing)"); 13579 } 13580 } 13581 13582 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13583 int opti, boolean dumpAll, String dumpPackage) { 13584 boolean printed = false; 13585 13586 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13587 13588 if (mIntentSenderRecords.size() > 0) { 13589 Iterator<WeakReference<PendingIntentRecord>> it 13590 = mIntentSenderRecords.values().iterator(); 13591 while (it.hasNext()) { 13592 WeakReference<PendingIntentRecord> ref = it.next(); 13593 PendingIntentRecord rec = ref != null ? ref.get(): null; 13594 if (dumpPackage != null && (rec == null 13595 || !dumpPackage.equals(rec.key.packageName))) { 13596 continue; 13597 } 13598 printed = true; 13599 if (rec != null) { 13600 pw.print(" * "); pw.println(rec); 13601 if (dumpAll) { 13602 rec.dump(pw, " "); 13603 } 13604 } else { 13605 pw.print(" * "); pw.println(ref); 13606 } 13607 } 13608 } 13609 13610 if (!printed) { 13611 pw.println(" (nothing)"); 13612 } 13613 } 13614 13615 private static final int dumpProcessList(PrintWriter pw, 13616 ActivityManagerService service, List list, 13617 String prefix, String normalLabel, String persistentLabel, 13618 String dumpPackage) { 13619 int numPers = 0; 13620 final int N = list.size()-1; 13621 for (int i=N; i>=0; i--) { 13622 ProcessRecord r = (ProcessRecord)list.get(i); 13623 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13624 continue; 13625 } 13626 pw.println(String.format("%s%s #%2d: %s", 13627 prefix, (r.persistent ? persistentLabel : normalLabel), 13628 i, r.toString())); 13629 if (r.persistent) { 13630 numPers++; 13631 } 13632 } 13633 return numPers; 13634 } 13635 13636 private static final boolean dumpProcessOomList(PrintWriter pw, 13637 ActivityManagerService service, List<ProcessRecord> origList, 13638 String prefix, String normalLabel, String persistentLabel, 13639 boolean inclDetails, String dumpPackage) { 13640 13641 ArrayList<Pair<ProcessRecord, Integer>> list 13642 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13643 for (int i=0; i<origList.size(); i++) { 13644 ProcessRecord r = origList.get(i); 13645 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13646 continue; 13647 } 13648 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13649 } 13650 13651 if (list.size() <= 0) { 13652 return false; 13653 } 13654 13655 Comparator<Pair<ProcessRecord, Integer>> comparator 13656 = new Comparator<Pair<ProcessRecord, Integer>>() { 13657 @Override 13658 public int compare(Pair<ProcessRecord, Integer> object1, 13659 Pair<ProcessRecord, Integer> object2) { 13660 if (object1.first.setAdj != object2.first.setAdj) { 13661 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13662 } 13663 if (object1.second.intValue() != object2.second.intValue()) { 13664 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13665 } 13666 return 0; 13667 } 13668 }; 13669 13670 Collections.sort(list, comparator); 13671 13672 final long curRealtime = SystemClock.elapsedRealtime(); 13673 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13674 final long curUptime = SystemClock.uptimeMillis(); 13675 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13676 13677 for (int i=list.size()-1; i>=0; i--) { 13678 ProcessRecord r = list.get(i).first; 13679 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13680 char schedGroup; 13681 switch (r.setSchedGroup) { 13682 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13683 schedGroup = 'B'; 13684 break; 13685 case Process.THREAD_GROUP_DEFAULT: 13686 schedGroup = 'F'; 13687 break; 13688 default: 13689 schedGroup = '?'; 13690 break; 13691 } 13692 char foreground; 13693 if (r.foregroundActivities) { 13694 foreground = 'A'; 13695 } else if (r.foregroundServices) { 13696 foreground = 'S'; 13697 } else { 13698 foreground = ' '; 13699 } 13700 String procState = ProcessList.makeProcStateString(r.curProcState); 13701 pw.print(prefix); 13702 pw.print(r.persistent ? persistentLabel : normalLabel); 13703 pw.print(" #"); 13704 int num = (origList.size()-1)-list.get(i).second; 13705 if (num < 10) pw.print(' '); 13706 pw.print(num); 13707 pw.print(": "); 13708 pw.print(oomAdj); 13709 pw.print(' '); 13710 pw.print(schedGroup); 13711 pw.print('/'); 13712 pw.print(foreground); 13713 pw.print('/'); 13714 pw.print(procState); 13715 pw.print(" trm:"); 13716 if (r.trimMemoryLevel < 10) pw.print(' '); 13717 pw.print(r.trimMemoryLevel); 13718 pw.print(' '); 13719 pw.print(r.toShortString()); 13720 pw.print(" ("); 13721 pw.print(r.adjType); 13722 pw.println(')'); 13723 if (r.adjSource != null || r.adjTarget != null) { 13724 pw.print(prefix); 13725 pw.print(" "); 13726 if (r.adjTarget instanceof ComponentName) { 13727 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13728 } else if (r.adjTarget != null) { 13729 pw.print(r.adjTarget.toString()); 13730 } else { 13731 pw.print("{null}"); 13732 } 13733 pw.print("<="); 13734 if (r.adjSource instanceof ProcessRecord) { 13735 pw.print("Proc{"); 13736 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13737 pw.println("}"); 13738 } else if (r.adjSource != null) { 13739 pw.println(r.adjSource.toString()); 13740 } else { 13741 pw.println("{null}"); 13742 } 13743 } 13744 if (inclDetails) { 13745 pw.print(prefix); 13746 pw.print(" "); 13747 pw.print("oom: max="); pw.print(r.maxAdj); 13748 pw.print(" curRaw="); pw.print(r.curRawAdj); 13749 pw.print(" setRaw="); pw.print(r.setRawAdj); 13750 pw.print(" cur="); pw.print(r.curAdj); 13751 pw.print(" set="); pw.println(r.setAdj); 13752 pw.print(prefix); 13753 pw.print(" "); 13754 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13755 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13756 pw.print(" lastPss="); pw.print(r.lastPss); 13757 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13758 pw.print(prefix); 13759 pw.print(" "); 13760 pw.print("cached="); pw.print(r.cached); 13761 pw.print(" empty="); pw.print(r.empty); 13762 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13763 13764 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13765 if (r.lastWakeTime != 0) { 13766 long wtime; 13767 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13768 synchronized (stats) { 13769 wtime = stats.getProcessWakeTime(r.info.uid, 13770 r.pid, curRealtime); 13771 } 13772 long timeUsed = wtime - r.lastWakeTime; 13773 pw.print(prefix); 13774 pw.print(" "); 13775 pw.print("keep awake over "); 13776 TimeUtils.formatDuration(realtimeSince, pw); 13777 pw.print(" used "); 13778 TimeUtils.formatDuration(timeUsed, pw); 13779 pw.print(" ("); 13780 pw.print((timeUsed*100)/realtimeSince); 13781 pw.println("%)"); 13782 } 13783 if (r.lastCpuTime != 0) { 13784 long timeUsed = r.curCpuTime - r.lastCpuTime; 13785 pw.print(prefix); 13786 pw.print(" "); 13787 pw.print("run cpu over "); 13788 TimeUtils.formatDuration(uptimeSince, pw); 13789 pw.print(" used "); 13790 TimeUtils.formatDuration(timeUsed, pw); 13791 pw.print(" ("); 13792 pw.print((timeUsed*100)/uptimeSince); 13793 pw.println("%)"); 13794 } 13795 } 13796 } 13797 } 13798 return true; 13799 } 13800 13801 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13802 String[] args) { 13803 ArrayList<ProcessRecord> procs; 13804 synchronized (this) { 13805 if (args != null && args.length > start 13806 && args[start].charAt(0) != '-') { 13807 procs = new ArrayList<ProcessRecord>(); 13808 int pid = -1; 13809 try { 13810 pid = Integer.parseInt(args[start]); 13811 } catch (NumberFormatException e) { 13812 } 13813 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13814 ProcessRecord proc = mLruProcesses.get(i); 13815 if (proc.pid == pid) { 13816 procs.add(proc); 13817 } else if (allPkgs && proc.pkgList != null 13818 && proc.pkgList.containsKey(args[start])) { 13819 procs.add(proc); 13820 } else if (proc.processName.equals(args[start])) { 13821 procs.add(proc); 13822 } 13823 } 13824 if (procs.size() <= 0) { 13825 return null; 13826 } 13827 } else { 13828 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13829 } 13830 } 13831 return procs; 13832 } 13833 13834 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13835 PrintWriter pw, String[] args) { 13836 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13837 if (procs == null) { 13838 pw.println("No process found for: " + args[0]); 13839 return; 13840 } 13841 13842 long uptime = SystemClock.uptimeMillis(); 13843 long realtime = SystemClock.elapsedRealtime(); 13844 pw.println("Applications Graphics Acceleration Info:"); 13845 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13846 13847 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13848 ProcessRecord r = procs.get(i); 13849 if (r.thread != null) { 13850 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13851 pw.flush(); 13852 try { 13853 TransferPipe tp = new TransferPipe(); 13854 try { 13855 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13856 tp.go(fd); 13857 } finally { 13858 tp.kill(); 13859 } 13860 } catch (IOException e) { 13861 pw.println("Failure while dumping the app: " + r); 13862 pw.flush(); 13863 } catch (RemoteException e) { 13864 pw.println("Got a RemoteException while dumping the app " + r); 13865 pw.flush(); 13866 } 13867 } 13868 } 13869 } 13870 13871 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13872 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13873 if (procs == null) { 13874 pw.println("No process found for: " + args[0]); 13875 return; 13876 } 13877 13878 pw.println("Applications Database Info:"); 13879 13880 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13881 ProcessRecord r = procs.get(i); 13882 if (r.thread != null) { 13883 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13884 pw.flush(); 13885 try { 13886 TransferPipe tp = new TransferPipe(); 13887 try { 13888 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13889 tp.go(fd); 13890 } finally { 13891 tp.kill(); 13892 } 13893 } catch (IOException e) { 13894 pw.println("Failure while dumping the app: " + r); 13895 pw.flush(); 13896 } catch (RemoteException e) { 13897 pw.println("Got a RemoteException while dumping the app " + r); 13898 pw.flush(); 13899 } 13900 } 13901 } 13902 } 13903 13904 final static class MemItem { 13905 final boolean isProc; 13906 final String label; 13907 final String shortLabel; 13908 final long pss; 13909 final int id; 13910 final boolean hasActivities; 13911 ArrayList<MemItem> subitems; 13912 13913 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13914 boolean _hasActivities) { 13915 isProc = true; 13916 label = _label; 13917 shortLabel = _shortLabel; 13918 pss = _pss; 13919 id = _id; 13920 hasActivities = _hasActivities; 13921 } 13922 13923 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13924 isProc = false; 13925 label = _label; 13926 shortLabel = _shortLabel; 13927 pss = _pss; 13928 id = _id; 13929 hasActivities = false; 13930 } 13931 } 13932 13933 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13934 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13935 if (sort && !isCompact) { 13936 Collections.sort(items, new Comparator<MemItem>() { 13937 @Override 13938 public int compare(MemItem lhs, MemItem rhs) { 13939 if (lhs.pss < rhs.pss) { 13940 return 1; 13941 } else if (lhs.pss > rhs.pss) { 13942 return -1; 13943 } 13944 return 0; 13945 } 13946 }); 13947 } 13948 13949 for (int i=0; i<items.size(); i++) { 13950 MemItem mi = items.get(i); 13951 if (!isCompact) { 13952 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13953 } else if (mi.isProc) { 13954 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13955 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13956 pw.println(mi.hasActivities ? ",a" : ",e"); 13957 } else { 13958 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13959 pw.println(mi.pss); 13960 } 13961 if (mi.subitems != null) { 13962 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13963 true, isCompact); 13964 } 13965 } 13966 } 13967 13968 // These are in KB. 13969 static final long[] DUMP_MEM_BUCKETS = new long[] { 13970 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13971 120*1024, 160*1024, 200*1024, 13972 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13973 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13974 }; 13975 13976 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13977 boolean stackLike) { 13978 int start = label.lastIndexOf('.'); 13979 if (start >= 0) start++; 13980 else start = 0; 13981 int end = label.length(); 13982 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13983 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13984 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13985 out.append(bucket); 13986 out.append(stackLike ? "MB." : "MB "); 13987 out.append(label, start, end); 13988 return; 13989 } 13990 } 13991 out.append(memKB/1024); 13992 out.append(stackLike ? "MB." : "MB "); 13993 out.append(label, start, end); 13994 } 13995 13996 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13997 ProcessList.NATIVE_ADJ, 13998 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13999 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14000 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14001 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14002 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14003 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14004 }; 14005 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14006 "Native", 14007 "System", "Persistent", "Persistent Service", "Foreground", 14008 "Visible", "Perceptible", 14009 "Heavy Weight", "Backup", 14010 "A Services", "Home", 14011 "Previous", "B Services", "Cached" 14012 }; 14013 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14014 "native", 14015 "sys", "pers", "persvc", "fore", 14016 "vis", "percept", 14017 "heavy", "backup", 14018 "servicea", "home", 14019 "prev", "serviceb", "cached" 14020 }; 14021 14022 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14023 long realtime, boolean isCheckinRequest, boolean isCompact) { 14024 if (isCheckinRequest || isCompact) { 14025 // short checkin version 14026 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14027 } else { 14028 pw.println("Applications Memory Usage (kB):"); 14029 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14030 } 14031 } 14032 14033 private static final int KSM_SHARED = 0; 14034 private static final int KSM_SHARING = 1; 14035 private static final int KSM_UNSHARED = 2; 14036 private static final int KSM_VOLATILE = 3; 14037 14038 private final long[] getKsmInfo() { 14039 long[] longOut = new long[4]; 14040 final int[] SINGLE_LONG_FORMAT = new int[] { 14041 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14042 }; 14043 long[] longTmp = new long[1]; 14044 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14045 SINGLE_LONG_FORMAT, null, longTmp, null); 14046 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14047 longTmp[0] = 0; 14048 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14049 SINGLE_LONG_FORMAT, null, longTmp, null); 14050 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14051 longTmp[0] = 0; 14052 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14053 SINGLE_LONG_FORMAT, null, longTmp, null); 14054 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14055 longTmp[0] = 0; 14056 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14057 SINGLE_LONG_FORMAT, null, longTmp, null); 14058 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14059 return longOut; 14060 } 14061 14062 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14063 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14064 boolean dumpDetails = false; 14065 boolean dumpFullDetails = false; 14066 boolean dumpDalvik = false; 14067 boolean oomOnly = false; 14068 boolean isCompact = false; 14069 boolean localOnly = false; 14070 boolean packages = false; 14071 14072 int opti = 0; 14073 while (opti < args.length) { 14074 String opt = args[opti]; 14075 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14076 break; 14077 } 14078 opti++; 14079 if ("-a".equals(opt)) { 14080 dumpDetails = true; 14081 dumpFullDetails = true; 14082 dumpDalvik = true; 14083 } else if ("-d".equals(opt)) { 14084 dumpDalvik = true; 14085 } else if ("-c".equals(opt)) { 14086 isCompact = true; 14087 } else if ("--oom".equals(opt)) { 14088 oomOnly = true; 14089 } else if ("--local".equals(opt)) { 14090 localOnly = true; 14091 } else if ("--package".equals(opt)) { 14092 packages = true; 14093 } else if ("-h".equals(opt)) { 14094 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14095 pw.println(" -a: include all available information for each process."); 14096 pw.println(" -d: include dalvik details when dumping process details."); 14097 pw.println(" -c: dump in a compact machine-parseable representation."); 14098 pw.println(" --oom: only show processes organized by oom adj."); 14099 pw.println(" --local: only collect details locally, don't call process."); 14100 pw.println(" --package: interpret process arg as package, dumping all"); 14101 pw.println(" processes that have loaded that package."); 14102 pw.println("If [process] is specified it can be the name or "); 14103 pw.println("pid of a specific process to dump."); 14104 return; 14105 } else { 14106 pw.println("Unknown argument: " + opt + "; use -h for help"); 14107 } 14108 } 14109 14110 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14111 long uptime = SystemClock.uptimeMillis(); 14112 long realtime = SystemClock.elapsedRealtime(); 14113 final long[] tmpLong = new long[1]; 14114 14115 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14116 if (procs == null) { 14117 // No Java processes. Maybe they want to print a native process. 14118 if (args != null && args.length > opti 14119 && args[opti].charAt(0) != '-') { 14120 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14121 = new ArrayList<ProcessCpuTracker.Stats>(); 14122 updateCpuStatsNow(); 14123 int findPid = -1; 14124 try { 14125 findPid = Integer.parseInt(args[opti]); 14126 } catch (NumberFormatException e) { 14127 } 14128 synchronized (mProcessCpuTracker) { 14129 final int N = mProcessCpuTracker.countStats(); 14130 for (int i=0; i<N; i++) { 14131 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14132 if (st.pid == findPid || (st.baseName != null 14133 && st.baseName.equals(args[opti]))) { 14134 nativeProcs.add(st); 14135 } 14136 } 14137 } 14138 if (nativeProcs.size() > 0) { 14139 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14140 isCompact); 14141 Debug.MemoryInfo mi = null; 14142 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14143 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14144 final int pid = r.pid; 14145 if (!isCheckinRequest && dumpDetails) { 14146 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14147 } 14148 if (mi == null) { 14149 mi = new Debug.MemoryInfo(); 14150 } 14151 if (dumpDetails || (!brief && !oomOnly)) { 14152 Debug.getMemoryInfo(pid, mi); 14153 } else { 14154 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14155 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14156 } 14157 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14158 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14159 if (isCheckinRequest) { 14160 pw.println(); 14161 } 14162 } 14163 return; 14164 } 14165 } 14166 pw.println("No process found for: " + args[opti]); 14167 return; 14168 } 14169 14170 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14171 dumpDetails = true; 14172 } 14173 14174 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14175 14176 String[] innerArgs = new String[args.length-opti]; 14177 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14178 14179 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14180 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14181 long nativePss = 0; 14182 long dalvikPss = 0; 14183 long otherPss = 0; 14184 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14185 14186 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14187 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14188 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14189 14190 long totalPss = 0; 14191 long cachedPss = 0; 14192 14193 Debug.MemoryInfo mi = null; 14194 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14195 final ProcessRecord r = procs.get(i); 14196 final IApplicationThread thread; 14197 final int pid; 14198 final int oomAdj; 14199 final boolean hasActivities; 14200 synchronized (this) { 14201 thread = r.thread; 14202 pid = r.pid; 14203 oomAdj = r.getSetAdjWithServices(); 14204 hasActivities = r.activities.size() > 0; 14205 } 14206 if (thread != null) { 14207 if (!isCheckinRequest && dumpDetails) { 14208 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14209 } 14210 if (mi == null) { 14211 mi = new Debug.MemoryInfo(); 14212 } 14213 if (dumpDetails || (!brief && !oomOnly)) { 14214 Debug.getMemoryInfo(pid, mi); 14215 } else { 14216 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14217 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14218 } 14219 if (dumpDetails) { 14220 if (localOnly) { 14221 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14222 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14223 if (isCheckinRequest) { 14224 pw.println(); 14225 } 14226 } else { 14227 try { 14228 pw.flush(); 14229 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14230 dumpDalvik, innerArgs); 14231 } catch (RemoteException e) { 14232 if (!isCheckinRequest) { 14233 pw.println("Got RemoteException!"); 14234 pw.flush(); 14235 } 14236 } 14237 } 14238 } 14239 14240 final long myTotalPss = mi.getTotalPss(); 14241 final long myTotalUss = mi.getTotalUss(); 14242 14243 synchronized (this) { 14244 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14245 // Record this for posterity if the process has been stable. 14246 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14247 } 14248 } 14249 14250 if (!isCheckinRequest && mi != null) { 14251 totalPss += myTotalPss; 14252 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14253 (hasActivities ? " / activities)" : ")"), 14254 r.processName, myTotalPss, pid, hasActivities); 14255 procMems.add(pssItem); 14256 procMemsMap.put(pid, pssItem); 14257 14258 nativePss += mi.nativePss; 14259 dalvikPss += mi.dalvikPss; 14260 otherPss += mi.otherPss; 14261 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14262 long mem = mi.getOtherPss(j); 14263 miscPss[j] += mem; 14264 otherPss -= mem; 14265 } 14266 14267 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14268 cachedPss += myTotalPss; 14269 } 14270 14271 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14272 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14273 || oomIndex == (oomPss.length-1)) { 14274 oomPss[oomIndex] += myTotalPss; 14275 if (oomProcs[oomIndex] == null) { 14276 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14277 } 14278 oomProcs[oomIndex].add(pssItem); 14279 break; 14280 } 14281 } 14282 } 14283 } 14284 } 14285 14286 long nativeProcTotalPss = 0; 14287 14288 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14289 // If we are showing aggregations, also look for native processes to 14290 // include so that our aggregations are more accurate. 14291 updateCpuStatsNow(); 14292 mi = null; 14293 synchronized (mProcessCpuTracker) { 14294 final int N = mProcessCpuTracker.countStats(); 14295 for (int i=0; i<N; i++) { 14296 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14297 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14298 if (mi == null) { 14299 mi = new Debug.MemoryInfo(); 14300 } 14301 if (!brief && !oomOnly) { 14302 Debug.getMemoryInfo(st.pid, mi); 14303 } else { 14304 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14305 mi.nativePrivateDirty = (int)tmpLong[0]; 14306 } 14307 14308 final long myTotalPss = mi.getTotalPss(); 14309 totalPss += myTotalPss; 14310 nativeProcTotalPss += myTotalPss; 14311 14312 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14313 st.name, myTotalPss, st.pid, false); 14314 procMems.add(pssItem); 14315 14316 nativePss += mi.nativePss; 14317 dalvikPss += mi.dalvikPss; 14318 otherPss += mi.otherPss; 14319 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14320 long mem = mi.getOtherPss(j); 14321 miscPss[j] += mem; 14322 otherPss -= mem; 14323 } 14324 oomPss[0] += myTotalPss; 14325 if (oomProcs[0] == null) { 14326 oomProcs[0] = new ArrayList<MemItem>(); 14327 } 14328 oomProcs[0].add(pssItem); 14329 } 14330 } 14331 } 14332 14333 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14334 14335 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14336 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14337 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14338 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14339 String label = Debug.MemoryInfo.getOtherLabel(j); 14340 catMems.add(new MemItem(label, label, miscPss[j], j)); 14341 } 14342 14343 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14344 for (int j=0; j<oomPss.length; j++) { 14345 if (oomPss[j] != 0) { 14346 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14347 : DUMP_MEM_OOM_LABEL[j]; 14348 MemItem item = new MemItem(label, label, oomPss[j], 14349 DUMP_MEM_OOM_ADJ[j]); 14350 item.subitems = oomProcs[j]; 14351 oomMems.add(item); 14352 } 14353 } 14354 14355 if (!brief && !oomOnly && !isCompact) { 14356 pw.println(); 14357 pw.println("Total PSS by process:"); 14358 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14359 pw.println(); 14360 } 14361 if (!isCompact) { 14362 pw.println("Total PSS by OOM adjustment:"); 14363 } 14364 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14365 if (!brief && !oomOnly) { 14366 PrintWriter out = categoryPw != null ? categoryPw : pw; 14367 if (!isCompact) { 14368 out.println(); 14369 out.println("Total PSS by category:"); 14370 } 14371 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14372 } 14373 if (!isCompact) { 14374 pw.println(); 14375 } 14376 MemInfoReader memInfo = new MemInfoReader(); 14377 memInfo.readMemInfo(); 14378 if (nativeProcTotalPss > 0) { 14379 synchronized (this) { 14380 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14381 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14382 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14383 } 14384 } 14385 if (!brief) { 14386 if (!isCompact) { 14387 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14388 pw.print(" kB (status "); 14389 switch (mLastMemoryLevel) { 14390 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14391 pw.println("normal)"); 14392 break; 14393 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14394 pw.println("moderate)"); 14395 break; 14396 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14397 pw.println("low)"); 14398 break; 14399 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14400 pw.println("critical)"); 14401 break; 14402 default: 14403 pw.print(mLastMemoryLevel); 14404 pw.println(")"); 14405 break; 14406 } 14407 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14408 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14409 pw.print(cachedPss); pw.print(" cached pss + "); 14410 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14411 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14412 } else { 14413 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14414 pw.print(cachedPss + memInfo.getCachedSizeKb() 14415 + memInfo.getFreeSizeKb()); pw.print(","); 14416 pw.println(totalPss - cachedPss); 14417 } 14418 } 14419 if (!isCompact) { 14420 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14421 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14422 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14423 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14424 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14425 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14426 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14427 } 14428 if (!brief) { 14429 if (memInfo.getZramTotalSizeKb() != 0) { 14430 if (!isCompact) { 14431 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14432 pw.print(" kB physical used for "); 14433 pw.print(memInfo.getSwapTotalSizeKb() 14434 - memInfo.getSwapFreeSizeKb()); 14435 pw.print(" kB in swap ("); 14436 pw.print(memInfo.getSwapTotalSizeKb()); 14437 pw.println(" kB total swap)"); 14438 } else { 14439 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14440 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14441 pw.println(memInfo.getSwapFreeSizeKb()); 14442 } 14443 } 14444 final long[] ksm = getKsmInfo(); 14445 if (!isCompact) { 14446 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14447 || ksm[KSM_VOLATILE] != 0) { 14448 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14449 pw.print(" kB saved from shared "); 14450 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14451 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14452 pw.print(" kB unshared; "); 14453 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14454 } 14455 pw.print(" Tuning: "); 14456 pw.print(ActivityManager.staticGetMemoryClass()); 14457 pw.print(" (large "); 14458 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14459 pw.print("), oom "); 14460 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14461 pw.print(" kB"); 14462 pw.print(", restore limit "); 14463 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14464 pw.print(" kB"); 14465 if (ActivityManager.isLowRamDeviceStatic()) { 14466 pw.print(" (low-ram)"); 14467 } 14468 if (ActivityManager.isHighEndGfx()) { 14469 pw.print(" (high-end-gfx)"); 14470 } 14471 pw.println(); 14472 } else { 14473 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14474 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14475 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14476 pw.print("tuning,"); 14477 pw.print(ActivityManager.staticGetMemoryClass()); 14478 pw.print(','); 14479 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14480 pw.print(','); 14481 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14482 if (ActivityManager.isLowRamDeviceStatic()) { 14483 pw.print(",low-ram"); 14484 } 14485 if (ActivityManager.isHighEndGfx()) { 14486 pw.print(",high-end-gfx"); 14487 } 14488 pw.println(); 14489 } 14490 } 14491 } 14492 } 14493 14494 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14495 long memtrack, String name) { 14496 sb.append(" "); 14497 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14498 sb.append(' '); 14499 sb.append(ProcessList.makeProcStateString(procState)); 14500 sb.append(' '); 14501 ProcessList.appendRamKb(sb, pss); 14502 sb.append(" kB: "); 14503 sb.append(name); 14504 if (memtrack > 0) { 14505 sb.append(" ("); 14506 sb.append(memtrack); 14507 sb.append(" kB memtrack)"); 14508 } 14509 } 14510 14511 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14512 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14513 sb.append(" (pid "); 14514 sb.append(mi.pid); 14515 sb.append(") "); 14516 sb.append(mi.adjType); 14517 sb.append('\n'); 14518 if (mi.adjReason != null) { 14519 sb.append(" "); 14520 sb.append(mi.adjReason); 14521 sb.append('\n'); 14522 } 14523 } 14524 14525 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14526 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14527 for (int i=0, N=memInfos.size(); i<N; i++) { 14528 ProcessMemInfo mi = memInfos.get(i); 14529 infoMap.put(mi.pid, mi); 14530 } 14531 updateCpuStatsNow(); 14532 long[] memtrackTmp = new long[1]; 14533 synchronized (mProcessCpuTracker) { 14534 final int N = mProcessCpuTracker.countStats(); 14535 for (int i=0; i<N; i++) { 14536 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14537 if (st.vsize > 0) { 14538 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14539 if (pss > 0) { 14540 if (infoMap.indexOfKey(st.pid) < 0) { 14541 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14542 ProcessList.NATIVE_ADJ, -1, "native", null); 14543 mi.pss = pss; 14544 mi.memtrack = memtrackTmp[0]; 14545 memInfos.add(mi); 14546 } 14547 } 14548 } 14549 } 14550 } 14551 14552 long totalPss = 0; 14553 long totalMemtrack = 0; 14554 for (int i=0, N=memInfos.size(); i<N; i++) { 14555 ProcessMemInfo mi = memInfos.get(i); 14556 if (mi.pss == 0) { 14557 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14558 mi.memtrack = memtrackTmp[0]; 14559 } 14560 totalPss += mi.pss; 14561 totalMemtrack += mi.memtrack; 14562 } 14563 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14564 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14565 if (lhs.oomAdj != rhs.oomAdj) { 14566 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14567 } 14568 if (lhs.pss != rhs.pss) { 14569 return lhs.pss < rhs.pss ? 1 : -1; 14570 } 14571 return 0; 14572 } 14573 }); 14574 14575 StringBuilder tag = new StringBuilder(128); 14576 StringBuilder stack = new StringBuilder(128); 14577 tag.append("Low on memory -- "); 14578 appendMemBucket(tag, totalPss, "total", false); 14579 appendMemBucket(stack, totalPss, "total", true); 14580 14581 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14582 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14583 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14584 14585 boolean firstLine = true; 14586 int lastOomAdj = Integer.MIN_VALUE; 14587 long extraNativeRam = 0; 14588 long extraNativeMemtrack = 0; 14589 long cachedPss = 0; 14590 for (int i=0, N=memInfos.size(); i<N; i++) { 14591 ProcessMemInfo mi = memInfos.get(i); 14592 14593 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14594 cachedPss += mi.pss; 14595 } 14596 14597 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14598 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14599 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14600 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14601 if (lastOomAdj != mi.oomAdj) { 14602 lastOomAdj = mi.oomAdj; 14603 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14604 tag.append(" / "); 14605 } 14606 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14607 if (firstLine) { 14608 stack.append(":"); 14609 firstLine = false; 14610 } 14611 stack.append("\n\t at "); 14612 } else { 14613 stack.append("$"); 14614 } 14615 } else { 14616 tag.append(" "); 14617 stack.append("$"); 14618 } 14619 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14620 appendMemBucket(tag, mi.pss, mi.name, false); 14621 } 14622 appendMemBucket(stack, mi.pss, mi.name, true); 14623 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14624 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14625 stack.append("("); 14626 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14627 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14628 stack.append(DUMP_MEM_OOM_LABEL[k]); 14629 stack.append(":"); 14630 stack.append(DUMP_MEM_OOM_ADJ[k]); 14631 } 14632 } 14633 stack.append(")"); 14634 } 14635 } 14636 14637 appendMemInfo(fullNativeBuilder, mi); 14638 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14639 // The short form only has native processes that are >= 512K. 14640 if (mi.pss >= 512) { 14641 appendMemInfo(shortNativeBuilder, mi); 14642 } else { 14643 extraNativeRam += mi.pss; 14644 extraNativeMemtrack += mi.memtrack; 14645 } 14646 } else { 14647 // Short form has all other details, but if we have collected RAM 14648 // from smaller native processes let's dump a summary of that. 14649 if (extraNativeRam > 0) { 14650 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14651 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14652 shortNativeBuilder.append('\n'); 14653 extraNativeRam = 0; 14654 } 14655 appendMemInfo(fullJavaBuilder, mi); 14656 } 14657 } 14658 14659 fullJavaBuilder.append(" "); 14660 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14661 fullJavaBuilder.append(" kB: TOTAL"); 14662 if (totalMemtrack > 0) { 14663 fullJavaBuilder.append(" ("); 14664 fullJavaBuilder.append(totalMemtrack); 14665 fullJavaBuilder.append(" kB memtrack)"); 14666 } else { 14667 } 14668 fullJavaBuilder.append("\n"); 14669 14670 MemInfoReader memInfo = new MemInfoReader(); 14671 memInfo.readMemInfo(); 14672 final long[] infos = memInfo.getRawInfo(); 14673 14674 StringBuilder memInfoBuilder = new StringBuilder(1024); 14675 Debug.getMemInfo(infos); 14676 memInfoBuilder.append(" MemInfo: "); 14677 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14678 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14679 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14680 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14681 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14682 memInfoBuilder.append(" "); 14683 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14684 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14685 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14686 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14687 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14688 memInfoBuilder.append(" ZRAM: "); 14689 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14690 memInfoBuilder.append(" kB RAM, "); 14691 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14692 memInfoBuilder.append(" kB swap total, "); 14693 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14694 memInfoBuilder.append(" kB swap free\n"); 14695 } 14696 final long[] ksm = getKsmInfo(); 14697 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14698 || ksm[KSM_VOLATILE] != 0) { 14699 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14700 memInfoBuilder.append(" kB saved from shared "); 14701 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14702 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14703 memInfoBuilder.append(" kB unshared; "); 14704 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14705 } 14706 memInfoBuilder.append(" Free RAM: "); 14707 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14708 + memInfo.getFreeSizeKb()); 14709 memInfoBuilder.append(" kB\n"); 14710 memInfoBuilder.append(" Used RAM: "); 14711 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14712 memInfoBuilder.append(" kB\n"); 14713 memInfoBuilder.append(" Lost RAM: "); 14714 memInfoBuilder.append(memInfo.getTotalSizeKb() 14715 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14716 - memInfo.getKernelUsedSizeKb()); 14717 memInfoBuilder.append(" kB\n"); 14718 Slog.i(TAG, "Low on memory:"); 14719 Slog.i(TAG, shortNativeBuilder.toString()); 14720 Slog.i(TAG, fullJavaBuilder.toString()); 14721 Slog.i(TAG, memInfoBuilder.toString()); 14722 14723 StringBuilder dropBuilder = new StringBuilder(1024); 14724 /* 14725 StringWriter oomSw = new StringWriter(); 14726 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14727 StringWriter catSw = new StringWriter(); 14728 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14729 String[] emptyArgs = new String[] { }; 14730 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14731 oomPw.flush(); 14732 String oomString = oomSw.toString(); 14733 */ 14734 dropBuilder.append("Low on memory:"); 14735 dropBuilder.append(stack); 14736 dropBuilder.append('\n'); 14737 dropBuilder.append(fullNativeBuilder); 14738 dropBuilder.append(fullJavaBuilder); 14739 dropBuilder.append('\n'); 14740 dropBuilder.append(memInfoBuilder); 14741 dropBuilder.append('\n'); 14742 /* 14743 dropBuilder.append(oomString); 14744 dropBuilder.append('\n'); 14745 */ 14746 StringWriter catSw = new StringWriter(); 14747 synchronized (ActivityManagerService.this) { 14748 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14749 String[] emptyArgs = new String[] { }; 14750 catPw.println(); 14751 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14752 catPw.println(); 14753 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14754 false, false, null); 14755 catPw.println(); 14756 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14757 catPw.flush(); 14758 } 14759 dropBuilder.append(catSw.toString()); 14760 addErrorToDropBox("lowmem", null, "system_server", null, 14761 null, tag.toString(), dropBuilder.toString(), null, null); 14762 //Slog.i(TAG, "Sent to dropbox:"); 14763 //Slog.i(TAG, dropBuilder.toString()); 14764 synchronized (ActivityManagerService.this) { 14765 long now = SystemClock.uptimeMillis(); 14766 if (mLastMemUsageReportTime < now) { 14767 mLastMemUsageReportTime = now; 14768 } 14769 } 14770 } 14771 14772 /** 14773 * Searches array of arguments for the specified string 14774 * @param args array of argument strings 14775 * @param value value to search for 14776 * @return true if the value is contained in the array 14777 */ 14778 private static boolean scanArgs(String[] args, String value) { 14779 if (args != null) { 14780 for (String arg : args) { 14781 if (value.equals(arg)) { 14782 return true; 14783 } 14784 } 14785 } 14786 return false; 14787 } 14788 14789 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14790 ContentProviderRecord cpr, boolean always) { 14791 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14792 14793 if (!inLaunching || always) { 14794 synchronized (cpr) { 14795 cpr.launchingApp = null; 14796 cpr.notifyAll(); 14797 } 14798 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14799 String names[] = cpr.info.authority.split(";"); 14800 for (int j = 0; j < names.length; j++) { 14801 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14802 } 14803 } 14804 14805 for (int i=0; i<cpr.connections.size(); i++) { 14806 ContentProviderConnection conn = cpr.connections.get(i); 14807 if (conn.waiting) { 14808 // If this connection is waiting for the provider, then we don't 14809 // need to mess with its process unless we are always removing 14810 // or for some reason the provider is not currently launching. 14811 if (inLaunching && !always) { 14812 continue; 14813 } 14814 } 14815 ProcessRecord capp = conn.client; 14816 conn.dead = true; 14817 if (conn.stableCount > 0) { 14818 if (!capp.persistent && capp.thread != null 14819 && capp.pid != 0 14820 && capp.pid != MY_PID) { 14821 capp.kill("depends on provider " 14822 + cpr.name.flattenToShortString() 14823 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14824 } 14825 } else if (capp.thread != null && conn.provider.provider != null) { 14826 try { 14827 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14828 } catch (RemoteException e) { 14829 } 14830 // In the protocol here, we don't expect the client to correctly 14831 // clean up this connection, we'll just remove it. 14832 cpr.connections.remove(i); 14833 if (conn.client.conProviders.remove(conn)) { 14834 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14835 } 14836 } 14837 } 14838 14839 if (inLaunching && always) { 14840 mLaunchingProviders.remove(cpr); 14841 } 14842 return inLaunching; 14843 } 14844 14845 /** 14846 * Main code for cleaning up a process when it has gone away. This is 14847 * called both as a result of the process dying, or directly when stopping 14848 * a process when running in single process mode. 14849 * 14850 * @return Returns true if the given process has been restarted, so the 14851 * app that was passed in must remain on the process lists. 14852 */ 14853 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14854 boolean restarting, boolean allowRestart, int index) { 14855 if (index >= 0) { 14856 removeLruProcessLocked(app); 14857 ProcessList.remove(app.pid); 14858 } 14859 14860 mProcessesToGc.remove(app); 14861 mPendingPssProcesses.remove(app); 14862 14863 // Dismiss any open dialogs. 14864 if (app.crashDialog != null && !app.forceCrashReport) { 14865 app.crashDialog.dismiss(); 14866 app.crashDialog = null; 14867 } 14868 if (app.anrDialog != null) { 14869 app.anrDialog.dismiss(); 14870 app.anrDialog = null; 14871 } 14872 if (app.waitDialog != null) { 14873 app.waitDialog.dismiss(); 14874 app.waitDialog = null; 14875 } 14876 14877 app.crashing = false; 14878 app.notResponding = false; 14879 14880 app.resetPackageList(mProcessStats); 14881 app.unlinkDeathRecipient(); 14882 app.makeInactive(mProcessStats); 14883 app.waitingToKill = null; 14884 app.forcingToForeground = null; 14885 updateProcessForegroundLocked(app, false, false); 14886 app.foregroundActivities = false; 14887 app.hasShownUi = false; 14888 app.treatLikeActivity = false; 14889 app.hasAboveClient = false; 14890 app.hasClientActivities = false; 14891 14892 mServices.killServicesLocked(app, allowRestart); 14893 14894 boolean restart = false; 14895 14896 // Remove published content providers. 14897 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14898 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14899 final boolean always = app.bad || !allowRestart; 14900 if (removeDyingProviderLocked(app, cpr, always) || always) { 14901 // We left the provider in the launching list, need to 14902 // restart it. 14903 restart = true; 14904 } 14905 14906 cpr.provider = null; 14907 cpr.proc = null; 14908 } 14909 app.pubProviders.clear(); 14910 14911 // Take care of any launching providers waiting for this process. 14912 if (checkAppInLaunchingProvidersLocked(app, false)) { 14913 restart = true; 14914 } 14915 14916 // Unregister from connected content providers. 14917 if (!app.conProviders.isEmpty()) { 14918 for (int i=0; i<app.conProviders.size(); i++) { 14919 ContentProviderConnection conn = app.conProviders.get(i); 14920 conn.provider.connections.remove(conn); 14921 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14922 conn.provider.name); 14923 } 14924 app.conProviders.clear(); 14925 } 14926 14927 // At this point there may be remaining entries in mLaunchingProviders 14928 // where we were the only one waiting, so they are no longer of use. 14929 // Look for these and clean up if found. 14930 // XXX Commented out for now. Trying to figure out a way to reproduce 14931 // the actual situation to identify what is actually going on. 14932 if (false) { 14933 for (int i=0; i<mLaunchingProviders.size(); i++) { 14934 ContentProviderRecord cpr = (ContentProviderRecord) 14935 mLaunchingProviders.get(i); 14936 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14937 synchronized (cpr) { 14938 cpr.launchingApp = null; 14939 cpr.notifyAll(); 14940 } 14941 } 14942 } 14943 } 14944 14945 skipCurrentReceiverLocked(app); 14946 14947 // Unregister any receivers. 14948 for (int i=app.receivers.size()-1; i>=0; i--) { 14949 removeReceiverLocked(app.receivers.valueAt(i)); 14950 } 14951 app.receivers.clear(); 14952 14953 // If the app is undergoing backup, tell the backup manager about it 14954 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14955 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14956 + mBackupTarget.appInfo + " died during backup"); 14957 try { 14958 IBackupManager bm = IBackupManager.Stub.asInterface( 14959 ServiceManager.getService(Context.BACKUP_SERVICE)); 14960 bm.agentDisconnected(app.info.packageName); 14961 } catch (RemoteException e) { 14962 // can't happen; backup manager is local 14963 } 14964 } 14965 14966 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14967 ProcessChangeItem item = mPendingProcessChanges.get(i); 14968 if (item.pid == app.pid) { 14969 mPendingProcessChanges.remove(i); 14970 mAvailProcessChanges.add(item); 14971 } 14972 } 14973 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14974 14975 // If the caller is restarting this app, then leave it in its 14976 // current lists and let the caller take care of it. 14977 if (restarting) { 14978 return false; 14979 } 14980 14981 if (!app.persistent || app.isolated) { 14982 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14983 "Removing non-persistent process during cleanup: " + app); 14984 mProcessNames.remove(app.processName, app.uid); 14985 mIsolatedProcesses.remove(app.uid); 14986 if (mHeavyWeightProcess == app) { 14987 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14988 mHeavyWeightProcess.userId, 0)); 14989 mHeavyWeightProcess = null; 14990 } 14991 } else if (!app.removed) { 14992 // This app is persistent, so we need to keep its record around. 14993 // If it is not already on the pending app list, add it there 14994 // and start a new process for it. 14995 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14996 mPersistentStartingProcesses.add(app); 14997 restart = true; 14998 } 14999 } 15000 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15001 "Clean-up removing on hold: " + app); 15002 mProcessesOnHold.remove(app); 15003 15004 if (app == mHomeProcess) { 15005 mHomeProcess = null; 15006 } 15007 if (app == mPreviousProcess) { 15008 mPreviousProcess = null; 15009 } 15010 15011 if (restart && !app.isolated) { 15012 // We have components that still need to be running in the 15013 // process, so re-launch it. 15014 if (index < 0) { 15015 ProcessList.remove(app.pid); 15016 } 15017 mProcessNames.put(app.processName, app.uid, app); 15018 startProcessLocked(app, "restart", app.processName); 15019 return true; 15020 } else if (app.pid > 0 && app.pid != MY_PID) { 15021 // Goodbye! 15022 boolean removed; 15023 synchronized (mPidsSelfLocked) { 15024 mPidsSelfLocked.remove(app.pid); 15025 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15026 } 15027 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15028 if (app.isolated) { 15029 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15030 } 15031 app.setPid(0); 15032 } 15033 return false; 15034 } 15035 15036 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15037 // Look through the content providers we are waiting to have launched, 15038 // and if any run in this process then either schedule a restart of 15039 // the process or kill the client waiting for it if this process has 15040 // gone bad. 15041 int NL = mLaunchingProviders.size(); 15042 boolean restart = false; 15043 for (int i=0; i<NL; i++) { 15044 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15045 if (cpr.launchingApp == app) { 15046 if (!alwaysBad && !app.bad) { 15047 restart = true; 15048 } else { 15049 removeDyingProviderLocked(app, cpr, true); 15050 // cpr should have been removed from mLaunchingProviders 15051 NL = mLaunchingProviders.size(); 15052 i--; 15053 } 15054 } 15055 } 15056 return restart; 15057 } 15058 15059 // ========================================================= 15060 // SERVICES 15061 // ========================================================= 15062 15063 @Override 15064 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15065 int flags) { 15066 enforceNotIsolatedCaller("getServices"); 15067 synchronized (this) { 15068 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15069 } 15070 } 15071 15072 @Override 15073 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15074 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15075 synchronized (this) { 15076 return mServices.getRunningServiceControlPanelLocked(name); 15077 } 15078 } 15079 15080 @Override 15081 public ComponentName startService(IApplicationThread caller, Intent service, 15082 String resolvedType, int userId) { 15083 enforceNotIsolatedCaller("startService"); 15084 // Refuse possible leaked file descriptors 15085 if (service != null && service.hasFileDescriptors() == true) { 15086 throw new IllegalArgumentException("File descriptors passed in Intent"); 15087 } 15088 15089 if (DEBUG_SERVICE) 15090 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15091 synchronized(this) { 15092 final int callingPid = Binder.getCallingPid(); 15093 final int callingUid = Binder.getCallingUid(); 15094 final long origId = Binder.clearCallingIdentity(); 15095 ComponentName res = mServices.startServiceLocked(caller, service, 15096 resolvedType, callingPid, callingUid, userId); 15097 Binder.restoreCallingIdentity(origId); 15098 return res; 15099 } 15100 } 15101 15102 ComponentName startServiceInPackage(int uid, 15103 Intent service, String resolvedType, int userId) { 15104 synchronized(this) { 15105 if (DEBUG_SERVICE) 15106 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15107 final long origId = Binder.clearCallingIdentity(); 15108 ComponentName res = mServices.startServiceLocked(null, service, 15109 resolvedType, -1, uid, userId); 15110 Binder.restoreCallingIdentity(origId); 15111 return res; 15112 } 15113 } 15114 15115 @Override 15116 public int stopService(IApplicationThread caller, Intent service, 15117 String resolvedType, int userId) { 15118 enforceNotIsolatedCaller("stopService"); 15119 // Refuse possible leaked file descriptors 15120 if (service != null && service.hasFileDescriptors() == true) { 15121 throw new IllegalArgumentException("File descriptors passed in Intent"); 15122 } 15123 15124 synchronized(this) { 15125 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15126 } 15127 } 15128 15129 @Override 15130 public IBinder peekService(Intent service, String resolvedType) { 15131 enforceNotIsolatedCaller("peekService"); 15132 // Refuse possible leaked file descriptors 15133 if (service != null && service.hasFileDescriptors() == true) { 15134 throw new IllegalArgumentException("File descriptors passed in Intent"); 15135 } 15136 synchronized(this) { 15137 return mServices.peekServiceLocked(service, resolvedType); 15138 } 15139 } 15140 15141 @Override 15142 public boolean stopServiceToken(ComponentName className, IBinder token, 15143 int startId) { 15144 synchronized(this) { 15145 return mServices.stopServiceTokenLocked(className, token, startId); 15146 } 15147 } 15148 15149 @Override 15150 public void setServiceForeground(ComponentName className, IBinder token, 15151 int id, Notification notification, boolean removeNotification) { 15152 synchronized(this) { 15153 mServices.setServiceForegroundLocked(className, token, id, notification, 15154 removeNotification); 15155 } 15156 } 15157 15158 @Override 15159 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15160 boolean requireFull, String name, String callerPackage) { 15161 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15162 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15163 } 15164 15165 int unsafeConvertIncomingUser(int userId) { 15166 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15167 ? mCurrentUserId : userId; 15168 } 15169 15170 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15171 int allowMode, String name, String callerPackage) { 15172 final int callingUserId = UserHandle.getUserId(callingUid); 15173 if (callingUserId == userId) { 15174 return userId; 15175 } 15176 15177 // Note that we may be accessing mCurrentUserId outside of a lock... 15178 // shouldn't be a big deal, if this is being called outside 15179 // of a locked context there is intrinsically a race with 15180 // the value the caller will receive and someone else changing it. 15181 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15182 // we will switch to the calling user if access to the current user fails. 15183 int targetUserId = unsafeConvertIncomingUser(userId); 15184 15185 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15186 final boolean allow; 15187 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15188 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15189 // If the caller has this permission, they always pass go. And collect $200. 15190 allow = true; 15191 } else if (allowMode == ALLOW_FULL_ONLY) { 15192 // We require full access, sucks to be you. 15193 allow = false; 15194 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15195 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15196 // If the caller does not have either permission, they are always doomed. 15197 allow = false; 15198 } else if (allowMode == ALLOW_NON_FULL) { 15199 // We are blanket allowing non-full access, you lucky caller! 15200 allow = true; 15201 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15202 // We may or may not allow this depending on whether the two users are 15203 // in the same profile. 15204 synchronized (mUserProfileGroupIdsSelfLocked) { 15205 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15206 UserInfo.NO_PROFILE_GROUP_ID); 15207 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15208 UserInfo.NO_PROFILE_GROUP_ID); 15209 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15210 && callingProfile == targetProfile; 15211 } 15212 } else { 15213 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15214 } 15215 if (!allow) { 15216 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15217 // In this case, they would like to just execute as their 15218 // owner user instead of failing. 15219 targetUserId = callingUserId; 15220 } else { 15221 StringBuilder builder = new StringBuilder(128); 15222 builder.append("Permission Denial: "); 15223 builder.append(name); 15224 if (callerPackage != null) { 15225 builder.append(" from "); 15226 builder.append(callerPackage); 15227 } 15228 builder.append(" asks to run as user "); 15229 builder.append(userId); 15230 builder.append(" but is calling from user "); 15231 builder.append(UserHandle.getUserId(callingUid)); 15232 builder.append("; this requires "); 15233 builder.append(INTERACT_ACROSS_USERS_FULL); 15234 if (allowMode != ALLOW_FULL_ONLY) { 15235 builder.append(" or "); 15236 builder.append(INTERACT_ACROSS_USERS); 15237 } 15238 String msg = builder.toString(); 15239 Slog.w(TAG, msg); 15240 throw new SecurityException(msg); 15241 } 15242 } 15243 } 15244 if (!allowAll && targetUserId < 0) { 15245 throw new IllegalArgumentException( 15246 "Call does not support special user #" + targetUserId); 15247 } 15248 // Check shell permission 15249 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15250 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15251 targetUserId)) { 15252 throw new SecurityException("Shell does not have permission to access user " 15253 + targetUserId + "\n " + Debug.getCallers(3)); 15254 } 15255 } 15256 return targetUserId; 15257 } 15258 15259 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15260 String className, int flags) { 15261 boolean result = false; 15262 // For apps that don't have pre-defined UIDs, check for permission 15263 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15264 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15265 if (ActivityManager.checkUidPermission( 15266 INTERACT_ACROSS_USERS, 15267 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15268 ComponentName comp = new ComponentName(aInfo.packageName, className); 15269 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15270 + " requests FLAG_SINGLE_USER, but app does not hold " 15271 + INTERACT_ACROSS_USERS; 15272 Slog.w(TAG, msg); 15273 throw new SecurityException(msg); 15274 } 15275 // Permission passed 15276 result = true; 15277 } 15278 } else if ("system".equals(componentProcessName)) { 15279 result = true; 15280 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15281 // Phone app and persistent apps are allowed to export singleuser providers. 15282 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15283 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15284 } 15285 if (DEBUG_MU) { 15286 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15287 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15288 } 15289 return result; 15290 } 15291 15292 /** 15293 * Checks to see if the caller is in the same app as the singleton 15294 * component, or the component is in a special app. It allows special apps 15295 * to export singleton components but prevents exporting singleton 15296 * components for regular apps. 15297 */ 15298 boolean isValidSingletonCall(int callingUid, int componentUid) { 15299 int componentAppId = UserHandle.getAppId(componentUid); 15300 return UserHandle.isSameApp(callingUid, componentUid) 15301 || componentAppId == Process.SYSTEM_UID 15302 || componentAppId == Process.PHONE_UID 15303 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15304 == PackageManager.PERMISSION_GRANTED; 15305 } 15306 15307 public int bindService(IApplicationThread caller, IBinder token, 15308 Intent service, String resolvedType, 15309 IServiceConnection connection, int flags, int userId) { 15310 enforceNotIsolatedCaller("bindService"); 15311 15312 // Refuse possible leaked file descriptors 15313 if (service != null && service.hasFileDescriptors() == true) { 15314 throw new IllegalArgumentException("File descriptors passed in Intent"); 15315 } 15316 15317 synchronized(this) { 15318 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15319 connection, flags, userId); 15320 } 15321 } 15322 15323 public boolean unbindService(IServiceConnection connection) { 15324 synchronized (this) { 15325 return mServices.unbindServiceLocked(connection); 15326 } 15327 } 15328 15329 public void publishService(IBinder token, Intent intent, IBinder service) { 15330 // Refuse possible leaked file descriptors 15331 if (intent != null && intent.hasFileDescriptors() == true) { 15332 throw new IllegalArgumentException("File descriptors passed in Intent"); 15333 } 15334 15335 synchronized(this) { 15336 if (!(token instanceof ServiceRecord)) { 15337 throw new IllegalArgumentException("Invalid service token"); 15338 } 15339 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15340 } 15341 } 15342 15343 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15344 // Refuse possible leaked file descriptors 15345 if (intent != null && intent.hasFileDescriptors() == true) { 15346 throw new IllegalArgumentException("File descriptors passed in Intent"); 15347 } 15348 15349 synchronized(this) { 15350 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15351 } 15352 } 15353 15354 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15355 synchronized(this) { 15356 if (!(token instanceof ServiceRecord)) { 15357 throw new IllegalArgumentException("Invalid service token"); 15358 } 15359 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15360 } 15361 } 15362 15363 // ========================================================= 15364 // BACKUP AND RESTORE 15365 // ========================================================= 15366 15367 // Cause the target app to be launched if necessary and its backup agent 15368 // instantiated. The backup agent will invoke backupAgentCreated() on the 15369 // activity manager to announce its creation. 15370 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15371 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15372 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15373 15374 synchronized(this) { 15375 // !!! TODO: currently no check here that we're already bound 15376 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15377 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15378 synchronized (stats) { 15379 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15380 } 15381 15382 // Backup agent is now in use, its package can't be stopped. 15383 try { 15384 AppGlobals.getPackageManager().setPackageStoppedState( 15385 app.packageName, false, UserHandle.getUserId(app.uid)); 15386 } catch (RemoteException e) { 15387 } catch (IllegalArgumentException e) { 15388 Slog.w(TAG, "Failed trying to unstop package " 15389 + app.packageName + ": " + e); 15390 } 15391 15392 BackupRecord r = new BackupRecord(ss, app, backupMode); 15393 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15394 ? new ComponentName(app.packageName, app.backupAgentName) 15395 : new ComponentName("android", "FullBackupAgent"); 15396 // startProcessLocked() returns existing proc's record if it's already running 15397 ProcessRecord proc = startProcessLocked(app.processName, app, 15398 false, 0, "backup", hostingName, false, false, false); 15399 if (proc == null) { 15400 Slog.e(TAG, "Unable to start backup agent process " + r); 15401 return false; 15402 } 15403 15404 r.app = proc; 15405 mBackupTarget = r; 15406 mBackupAppName = app.packageName; 15407 15408 // Try not to kill the process during backup 15409 updateOomAdjLocked(proc); 15410 15411 // If the process is already attached, schedule the creation of the backup agent now. 15412 // If it is not yet live, this will be done when it attaches to the framework. 15413 if (proc.thread != null) { 15414 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15415 try { 15416 proc.thread.scheduleCreateBackupAgent(app, 15417 compatibilityInfoForPackageLocked(app), backupMode); 15418 } catch (RemoteException e) { 15419 // Will time out on the backup manager side 15420 } 15421 } else { 15422 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15423 } 15424 // Invariants: at this point, the target app process exists and the application 15425 // is either already running or in the process of coming up. mBackupTarget and 15426 // mBackupAppName describe the app, so that when it binds back to the AM we 15427 // know that it's scheduled for a backup-agent operation. 15428 } 15429 15430 return true; 15431 } 15432 15433 @Override 15434 public void clearPendingBackup() { 15435 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15436 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15437 15438 synchronized (this) { 15439 mBackupTarget = null; 15440 mBackupAppName = null; 15441 } 15442 } 15443 15444 // A backup agent has just come up 15445 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15446 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15447 + " = " + agent); 15448 15449 synchronized(this) { 15450 if (!agentPackageName.equals(mBackupAppName)) { 15451 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15452 return; 15453 } 15454 } 15455 15456 long oldIdent = Binder.clearCallingIdentity(); 15457 try { 15458 IBackupManager bm = IBackupManager.Stub.asInterface( 15459 ServiceManager.getService(Context.BACKUP_SERVICE)); 15460 bm.agentConnected(agentPackageName, agent); 15461 } catch (RemoteException e) { 15462 // can't happen; the backup manager service is local 15463 } catch (Exception e) { 15464 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15465 e.printStackTrace(); 15466 } finally { 15467 Binder.restoreCallingIdentity(oldIdent); 15468 } 15469 } 15470 15471 // done with this agent 15472 public void unbindBackupAgent(ApplicationInfo appInfo) { 15473 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15474 if (appInfo == null) { 15475 Slog.w(TAG, "unbind backup agent for null app"); 15476 return; 15477 } 15478 15479 synchronized(this) { 15480 try { 15481 if (mBackupAppName == null) { 15482 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15483 return; 15484 } 15485 15486 if (!mBackupAppName.equals(appInfo.packageName)) { 15487 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15488 return; 15489 } 15490 15491 // Not backing this app up any more; reset its OOM adjustment 15492 final ProcessRecord proc = mBackupTarget.app; 15493 updateOomAdjLocked(proc); 15494 15495 // If the app crashed during backup, 'thread' will be null here 15496 if (proc.thread != null) { 15497 try { 15498 proc.thread.scheduleDestroyBackupAgent(appInfo, 15499 compatibilityInfoForPackageLocked(appInfo)); 15500 } catch (Exception e) { 15501 Slog.e(TAG, "Exception when unbinding backup agent:"); 15502 e.printStackTrace(); 15503 } 15504 } 15505 } finally { 15506 mBackupTarget = null; 15507 mBackupAppName = null; 15508 } 15509 } 15510 } 15511 // ========================================================= 15512 // BROADCASTS 15513 // ========================================================= 15514 15515 private final List getStickiesLocked(String action, IntentFilter filter, 15516 List cur, int userId) { 15517 final ContentResolver resolver = mContext.getContentResolver(); 15518 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15519 if (stickies == null) { 15520 return cur; 15521 } 15522 final ArrayList<Intent> list = stickies.get(action); 15523 if (list == null) { 15524 return cur; 15525 } 15526 int N = list.size(); 15527 for (int i=0; i<N; i++) { 15528 Intent intent = list.get(i); 15529 if (filter.match(resolver, intent, true, TAG) >= 0) { 15530 if (cur == null) { 15531 cur = new ArrayList<Intent>(); 15532 } 15533 cur.add(intent); 15534 } 15535 } 15536 return cur; 15537 } 15538 15539 boolean isPendingBroadcastProcessLocked(int pid) { 15540 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15541 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15542 } 15543 15544 void skipPendingBroadcastLocked(int pid) { 15545 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15546 for (BroadcastQueue queue : mBroadcastQueues) { 15547 queue.skipPendingBroadcastLocked(pid); 15548 } 15549 } 15550 15551 // The app just attached; send any pending broadcasts that it should receive 15552 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15553 boolean didSomething = false; 15554 for (BroadcastQueue queue : mBroadcastQueues) { 15555 didSomething |= queue.sendPendingBroadcastsLocked(app); 15556 } 15557 return didSomething; 15558 } 15559 15560 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15561 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15562 enforceNotIsolatedCaller("registerReceiver"); 15563 int callingUid; 15564 int callingPid; 15565 synchronized(this) { 15566 ProcessRecord callerApp = null; 15567 if (caller != null) { 15568 callerApp = getRecordForAppLocked(caller); 15569 if (callerApp == null) { 15570 throw new SecurityException( 15571 "Unable to find app for caller " + caller 15572 + " (pid=" + Binder.getCallingPid() 15573 + ") when registering receiver " + receiver); 15574 } 15575 if (callerApp.info.uid != Process.SYSTEM_UID && 15576 !callerApp.pkgList.containsKey(callerPackage) && 15577 !"android".equals(callerPackage)) { 15578 throw new SecurityException("Given caller package " + callerPackage 15579 + " is not running in process " + callerApp); 15580 } 15581 callingUid = callerApp.info.uid; 15582 callingPid = callerApp.pid; 15583 } else { 15584 callerPackage = null; 15585 callingUid = Binder.getCallingUid(); 15586 callingPid = Binder.getCallingPid(); 15587 } 15588 15589 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15590 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15591 15592 List allSticky = null; 15593 15594 // Look for any matching sticky broadcasts... 15595 Iterator actions = filter.actionsIterator(); 15596 if (actions != null) { 15597 while (actions.hasNext()) { 15598 String action = (String)actions.next(); 15599 allSticky = getStickiesLocked(action, filter, allSticky, 15600 UserHandle.USER_ALL); 15601 allSticky = getStickiesLocked(action, filter, allSticky, 15602 UserHandle.getUserId(callingUid)); 15603 } 15604 } else { 15605 allSticky = getStickiesLocked(null, filter, allSticky, 15606 UserHandle.USER_ALL); 15607 allSticky = getStickiesLocked(null, filter, allSticky, 15608 UserHandle.getUserId(callingUid)); 15609 } 15610 15611 // The first sticky in the list is returned directly back to 15612 // the client. 15613 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15614 15615 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15616 + ": " + sticky); 15617 15618 if (receiver == null) { 15619 return sticky; 15620 } 15621 15622 ReceiverList rl 15623 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15624 if (rl == null) { 15625 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15626 userId, receiver); 15627 if (rl.app != null) { 15628 rl.app.receivers.add(rl); 15629 } else { 15630 try { 15631 receiver.asBinder().linkToDeath(rl, 0); 15632 } catch (RemoteException e) { 15633 return sticky; 15634 } 15635 rl.linkedToDeath = true; 15636 } 15637 mRegisteredReceivers.put(receiver.asBinder(), rl); 15638 } else if (rl.uid != callingUid) { 15639 throw new IllegalArgumentException( 15640 "Receiver requested to register for uid " + callingUid 15641 + " was previously registered for uid " + rl.uid); 15642 } else if (rl.pid != callingPid) { 15643 throw new IllegalArgumentException( 15644 "Receiver requested to register for pid " + callingPid 15645 + " was previously registered for pid " + rl.pid); 15646 } else if (rl.userId != userId) { 15647 throw new IllegalArgumentException( 15648 "Receiver requested to register for user " + userId 15649 + " was previously registered for user " + rl.userId); 15650 } 15651 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15652 permission, callingUid, userId); 15653 rl.add(bf); 15654 if (!bf.debugCheck()) { 15655 Slog.w(TAG, "==> For Dynamic broadast"); 15656 } 15657 mReceiverResolver.addFilter(bf); 15658 15659 // Enqueue broadcasts for all existing stickies that match 15660 // this filter. 15661 if (allSticky != null) { 15662 ArrayList receivers = new ArrayList(); 15663 receivers.add(bf); 15664 15665 int N = allSticky.size(); 15666 for (int i=0; i<N; i++) { 15667 Intent intent = (Intent)allSticky.get(i); 15668 BroadcastQueue queue = broadcastQueueForIntent(intent); 15669 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15670 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15671 null, null, false, true, true, -1); 15672 queue.enqueueParallelBroadcastLocked(r); 15673 queue.scheduleBroadcastsLocked(); 15674 } 15675 } 15676 15677 return sticky; 15678 } 15679 } 15680 15681 public void unregisterReceiver(IIntentReceiver receiver) { 15682 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15683 15684 final long origId = Binder.clearCallingIdentity(); 15685 try { 15686 boolean doTrim = false; 15687 15688 synchronized(this) { 15689 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15690 if (rl != null) { 15691 if (rl.curBroadcast != null) { 15692 BroadcastRecord r = rl.curBroadcast; 15693 final boolean doNext = finishReceiverLocked( 15694 receiver.asBinder(), r.resultCode, r.resultData, 15695 r.resultExtras, r.resultAbort); 15696 if (doNext) { 15697 doTrim = true; 15698 r.queue.processNextBroadcast(false); 15699 } 15700 } 15701 15702 if (rl.app != null) { 15703 rl.app.receivers.remove(rl); 15704 } 15705 removeReceiverLocked(rl); 15706 if (rl.linkedToDeath) { 15707 rl.linkedToDeath = false; 15708 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15709 } 15710 } 15711 } 15712 15713 // If we actually concluded any broadcasts, we might now be able 15714 // to trim the recipients' apps from our working set 15715 if (doTrim) { 15716 trimApplications(); 15717 return; 15718 } 15719 15720 } finally { 15721 Binder.restoreCallingIdentity(origId); 15722 } 15723 } 15724 15725 void removeReceiverLocked(ReceiverList rl) { 15726 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15727 int N = rl.size(); 15728 for (int i=0; i<N; i++) { 15729 mReceiverResolver.removeFilter(rl.get(i)); 15730 } 15731 } 15732 15733 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15734 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15735 ProcessRecord r = mLruProcesses.get(i); 15736 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15737 try { 15738 r.thread.dispatchPackageBroadcast(cmd, packages); 15739 } catch (RemoteException ex) { 15740 } 15741 } 15742 } 15743 } 15744 15745 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15746 int callingUid, int[] users) { 15747 List<ResolveInfo> receivers = null; 15748 try { 15749 HashSet<ComponentName> singleUserReceivers = null; 15750 boolean scannedFirstReceivers = false; 15751 for (int user : users) { 15752 // Skip users that have Shell restrictions 15753 if (callingUid == Process.SHELL_UID 15754 && getUserManagerLocked().hasUserRestriction( 15755 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15756 continue; 15757 } 15758 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15759 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15760 if (user != 0 && newReceivers != null) { 15761 // If this is not the primary user, we need to check for 15762 // any receivers that should be filtered out. 15763 for (int i=0; i<newReceivers.size(); i++) { 15764 ResolveInfo ri = newReceivers.get(i); 15765 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15766 newReceivers.remove(i); 15767 i--; 15768 } 15769 } 15770 } 15771 if (newReceivers != null && newReceivers.size() == 0) { 15772 newReceivers = null; 15773 } 15774 if (receivers == null) { 15775 receivers = newReceivers; 15776 } else if (newReceivers != null) { 15777 // We need to concatenate the additional receivers 15778 // found with what we have do far. This would be easy, 15779 // but we also need to de-dup any receivers that are 15780 // singleUser. 15781 if (!scannedFirstReceivers) { 15782 // Collect any single user receivers we had already retrieved. 15783 scannedFirstReceivers = true; 15784 for (int i=0; i<receivers.size(); i++) { 15785 ResolveInfo ri = receivers.get(i); 15786 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15787 ComponentName cn = new ComponentName( 15788 ri.activityInfo.packageName, ri.activityInfo.name); 15789 if (singleUserReceivers == null) { 15790 singleUserReceivers = new HashSet<ComponentName>(); 15791 } 15792 singleUserReceivers.add(cn); 15793 } 15794 } 15795 } 15796 // Add the new results to the existing results, tracking 15797 // and de-dupping single user receivers. 15798 for (int i=0; i<newReceivers.size(); i++) { 15799 ResolveInfo ri = newReceivers.get(i); 15800 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15801 ComponentName cn = new ComponentName( 15802 ri.activityInfo.packageName, ri.activityInfo.name); 15803 if (singleUserReceivers == null) { 15804 singleUserReceivers = new HashSet<ComponentName>(); 15805 } 15806 if (!singleUserReceivers.contains(cn)) { 15807 singleUserReceivers.add(cn); 15808 receivers.add(ri); 15809 } 15810 } else { 15811 receivers.add(ri); 15812 } 15813 } 15814 } 15815 } 15816 } catch (RemoteException ex) { 15817 // pm is in same process, this will never happen. 15818 } 15819 return receivers; 15820 } 15821 15822 private final int broadcastIntentLocked(ProcessRecord callerApp, 15823 String callerPackage, Intent intent, String resolvedType, 15824 IIntentReceiver resultTo, int resultCode, String resultData, 15825 Bundle map, String requiredPermission, int appOp, 15826 boolean ordered, boolean sticky, int callingPid, int callingUid, 15827 int userId) { 15828 intent = new Intent(intent); 15829 15830 // By default broadcasts do not go to stopped apps. 15831 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15832 15833 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15834 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15835 + " ordered=" + ordered + " userid=" + userId); 15836 if ((resultTo != null) && !ordered) { 15837 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15838 } 15839 15840 userId = handleIncomingUser(callingPid, callingUid, userId, 15841 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15842 15843 // Make sure that the user who is receiving this broadcast is running. 15844 // If not, we will just skip it. Make an exception for shutdown broadcasts 15845 // and upgrade steps. 15846 15847 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15848 if ((callingUid != Process.SYSTEM_UID 15849 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15850 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15851 Slog.w(TAG, "Skipping broadcast of " + intent 15852 + ": user " + userId + " is stopped"); 15853 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15854 } 15855 } 15856 15857 /* 15858 * Prevent non-system code (defined here to be non-persistent 15859 * processes) from sending protected broadcasts. 15860 */ 15861 int callingAppId = UserHandle.getAppId(callingUid); 15862 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15863 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15864 || callingAppId == Process.NFC_UID || callingUid == 0) { 15865 // Always okay. 15866 } else if (callerApp == null || !callerApp.persistent) { 15867 try { 15868 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15869 intent.getAction())) { 15870 String msg = "Permission Denial: not allowed to send broadcast " 15871 + intent.getAction() + " from pid=" 15872 + callingPid + ", uid=" + callingUid; 15873 Slog.w(TAG, msg); 15874 throw new SecurityException(msg); 15875 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15876 // Special case for compatibility: we don't want apps to send this, 15877 // but historically it has not been protected and apps may be using it 15878 // to poke their own app widget. So, instead of making it protected, 15879 // just limit it to the caller. 15880 if (callerApp == null) { 15881 String msg = "Permission Denial: not allowed to send broadcast " 15882 + intent.getAction() + " from unknown caller."; 15883 Slog.w(TAG, msg); 15884 throw new SecurityException(msg); 15885 } else if (intent.getComponent() != null) { 15886 // They are good enough to send to an explicit component... verify 15887 // it is being sent to the calling app. 15888 if (!intent.getComponent().getPackageName().equals( 15889 callerApp.info.packageName)) { 15890 String msg = "Permission Denial: not allowed to send broadcast " 15891 + intent.getAction() + " to " 15892 + intent.getComponent().getPackageName() + " from " 15893 + callerApp.info.packageName; 15894 Slog.w(TAG, msg); 15895 throw new SecurityException(msg); 15896 } 15897 } else { 15898 // Limit broadcast to their own package. 15899 intent.setPackage(callerApp.info.packageName); 15900 } 15901 } 15902 } catch (RemoteException e) { 15903 Slog.w(TAG, "Remote exception", e); 15904 return ActivityManager.BROADCAST_SUCCESS; 15905 } 15906 } 15907 15908 final String action = intent.getAction(); 15909 if (action != null) { 15910 switch (action) { 15911 case Intent.ACTION_UID_REMOVED: 15912 case Intent.ACTION_PACKAGE_REMOVED: 15913 case Intent.ACTION_PACKAGE_CHANGED: 15914 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15915 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15916 // Handle special intents: if this broadcast is from the package 15917 // manager about a package being removed, we need to remove all of 15918 // its activities from the history stack. 15919 if (checkComponentPermission( 15920 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15921 callingPid, callingUid, -1, true) 15922 != PackageManager.PERMISSION_GRANTED) { 15923 String msg = "Permission Denial: " + intent.getAction() 15924 + " broadcast from " + callerPackage + " (pid=" + callingPid 15925 + ", uid=" + callingUid + ")" 15926 + " requires " 15927 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15928 Slog.w(TAG, msg); 15929 throw new SecurityException(msg); 15930 } 15931 switch (action) { 15932 case Intent.ACTION_UID_REMOVED: 15933 final Bundle intentExtras = intent.getExtras(); 15934 final int uid = intentExtras != null 15935 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15936 if (uid >= 0) { 15937 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15938 synchronized (bs) { 15939 bs.removeUidStatsLocked(uid); 15940 } 15941 mAppOpsService.uidRemoved(uid); 15942 } 15943 break; 15944 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15945 // If resources are unavailable just force stop all those packages 15946 // and flush the attribute cache as well. 15947 String list[] = 15948 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15949 if (list != null && list.length > 0) { 15950 for (int i = 0; i < list.length; i++) { 15951 forceStopPackageLocked(list[i], -1, false, true, true, 15952 false, false, userId, "storage unmount"); 15953 } 15954 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15955 sendPackageBroadcastLocked( 15956 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15957 userId); 15958 } 15959 break; 15960 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15961 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15962 break; 15963 case Intent.ACTION_PACKAGE_REMOVED: 15964 case Intent.ACTION_PACKAGE_CHANGED: 15965 Uri data = intent.getData(); 15966 String ssp; 15967 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15968 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15969 boolean fullUninstall = removed && 15970 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15971 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15972 forceStopPackageLocked(ssp, UserHandle.getAppId( 15973 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15974 false, true, true, false, fullUninstall, userId, 15975 removed ? "pkg removed" : "pkg changed"); 15976 } 15977 if (removed) { 15978 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15979 new String[] {ssp}, userId); 15980 if (fullUninstall) { 15981 mAppOpsService.packageRemoved( 15982 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15983 15984 // Remove all permissions granted from/to this package 15985 removeUriPermissionsForPackageLocked(ssp, userId, true); 15986 15987 removeTasksByPackageNameLocked(ssp, userId); 15988 } 15989 } else { 15990 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15991 if (userId == UserHandle.USER_OWNER) { 15992 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15993 } 15994 } 15995 } 15996 break; 15997 } 15998 break; 15999 case Intent.ACTION_PACKAGE_ADDED: 16000 // Special case for adding a package: by default turn on compatibility mode. 16001 Uri data = intent.getData(); 16002 String ssp; 16003 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16004 final boolean replacing = 16005 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16006 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16007 16008 if (replacing) { 16009 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16010 } 16011 if (userId == UserHandle.USER_OWNER) { 16012 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16013 } 16014 } 16015 break; 16016 case Intent.ACTION_TIMEZONE_CHANGED: 16017 // If this is the time zone changed action, queue up a message that will reset 16018 // the timezone of all currently running processes. This message will get 16019 // queued up before the broadcast happens. 16020 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16021 break; 16022 case Intent.ACTION_TIME_CHANGED: 16023 // If the user set the time, let all running processes know. 16024 final int is24Hour = 16025 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16026 : 0; 16027 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16028 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16029 synchronized (stats) { 16030 stats.noteCurrentTimeChangedLocked(); 16031 } 16032 break; 16033 case Intent.ACTION_CLEAR_DNS_CACHE: 16034 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16035 break; 16036 case Proxy.PROXY_CHANGE_ACTION: 16037 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16038 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16039 break; 16040 } 16041 } 16042 16043 // Add to the sticky list if requested. 16044 if (sticky) { 16045 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16046 callingPid, callingUid) 16047 != PackageManager.PERMISSION_GRANTED) { 16048 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16049 + callingPid + ", uid=" + callingUid 16050 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16051 Slog.w(TAG, msg); 16052 throw new SecurityException(msg); 16053 } 16054 if (requiredPermission != null) { 16055 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16056 + " and enforce permission " + requiredPermission); 16057 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16058 } 16059 if (intent.getComponent() != null) { 16060 throw new SecurityException( 16061 "Sticky broadcasts can't target a specific component"); 16062 } 16063 // We use userId directly here, since the "all" target is maintained 16064 // as a separate set of sticky broadcasts. 16065 if (userId != UserHandle.USER_ALL) { 16066 // But first, if this is not a broadcast to all users, then 16067 // make sure it doesn't conflict with an existing broadcast to 16068 // all users. 16069 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16070 UserHandle.USER_ALL); 16071 if (stickies != null) { 16072 ArrayList<Intent> list = stickies.get(intent.getAction()); 16073 if (list != null) { 16074 int N = list.size(); 16075 int i; 16076 for (i=0; i<N; i++) { 16077 if (intent.filterEquals(list.get(i))) { 16078 throw new IllegalArgumentException( 16079 "Sticky broadcast " + intent + " for user " 16080 + userId + " conflicts with existing global broadcast"); 16081 } 16082 } 16083 } 16084 } 16085 } 16086 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16087 if (stickies == null) { 16088 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16089 mStickyBroadcasts.put(userId, stickies); 16090 } 16091 ArrayList<Intent> list = stickies.get(intent.getAction()); 16092 if (list == null) { 16093 list = new ArrayList<Intent>(); 16094 stickies.put(intent.getAction(), list); 16095 } 16096 int N = list.size(); 16097 int i; 16098 for (i=0; i<N; i++) { 16099 if (intent.filterEquals(list.get(i))) { 16100 // This sticky already exists, replace it. 16101 list.set(i, new Intent(intent)); 16102 break; 16103 } 16104 } 16105 if (i >= N) { 16106 list.add(new Intent(intent)); 16107 } 16108 } 16109 16110 int[] users; 16111 if (userId == UserHandle.USER_ALL) { 16112 // Caller wants broadcast to go to all started users. 16113 users = mStartedUserArray; 16114 } else { 16115 // Caller wants broadcast to go to one specific user. 16116 users = new int[] {userId}; 16117 } 16118 16119 // Figure out who all will receive this broadcast. 16120 List receivers = null; 16121 List<BroadcastFilter> registeredReceivers = null; 16122 // Need to resolve the intent to interested receivers... 16123 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16124 == 0) { 16125 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16126 } 16127 if (intent.getComponent() == null) { 16128 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16129 // Query one target user at a time, excluding shell-restricted users 16130 UserManagerService ums = getUserManagerLocked(); 16131 for (int i = 0; i < users.length; i++) { 16132 if (ums.hasUserRestriction( 16133 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16134 continue; 16135 } 16136 List<BroadcastFilter> registeredReceiversForUser = 16137 mReceiverResolver.queryIntent(intent, 16138 resolvedType, false, users[i]); 16139 if (registeredReceivers == null) { 16140 registeredReceivers = registeredReceiversForUser; 16141 } else if (registeredReceiversForUser != null) { 16142 registeredReceivers.addAll(registeredReceiversForUser); 16143 } 16144 } 16145 } else { 16146 registeredReceivers = mReceiverResolver.queryIntent(intent, 16147 resolvedType, false, userId); 16148 } 16149 } 16150 16151 final boolean replacePending = 16152 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16153 16154 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16155 + " replacePending=" + replacePending); 16156 16157 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16158 if (!ordered && NR > 0) { 16159 // If we are not serializing this broadcast, then send the 16160 // registered receivers separately so they don't wait for the 16161 // components to be launched. 16162 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16163 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16164 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16165 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16166 ordered, sticky, false, userId); 16167 if (DEBUG_BROADCAST) Slog.v( 16168 TAG, "Enqueueing parallel broadcast " + r); 16169 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16170 if (!replaced) { 16171 queue.enqueueParallelBroadcastLocked(r); 16172 queue.scheduleBroadcastsLocked(); 16173 } 16174 registeredReceivers = null; 16175 NR = 0; 16176 } 16177 16178 // Merge into one list. 16179 int ir = 0; 16180 if (receivers != null) { 16181 // A special case for PACKAGE_ADDED: do not allow the package 16182 // being added to see this broadcast. This prevents them from 16183 // using this as a back door to get run as soon as they are 16184 // installed. Maybe in the future we want to have a special install 16185 // broadcast or such for apps, but we'd like to deliberately make 16186 // this decision. 16187 String skipPackages[] = null; 16188 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16189 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16190 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16191 Uri data = intent.getData(); 16192 if (data != null) { 16193 String pkgName = data.getSchemeSpecificPart(); 16194 if (pkgName != null) { 16195 skipPackages = new String[] { pkgName }; 16196 } 16197 } 16198 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16199 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16200 } 16201 if (skipPackages != null && (skipPackages.length > 0)) { 16202 for (String skipPackage : skipPackages) { 16203 if (skipPackage != null) { 16204 int NT = receivers.size(); 16205 for (int it=0; it<NT; it++) { 16206 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16207 if (curt.activityInfo.packageName.equals(skipPackage)) { 16208 receivers.remove(it); 16209 it--; 16210 NT--; 16211 } 16212 } 16213 } 16214 } 16215 } 16216 16217 int NT = receivers != null ? receivers.size() : 0; 16218 int it = 0; 16219 ResolveInfo curt = null; 16220 BroadcastFilter curr = null; 16221 while (it < NT && ir < NR) { 16222 if (curt == null) { 16223 curt = (ResolveInfo)receivers.get(it); 16224 } 16225 if (curr == null) { 16226 curr = registeredReceivers.get(ir); 16227 } 16228 if (curr.getPriority() >= curt.priority) { 16229 // Insert this broadcast record into the final list. 16230 receivers.add(it, curr); 16231 ir++; 16232 curr = null; 16233 it++; 16234 NT++; 16235 } else { 16236 // Skip to the next ResolveInfo in the final list. 16237 it++; 16238 curt = null; 16239 } 16240 } 16241 } 16242 while (ir < NR) { 16243 if (receivers == null) { 16244 receivers = new ArrayList(); 16245 } 16246 receivers.add(registeredReceivers.get(ir)); 16247 ir++; 16248 } 16249 16250 if ((receivers != null && receivers.size() > 0) 16251 || resultTo != null) { 16252 BroadcastQueue queue = broadcastQueueForIntent(intent); 16253 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16254 callerPackage, callingPid, callingUid, resolvedType, 16255 requiredPermission, appOp, receivers, resultTo, resultCode, 16256 resultData, map, ordered, sticky, false, userId); 16257 if (DEBUG_BROADCAST) Slog.v( 16258 TAG, "Enqueueing ordered broadcast " + r 16259 + ": prev had " + queue.mOrderedBroadcasts.size()); 16260 if (DEBUG_BROADCAST) { 16261 int seq = r.intent.getIntExtra("seq", -1); 16262 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16263 } 16264 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16265 if (!replaced) { 16266 queue.enqueueOrderedBroadcastLocked(r); 16267 queue.scheduleBroadcastsLocked(); 16268 } 16269 } 16270 16271 return ActivityManager.BROADCAST_SUCCESS; 16272 } 16273 16274 final Intent verifyBroadcastLocked(Intent intent) { 16275 // Refuse possible leaked file descriptors 16276 if (intent != null && intent.hasFileDescriptors() == true) { 16277 throw new IllegalArgumentException("File descriptors passed in Intent"); 16278 } 16279 16280 int flags = intent.getFlags(); 16281 16282 if (!mProcessesReady) { 16283 // if the caller really truly claims to know what they're doing, go 16284 // ahead and allow the broadcast without launching any receivers 16285 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16286 intent = new Intent(intent); 16287 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16288 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16289 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16290 + " before boot completion"); 16291 throw new IllegalStateException("Cannot broadcast before boot completed"); 16292 } 16293 } 16294 16295 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16296 throw new IllegalArgumentException( 16297 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16298 } 16299 16300 return intent; 16301 } 16302 16303 public final int broadcastIntent(IApplicationThread caller, 16304 Intent intent, String resolvedType, IIntentReceiver resultTo, 16305 int resultCode, String resultData, Bundle map, 16306 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16307 enforceNotIsolatedCaller("broadcastIntent"); 16308 synchronized(this) { 16309 intent = verifyBroadcastLocked(intent); 16310 16311 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16312 final int callingPid = Binder.getCallingPid(); 16313 final int callingUid = Binder.getCallingUid(); 16314 final long origId = Binder.clearCallingIdentity(); 16315 int res = broadcastIntentLocked(callerApp, 16316 callerApp != null ? callerApp.info.packageName : null, 16317 intent, resolvedType, resultTo, 16318 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16319 callingPid, callingUid, userId); 16320 Binder.restoreCallingIdentity(origId); 16321 return res; 16322 } 16323 } 16324 16325 int broadcastIntentInPackage(String packageName, int uid, 16326 Intent intent, String resolvedType, IIntentReceiver resultTo, 16327 int resultCode, String resultData, Bundle map, 16328 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16329 synchronized(this) { 16330 intent = verifyBroadcastLocked(intent); 16331 16332 final long origId = Binder.clearCallingIdentity(); 16333 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16334 resultTo, resultCode, resultData, map, requiredPermission, 16335 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16336 Binder.restoreCallingIdentity(origId); 16337 return res; 16338 } 16339 } 16340 16341 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16342 // Refuse possible leaked file descriptors 16343 if (intent != null && intent.hasFileDescriptors() == true) { 16344 throw new IllegalArgumentException("File descriptors passed in Intent"); 16345 } 16346 16347 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16348 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16349 16350 synchronized(this) { 16351 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16352 != PackageManager.PERMISSION_GRANTED) { 16353 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16354 + Binder.getCallingPid() 16355 + ", uid=" + Binder.getCallingUid() 16356 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16357 Slog.w(TAG, msg); 16358 throw new SecurityException(msg); 16359 } 16360 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16361 if (stickies != null) { 16362 ArrayList<Intent> list = stickies.get(intent.getAction()); 16363 if (list != null) { 16364 int N = list.size(); 16365 int i; 16366 for (i=0; i<N; i++) { 16367 if (intent.filterEquals(list.get(i))) { 16368 list.remove(i); 16369 break; 16370 } 16371 } 16372 if (list.size() <= 0) { 16373 stickies.remove(intent.getAction()); 16374 } 16375 } 16376 if (stickies.size() <= 0) { 16377 mStickyBroadcasts.remove(userId); 16378 } 16379 } 16380 } 16381 } 16382 16383 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16384 String resultData, Bundle resultExtras, boolean resultAbort) { 16385 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16386 if (r == null) { 16387 Slog.w(TAG, "finishReceiver called but not found on queue"); 16388 return false; 16389 } 16390 16391 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16392 } 16393 16394 void backgroundServicesFinishedLocked(int userId) { 16395 for (BroadcastQueue queue : mBroadcastQueues) { 16396 queue.backgroundServicesFinishedLocked(userId); 16397 } 16398 } 16399 16400 public void finishReceiver(IBinder who, int resultCode, String resultData, 16401 Bundle resultExtras, boolean resultAbort) { 16402 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16403 16404 // Refuse possible leaked file descriptors 16405 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16406 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16407 } 16408 16409 final long origId = Binder.clearCallingIdentity(); 16410 try { 16411 boolean doNext = false; 16412 BroadcastRecord r; 16413 16414 synchronized(this) { 16415 r = broadcastRecordForReceiverLocked(who); 16416 if (r != null) { 16417 doNext = r.queue.finishReceiverLocked(r, resultCode, 16418 resultData, resultExtras, resultAbort, true); 16419 } 16420 } 16421 16422 if (doNext) { 16423 r.queue.processNextBroadcast(false); 16424 } 16425 trimApplications(); 16426 } finally { 16427 Binder.restoreCallingIdentity(origId); 16428 } 16429 } 16430 16431 // ========================================================= 16432 // INSTRUMENTATION 16433 // ========================================================= 16434 16435 public boolean startInstrumentation(ComponentName className, 16436 String profileFile, int flags, Bundle arguments, 16437 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16438 int userId, String abiOverride) { 16439 enforceNotIsolatedCaller("startInstrumentation"); 16440 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16441 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16442 // Refuse possible leaked file descriptors 16443 if (arguments != null && arguments.hasFileDescriptors()) { 16444 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16445 } 16446 16447 synchronized(this) { 16448 InstrumentationInfo ii = null; 16449 ApplicationInfo ai = null; 16450 try { 16451 ii = mContext.getPackageManager().getInstrumentationInfo( 16452 className, STOCK_PM_FLAGS); 16453 ai = AppGlobals.getPackageManager().getApplicationInfo( 16454 ii.targetPackage, STOCK_PM_FLAGS, userId); 16455 } catch (PackageManager.NameNotFoundException e) { 16456 } catch (RemoteException e) { 16457 } 16458 if (ii == null) { 16459 reportStartInstrumentationFailure(watcher, className, 16460 "Unable to find instrumentation info for: " + className); 16461 return false; 16462 } 16463 if (ai == null) { 16464 reportStartInstrumentationFailure(watcher, className, 16465 "Unable to find instrumentation target package: " + ii.targetPackage); 16466 return false; 16467 } 16468 16469 int match = mContext.getPackageManager().checkSignatures( 16470 ii.targetPackage, ii.packageName); 16471 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16472 String msg = "Permission Denial: starting instrumentation " 16473 + className + " from pid=" 16474 + Binder.getCallingPid() 16475 + ", uid=" + Binder.getCallingPid() 16476 + " not allowed because package " + ii.packageName 16477 + " does not have a signature matching the target " 16478 + ii.targetPackage; 16479 reportStartInstrumentationFailure(watcher, className, msg); 16480 throw new SecurityException(msg); 16481 } 16482 16483 final long origId = Binder.clearCallingIdentity(); 16484 // Instrumentation can kill and relaunch even persistent processes 16485 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16486 "start instr"); 16487 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16488 app.instrumentationClass = className; 16489 app.instrumentationInfo = ai; 16490 app.instrumentationProfileFile = profileFile; 16491 app.instrumentationArguments = arguments; 16492 app.instrumentationWatcher = watcher; 16493 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16494 app.instrumentationResultClass = className; 16495 Binder.restoreCallingIdentity(origId); 16496 } 16497 16498 return true; 16499 } 16500 16501 /** 16502 * Report errors that occur while attempting to start Instrumentation. Always writes the 16503 * error to the logs, but if somebody is watching, send the report there too. This enables 16504 * the "am" command to report errors with more information. 16505 * 16506 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16507 * @param cn The component name of the instrumentation. 16508 * @param report The error report. 16509 */ 16510 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16511 ComponentName cn, String report) { 16512 Slog.w(TAG, report); 16513 try { 16514 if (watcher != null) { 16515 Bundle results = new Bundle(); 16516 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16517 results.putString("Error", report); 16518 watcher.instrumentationStatus(cn, -1, results); 16519 } 16520 } catch (RemoteException e) { 16521 Slog.w(TAG, e); 16522 } 16523 } 16524 16525 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16526 if (app.instrumentationWatcher != null) { 16527 try { 16528 // NOTE: IInstrumentationWatcher *must* be oneway here 16529 app.instrumentationWatcher.instrumentationFinished( 16530 app.instrumentationClass, 16531 resultCode, 16532 results); 16533 } catch (RemoteException e) { 16534 } 16535 } 16536 if (app.instrumentationUiAutomationConnection != null) { 16537 try { 16538 app.instrumentationUiAutomationConnection.shutdown(); 16539 } catch (RemoteException re) { 16540 /* ignore */ 16541 } 16542 // Only a UiAutomation can set this flag and now that 16543 // it is finished we make sure it is reset to its default. 16544 mUserIsMonkey = false; 16545 } 16546 app.instrumentationWatcher = null; 16547 app.instrumentationUiAutomationConnection = null; 16548 app.instrumentationClass = null; 16549 app.instrumentationInfo = null; 16550 app.instrumentationProfileFile = null; 16551 app.instrumentationArguments = null; 16552 16553 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16554 "finished inst"); 16555 } 16556 16557 public void finishInstrumentation(IApplicationThread target, 16558 int resultCode, Bundle results) { 16559 int userId = UserHandle.getCallingUserId(); 16560 // Refuse possible leaked file descriptors 16561 if (results != null && results.hasFileDescriptors()) { 16562 throw new IllegalArgumentException("File descriptors passed in Intent"); 16563 } 16564 16565 synchronized(this) { 16566 ProcessRecord app = getRecordForAppLocked(target); 16567 if (app == null) { 16568 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16569 return; 16570 } 16571 final long origId = Binder.clearCallingIdentity(); 16572 finishInstrumentationLocked(app, resultCode, results); 16573 Binder.restoreCallingIdentity(origId); 16574 } 16575 } 16576 16577 // ========================================================= 16578 // CONFIGURATION 16579 // ========================================================= 16580 16581 public ConfigurationInfo getDeviceConfigurationInfo() { 16582 ConfigurationInfo config = new ConfigurationInfo(); 16583 synchronized (this) { 16584 config.reqTouchScreen = mConfiguration.touchscreen; 16585 config.reqKeyboardType = mConfiguration.keyboard; 16586 config.reqNavigation = mConfiguration.navigation; 16587 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16588 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16589 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16590 } 16591 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16592 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16593 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16594 } 16595 config.reqGlEsVersion = GL_ES_VERSION; 16596 } 16597 return config; 16598 } 16599 16600 ActivityStack getFocusedStack() { 16601 return mStackSupervisor.getFocusedStack(); 16602 } 16603 16604 public Configuration getConfiguration() { 16605 Configuration ci; 16606 synchronized(this) { 16607 ci = new Configuration(mConfiguration); 16608 } 16609 return ci; 16610 } 16611 16612 public void updatePersistentConfiguration(Configuration values) { 16613 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16614 "updateConfiguration()"); 16615 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16616 "updateConfiguration()"); 16617 if (values == null) { 16618 throw new NullPointerException("Configuration must not be null"); 16619 } 16620 16621 synchronized(this) { 16622 final long origId = Binder.clearCallingIdentity(); 16623 updateConfigurationLocked(values, null, true, false); 16624 Binder.restoreCallingIdentity(origId); 16625 } 16626 } 16627 16628 public void updateConfiguration(Configuration values) { 16629 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16630 "updateConfiguration()"); 16631 16632 synchronized(this) { 16633 if (values == null && mWindowManager != null) { 16634 // sentinel: fetch the current configuration from the window manager 16635 values = mWindowManager.computeNewConfiguration(); 16636 } 16637 16638 if (mWindowManager != null) { 16639 mProcessList.applyDisplaySize(mWindowManager); 16640 } 16641 16642 final long origId = Binder.clearCallingIdentity(); 16643 if (values != null) { 16644 Settings.System.clearConfiguration(values); 16645 } 16646 updateConfigurationLocked(values, null, false, false); 16647 Binder.restoreCallingIdentity(origId); 16648 } 16649 } 16650 16651 /** 16652 * Do either or both things: (1) change the current configuration, and (2) 16653 * make sure the given activity is running with the (now) current 16654 * configuration. Returns true if the activity has been left running, or 16655 * false if <var>starting</var> is being destroyed to match the new 16656 * configuration. 16657 * @param persistent TODO 16658 */ 16659 boolean updateConfigurationLocked(Configuration values, 16660 ActivityRecord starting, boolean persistent, boolean initLocale) { 16661 int changes = 0; 16662 16663 if (values != null) { 16664 Configuration newConfig = new Configuration(mConfiguration); 16665 changes = newConfig.updateFrom(values); 16666 if (changes != 0) { 16667 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16668 Slog.i(TAG, "Updating configuration to: " + values); 16669 } 16670 16671 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16672 16673 if (values.locale != null && !initLocale) { 16674 saveLocaleLocked(values.locale, 16675 !values.locale.equals(mConfiguration.locale), 16676 values.userSetLocale); 16677 } 16678 16679 mConfigurationSeq++; 16680 if (mConfigurationSeq <= 0) { 16681 mConfigurationSeq = 1; 16682 } 16683 newConfig.seq = mConfigurationSeq; 16684 mConfiguration = newConfig; 16685 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16686 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16687 //mUsageStatsService.noteStartConfig(newConfig); 16688 16689 final Configuration configCopy = new Configuration(mConfiguration); 16690 16691 // TODO: If our config changes, should we auto dismiss any currently 16692 // showing dialogs? 16693 mShowDialogs = shouldShowDialogs(newConfig); 16694 16695 AttributeCache ac = AttributeCache.instance(); 16696 if (ac != null) { 16697 ac.updateConfiguration(configCopy); 16698 } 16699 16700 // Make sure all resources in our process are updated 16701 // right now, so that anyone who is going to retrieve 16702 // resource values after we return will be sure to get 16703 // the new ones. This is especially important during 16704 // boot, where the first config change needs to guarantee 16705 // all resources have that config before following boot 16706 // code is executed. 16707 mSystemThread.applyConfigurationToResources(configCopy); 16708 16709 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16710 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16711 msg.obj = new Configuration(configCopy); 16712 mHandler.sendMessage(msg); 16713 } 16714 16715 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16716 ProcessRecord app = mLruProcesses.get(i); 16717 try { 16718 if (app.thread != null) { 16719 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16720 + app.processName + " new config " + mConfiguration); 16721 app.thread.scheduleConfigurationChanged(configCopy); 16722 } 16723 } catch (Exception e) { 16724 } 16725 } 16726 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16727 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16728 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16729 | Intent.FLAG_RECEIVER_FOREGROUND); 16730 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16731 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16732 Process.SYSTEM_UID, UserHandle.USER_ALL); 16733 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16734 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16735 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16736 broadcastIntentLocked(null, null, intent, 16737 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16738 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16739 } 16740 } 16741 } 16742 16743 boolean kept = true; 16744 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16745 // mainStack is null during startup. 16746 if (mainStack != null) { 16747 if (changes != 0 && starting == null) { 16748 // If the configuration changed, and the caller is not already 16749 // in the process of starting an activity, then find the top 16750 // activity to check if its configuration needs to change. 16751 starting = mainStack.topRunningActivityLocked(null); 16752 } 16753 16754 if (starting != null) { 16755 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16756 // And we need to make sure at this point that all other activities 16757 // are made visible with the correct configuration. 16758 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16759 } 16760 } 16761 16762 if (values != null && mWindowManager != null) { 16763 mWindowManager.setNewConfiguration(mConfiguration); 16764 } 16765 16766 return kept; 16767 } 16768 16769 /** 16770 * Decide based on the configuration whether we should shouw the ANR, 16771 * crash, etc dialogs. The idea is that if there is no affordnace to 16772 * press the on-screen buttons, we shouldn't show the dialog. 16773 * 16774 * A thought: SystemUI might also want to get told about this, the Power 16775 * dialog / global actions also might want different behaviors. 16776 */ 16777 private static final boolean shouldShowDialogs(Configuration config) { 16778 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16779 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16780 } 16781 16782 /** 16783 * Save the locale. You must be inside a synchronized (this) block. 16784 */ 16785 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16786 if(isDiff) { 16787 SystemProperties.set("user.language", l.getLanguage()); 16788 SystemProperties.set("user.region", l.getCountry()); 16789 } 16790 16791 if(isPersist) { 16792 SystemProperties.set("persist.sys.language", l.getLanguage()); 16793 SystemProperties.set("persist.sys.country", l.getCountry()); 16794 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16795 16796 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16797 } 16798 } 16799 16800 @Override 16801 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16802 synchronized (this) { 16803 ActivityRecord srec = ActivityRecord.forToken(token); 16804 if (srec.task != null && srec.task.stack != null) { 16805 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16806 } 16807 } 16808 return false; 16809 } 16810 16811 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16812 Intent resultData) { 16813 16814 synchronized (this) { 16815 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16816 if (stack != null) { 16817 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16818 } 16819 return false; 16820 } 16821 } 16822 16823 public int getLaunchedFromUid(IBinder activityToken) { 16824 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16825 if (srec == null) { 16826 return -1; 16827 } 16828 return srec.launchedFromUid; 16829 } 16830 16831 public String getLaunchedFromPackage(IBinder activityToken) { 16832 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16833 if (srec == null) { 16834 return null; 16835 } 16836 return srec.launchedFromPackage; 16837 } 16838 16839 // ========================================================= 16840 // LIFETIME MANAGEMENT 16841 // ========================================================= 16842 16843 // Returns which broadcast queue the app is the current [or imminent] receiver 16844 // on, or 'null' if the app is not an active broadcast recipient. 16845 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16846 BroadcastRecord r = app.curReceiver; 16847 if (r != null) { 16848 return r.queue; 16849 } 16850 16851 // It's not the current receiver, but it might be starting up to become one 16852 synchronized (this) { 16853 for (BroadcastQueue queue : mBroadcastQueues) { 16854 r = queue.mPendingBroadcast; 16855 if (r != null && r.curApp == app) { 16856 // found it; report which queue it's in 16857 return queue; 16858 } 16859 } 16860 } 16861 16862 return null; 16863 } 16864 16865 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16866 ComponentName targetComponent, String targetProcess) { 16867 if (!mTrackingAssociations) { 16868 return null; 16869 } 16870 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16871 = mAssociations.get(targetUid); 16872 if (components == null) { 16873 components = new ArrayMap<>(); 16874 mAssociations.put(targetUid, components); 16875 } 16876 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16877 if (sourceUids == null) { 16878 sourceUids = new SparseArray<>(); 16879 components.put(targetComponent, sourceUids); 16880 } 16881 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16882 if (sourceProcesses == null) { 16883 sourceProcesses = new ArrayMap<>(); 16884 sourceUids.put(sourceUid, sourceProcesses); 16885 } 16886 Association ass = sourceProcesses.get(sourceProcess); 16887 if (ass == null) { 16888 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16889 targetProcess); 16890 sourceProcesses.put(sourceProcess, ass); 16891 } 16892 ass.mCount++; 16893 ass.mNesting++; 16894 if (ass.mNesting == 1) { 16895 ass.mStartTime = SystemClock.uptimeMillis(); 16896 } 16897 return ass; 16898 } 16899 16900 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16901 ComponentName targetComponent) { 16902 if (!mTrackingAssociations) { 16903 return; 16904 } 16905 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16906 = mAssociations.get(targetUid); 16907 if (components == null) { 16908 return; 16909 } 16910 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16911 if (sourceUids == null) { 16912 return; 16913 } 16914 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16915 if (sourceProcesses == null) { 16916 return; 16917 } 16918 Association ass = sourceProcesses.get(sourceProcess); 16919 if (ass == null || ass.mNesting <= 0) { 16920 return; 16921 } 16922 ass.mNesting--; 16923 if (ass.mNesting == 0) { 16924 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16925 } 16926 } 16927 16928 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16929 boolean doingAll, long now) { 16930 if (mAdjSeq == app.adjSeq) { 16931 // This adjustment has already been computed. 16932 return app.curRawAdj; 16933 } 16934 16935 if (app.thread == null) { 16936 app.adjSeq = mAdjSeq; 16937 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16938 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16939 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16940 } 16941 16942 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16943 app.adjSource = null; 16944 app.adjTarget = null; 16945 app.empty = false; 16946 app.cached = false; 16947 16948 final int activitiesSize = app.activities.size(); 16949 16950 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16951 // The max adjustment doesn't allow this app to be anything 16952 // below foreground, so it is not worth doing work for it. 16953 app.adjType = "fixed"; 16954 app.adjSeq = mAdjSeq; 16955 app.curRawAdj = app.maxAdj; 16956 app.foregroundActivities = false; 16957 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16958 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16959 // System processes can do UI, and when they do we want to have 16960 // them trim their memory after the user leaves the UI. To 16961 // facilitate this, here we need to determine whether or not it 16962 // is currently showing UI. 16963 app.systemNoUi = true; 16964 if (app == TOP_APP) { 16965 app.systemNoUi = false; 16966 } else if (activitiesSize > 0) { 16967 for (int j = 0; j < activitiesSize; j++) { 16968 final ActivityRecord r = app.activities.get(j); 16969 if (r.visible) { 16970 app.systemNoUi = false; 16971 } 16972 } 16973 } 16974 if (!app.systemNoUi) { 16975 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16976 } 16977 return (app.curAdj=app.maxAdj); 16978 } 16979 16980 app.systemNoUi = false; 16981 16982 // Determine the importance of the process, starting with most 16983 // important to least, and assign an appropriate OOM adjustment. 16984 int adj; 16985 int schedGroup; 16986 int procState; 16987 boolean foregroundActivities = false; 16988 BroadcastQueue queue; 16989 if (app == TOP_APP) { 16990 // The last app on the list is the foreground app. 16991 adj = ProcessList.FOREGROUND_APP_ADJ; 16992 schedGroup = Process.THREAD_GROUP_DEFAULT; 16993 app.adjType = "top-activity"; 16994 foregroundActivities = true; 16995 procState = ActivityManager.PROCESS_STATE_TOP; 16996 } else if (app.instrumentationClass != null) { 16997 // Don't want to kill running instrumentation. 16998 adj = ProcessList.FOREGROUND_APP_ADJ; 16999 schedGroup = Process.THREAD_GROUP_DEFAULT; 17000 app.adjType = "instrumentation"; 17001 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17002 } else if ((queue = isReceivingBroadcast(app)) != null) { 17003 // An app that is currently receiving a broadcast also 17004 // counts as being in the foreground for OOM killer purposes. 17005 // It's placed in a sched group based on the nature of the 17006 // broadcast as reflected by which queue it's active in. 17007 adj = ProcessList.FOREGROUND_APP_ADJ; 17008 schedGroup = (queue == mFgBroadcastQueue) 17009 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17010 app.adjType = "broadcast"; 17011 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17012 } else if (app.executingServices.size() > 0) { 17013 // An app that is currently executing a service callback also 17014 // counts as being in the foreground. 17015 adj = ProcessList.FOREGROUND_APP_ADJ; 17016 schedGroup = app.execServicesFg ? 17017 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17018 app.adjType = "exec-service"; 17019 procState = ActivityManager.PROCESS_STATE_SERVICE; 17020 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17021 } else { 17022 // As far as we know the process is empty. We may change our mind later. 17023 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17024 // At this point we don't actually know the adjustment. Use the cached adj 17025 // value that the caller wants us to. 17026 adj = cachedAdj; 17027 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17028 app.cached = true; 17029 app.empty = true; 17030 app.adjType = "cch-empty"; 17031 } 17032 17033 // Examine all activities if not already foreground. 17034 if (!foregroundActivities && activitiesSize > 0) { 17035 for (int j = 0; j < activitiesSize; j++) { 17036 final ActivityRecord r = app.activities.get(j); 17037 if (r.app != app) { 17038 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17039 + app + "?!?"); 17040 continue; 17041 } 17042 if (r.visible) { 17043 // App has a visible activity; only upgrade adjustment. 17044 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17045 adj = ProcessList.VISIBLE_APP_ADJ; 17046 app.adjType = "visible"; 17047 } 17048 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17049 procState = ActivityManager.PROCESS_STATE_TOP; 17050 } 17051 schedGroup = Process.THREAD_GROUP_DEFAULT; 17052 app.cached = false; 17053 app.empty = false; 17054 foregroundActivities = true; 17055 break; 17056 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17057 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17058 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17059 app.adjType = "pausing"; 17060 } 17061 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17062 procState = ActivityManager.PROCESS_STATE_TOP; 17063 } 17064 schedGroup = Process.THREAD_GROUP_DEFAULT; 17065 app.cached = false; 17066 app.empty = false; 17067 foregroundActivities = true; 17068 } else if (r.state == ActivityState.STOPPING) { 17069 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17070 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17071 app.adjType = "stopping"; 17072 } 17073 // For the process state, we will at this point consider the 17074 // process to be cached. It will be cached either as an activity 17075 // or empty depending on whether the activity is finishing. We do 17076 // this so that we can treat the process as cached for purposes of 17077 // memory trimming (determing current memory level, trim command to 17078 // send to process) since there can be an arbitrary number of stopping 17079 // processes and they should soon all go into the cached state. 17080 if (!r.finishing) { 17081 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17082 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17083 } 17084 } 17085 app.cached = false; 17086 app.empty = false; 17087 foregroundActivities = true; 17088 } else { 17089 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17090 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17091 app.adjType = "cch-act"; 17092 } 17093 } 17094 } 17095 } 17096 17097 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17098 if (app.foregroundServices) { 17099 // The user is aware of this app, so make it visible. 17100 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17101 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17102 app.cached = false; 17103 app.adjType = "fg-service"; 17104 schedGroup = Process.THREAD_GROUP_DEFAULT; 17105 } else if (app.forcingToForeground != null) { 17106 // The user is aware of this app, so make it visible. 17107 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17108 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17109 app.cached = false; 17110 app.adjType = "force-fg"; 17111 app.adjSource = app.forcingToForeground; 17112 schedGroup = Process.THREAD_GROUP_DEFAULT; 17113 } 17114 } 17115 17116 if (app == mHeavyWeightProcess) { 17117 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17118 // We don't want to kill the current heavy-weight process. 17119 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17120 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17121 app.cached = false; 17122 app.adjType = "heavy"; 17123 } 17124 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17125 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17126 } 17127 } 17128 17129 if (app == mHomeProcess) { 17130 if (adj > ProcessList.HOME_APP_ADJ) { 17131 // This process is hosting what we currently consider to be the 17132 // home app, so we don't want to let it go into the background. 17133 adj = ProcessList.HOME_APP_ADJ; 17134 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17135 app.cached = false; 17136 app.adjType = "home"; 17137 } 17138 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17139 procState = ActivityManager.PROCESS_STATE_HOME; 17140 } 17141 } 17142 17143 if (app == mPreviousProcess && app.activities.size() > 0) { 17144 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17145 // This was the previous process that showed UI to the user. 17146 // We want to try to keep it around more aggressively, to give 17147 // a good experience around switching between two apps. 17148 adj = ProcessList.PREVIOUS_APP_ADJ; 17149 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17150 app.cached = false; 17151 app.adjType = "previous"; 17152 } 17153 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17154 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17155 } 17156 } 17157 17158 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17159 + " reason=" + app.adjType); 17160 17161 // By default, we use the computed adjustment. It may be changed if 17162 // there are applications dependent on our services or providers, but 17163 // this gives us a baseline and makes sure we don't get into an 17164 // infinite recursion. 17165 app.adjSeq = mAdjSeq; 17166 app.curRawAdj = adj; 17167 app.hasStartedServices = false; 17168 17169 if (mBackupTarget != null && app == mBackupTarget.app) { 17170 // If possible we want to avoid killing apps while they're being backed up 17171 if (adj > ProcessList.BACKUP_APP_ADJ) { 17172 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17173 adj = ProcessList.BACKUP_APP_ADJ; 17174 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17175 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17176 } 17177 app.adjType = "backup"; 17178 app.cached = false; 17179 } 17180 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17181 procState = ActivityManager.PROCESS_STATE_BACKUP; 17182 } 17183 } 17184 17185 boolean mayBeTop = false; 17186 17187 for (int is = app.services.size()-1; 17188 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17189 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17190 || procState > ActivityManager.PROCESS_STATE_TOP); 17191 is--) { 17192 ServiceRecord s = app.services.valueAt(is); 17193 if (s.startRequested) { 17194 app.hasStartedServices = true; 17195 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17196 procState = ActivityManager.PROCESS_STATE_SERVICE; 17197 } 17198 if (app.hasShownUi && app != mHomeProcess) { 17199 // If this process has shown some UI, let it immediately 17200 // go to the LRU list because it may be pretty heavy with 17201 // UI stuff. We'll tag it with a label just to help 17202 // debug and understand what is going on. 17203 if (adj > ProcessList.SERVICE_ADJ) { 17204 app.adjType = "cch-started-ui-services"; 17205 } 17206 } else { 17207 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17208 // This service has seen some activity within 17209 // recent memory, so we will keep its process ahead 17210 // of the background processes. 17211 if (adj > ProcessList.SERVICE_ADJ) { 17212 adj = ProcessList.SERVICE_ADJ; 17213 app.adjType = "started-services"; 17214 app.cached = false; 17215 } 17216 } 17217 // If we have let the service slide into the background 17218 // state, still have some text describing what it is doing 17219 // even though the service no longer has an impact. 17220 if (adj > ProcessList.SERVICE_ADJ) { 17221 app.adjType = "cch-started-services"; 17222 } 17223 } 17224 } 17225 for (int conni = s.connections.size()-1; 17226 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17227 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17228 || procState > ActivityManager.PROCESS_STATE_TOP); 17229 conni--) { 17230 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17231 for (int i = 0; 17232 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17233 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17234 || procState > ActivityManager.PROCESS_STATE_TOP); 17235 i++) { 17236 // XXX should compute this based on the max of 17237 // all connected clients. 17238 ConnectionRecord cr = clist.get(i); 17239 if (cr.binding.client == app) { 17240 // Binding to ourself is not interesting. 17241 continue; 17242 } 17243 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17244 ProcessRecord client = cr.binding.client; 17245 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17246 TOP_APP, doingAll, now); 17247 int clientProcState = client.curProcState; 17248 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17249 // If the other app is cached for any reason, for purposes here 17250 // we are going to consider it empty. The specific cached state 17251 // doesn't propagate except under certain conditions. 17252 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17253 } 17254 String adjType = null; 17255 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17256 // Not doing bind OOM management, so treat 17257 // this guy more like a started service. 17258 if (app.hasShownUi && app != mHomeProcess) { 17259 // If this process has shown some UI, let it immediately 17260 // go to the LRU list because it may be pretty heavy with 17261 // UI stuff. We'll tag it with a label just to help 17262 // debug and understand what is going on. 17263 if (adj > clientAdj) { 17264 adjType = "cch-bound-ui-services"; 17265 } 17266 app.cached = false; 17267 clientAdj = adj; 17268 clientProcState = procState; 17269 } else { 17270 if (now >= (s.lastActivity 17271 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17272 // This service has not seen activity within 17273 // recent memory, so allow it to drop to the 17274 // LRU list if there is no other reason to keep 17275 // it around. We'll also tag it with a label just 17276 // to help debug and undertand what is going on. 17277 if (adj > clientAdj) { 17278 adjType = "cch-bound-services"; 17279 } 17280 clientAdj = adj; 17281 } 17282 } 17283 } 17284 if (adj > clientAdj) { 17285 // If this process has recently shown UI, and 17286 // the process that is binding to it is less 17287 // important than being visible, then we don't 17288 // care about the binding as much as we care 17289 // about letting this process get into the LRU 17290 // list to be killed and restarted if needed for 17291 // memory. 17292 if (app.hasShownUi && app != mHomeProcess 17293 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17294 adjType = "cch-bound-ui-services"; 17295 } else { 17296 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17297 |Context.BIND_IMPORTANT)) != 0) { 17298 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17299 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17300 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17301 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17302 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17303 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17304 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17305 adj = clientAdj; 17306 } else { 17307 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17308 adj = ProcessList.VISIBLE_APP_ADJ; 17309 } 17310 } 17311 if (!client.cached) { 17312 app.cached = false; 17313 } 17314 adjType = "service"; 17315 } 17316 } 17317 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17318 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17319 schedGroup = Process.THREAD_GROUP_DEFAULT; 17320 } 17321 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17322 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17323 // Special handling of clients who are in the top state. 17324 // We *may* want to consider this process to be in the 17325 // top state as well, but only if there is not another 17326 // reason for it to be running. Being on the top is a 17327 // special state, meaning you are specifically running 17328 // for the current top app. If the process is already 17329 // running in the background for some other reason, it 17330 // is more important to continue considering it to be 17331 // in the background state. 17332 mayBeTop = true; 17333 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17334 } else { 17335 // Special handling for above-top states (persistent 17336 // processes). These should not bring the current process 17337 // into the top state, since they are not on top. Instead 17338 // give them the best state after that. 17339 clientProcState = 17340 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17341 } 17342 } 17343 } else { 17344 if (clientProcState < 17345 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17346 clientProcState = 17347 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17348 } 17349 } 17350 if (procState > clientProcState) { 17351 procState = clientProcState; 17352 } 17353 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17354 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17355 app.pendingUiClean = true; 17356 } 17357 if (adjType != null) { 17358 app.adjType = adjType; 17359 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17360 .REASON_SERVICE_IN_USE; 17361 app.adjSource = cr.binding.client; 17362 app.adjSourceProcState = clientProcState; 17363 app.adjTarget = s.name; 17364 } 17365 } 17366 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17367 app.treatLikeActivity = true; 17368 } 17369 final ActivityRecord a = cr.activity; 17370 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17371 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17372 (a.visible || a.state == ActivityState.RESUMED 17373 || a.state == ActivityState.PAUSING)) { 17374 adj = ProcessList.FOREGROUND_APP_ADJ; 17375 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17376 schedGroup = Process.THREAD_GROUP_DEFAULT; 17377 } 17378 app.cached = false; 17379 app.adjType = "service"; 17380 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17381 .REASON_SERVICE_IN_USE; 17382 app.adjSource = a; 17383 app.adjSourceProcState = procState; 17384 app.adjTarget = s.name; 17385 } 17386 } 17387 } 17388 } 17389 } 17390 17391 for (int provi = app.pubProviders.size()-1; 17392 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17393 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17394 || procState > ActivityManager.PROCESS_STATE_TOP); 17395 provi--) { 17396 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17397 for (int i = cpr.connections.size()-1; 17398 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17399 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17400 || procState > ActivityManager.PROCESS_STATE_TOP); 17401 i--) { 17402 ContentProviderConnection conn = cpr.connections.get(i); 17403 ProcessRecord client = conn.client; 17404 if (client == app) { 17405 // Being our own client is not interesting. 17406 continue; 17407 } 17408 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17409 int clientProcState = client.curProcState; 17410 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17411 // If the other app is cached for any reason, for purposes here 17412 // we are going to consider it empty. 17413 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17414 } 17415 if (adj > clientAdj) { 17416 if (app.hasShownUi && app != mHomeProcess 17417 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17418 app.adjType = "cch-ui-provider"; 17419 } else { 17420 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17421 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17422 app.adjType = "provider"; 17423 } 17424 app.cached &= client.cached; 17425 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17426 .REASON_PROVIDER_IN_USE; 17427 app.adjSource = client; 17428 app.adjSourceProcState = clientProcState; 17429 app.adjTarget = cpr.name; 17430 } 17431 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17432 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17433 // Special handling of clients who are in the top state. 17434 // We *may* want to consider this process to be in the 17435 // top state as well, but only if there is not another 17436 // reason for it to be running. Being on the top is a 17437 // special state, meaning you are specifically running 17438 // for the current top app. If the process is already 17439 // running in the background for some other reason, it 17440 // is more important to continue considering it to be 17441 // in the background state. 17442 mayBeTop = true; 17443 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17444 } else { 17445 // Special handling for above-top states (persistent 17446 // processes). These should not bring the current process 17447 // into the top state, since they are not on top. Instead 17448 // give them the best state after that. 17449 clientProcState = 17450 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17451 } 17452 } 17453 if (procState > clientProcState) { 17454 procState = clientProcState; 17455 } 17456 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17457 schedGroup = Process.THREAD_GROUP_DEFAULT; 17458 } 17459 } 17460 // If the provider has external (non-framework) process 17461 // dependencies, ensure that its adjustment is at least 17462 // FOREGROUND_APP_ADJ. 17463 if (cpr.hasExternalProcessHandles()) { 17464 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17465 adj = ProcessList.FOREGROUND_APP_ADJ; 17466 schedGroup = Process.THREAD_GROUP_DEFAULT; 17467 app.cached = false; 17468 app.adjType = "provider"; 17469 app.adjTarget = cpr.name; 17470 } 17471 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17472 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17473 } 17474 } 17475 } 17476 17477 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17478 // A client of one of our services or providers is in the top state. We 17479 // *may* want to be in the top state, but not if we are already running in 17480 // the background for some other reason. For the decision here, we are going 17481 // to pick out a few specific states that we want to remain in when a client 17482 // is top (states that tend to be longer-term) and otherwise allow it to go 17483 // to the top state. 17484 switch (procState) { 17485 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17486 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17487 case ActivityManager.PROCESS_STATE_SERVICE: 17488 // These all are longer-term states, so pull them up to the top 17489 // of the background states, but not all the way to the top state. 17490 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17491 break; 17492 default: 17493 // Otherwise, top is a better choice, so take it. 17494 procState = ActivityManager.PROCESS_STATE_TOP; 17495 break; 17496 } 17497 } 17498 17499 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17500 if (app.hasClientActivities) { 17501 // This is a cached process, but with client activities. Mark it so. 17502 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17503 app.adjType = "cch-client-act"; 17504 } else if (app.treatLikeActivity) { 17505 // This is a cached process, but somebody wants us to treat it like it has 17506 // an activity, okay! 17507 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17508 app.adjType = "cch-as-act"; 17509 } 17510 } 17511 17512 if (adj == ProcessList.SERVICE_ADJ) { 17513 if (doingAll) { 17514 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17515 mNewNumServiceProcs++; 17516 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17517 if (!app.serviceb) { 17518 // This service isn't far enough down on the LRU list to 17519 // normally be a B service, but if we are low on RAM and it 17520 // is large we want to force it down since we would prefer to 17521 // keep launcher over it. 17522 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17523 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17524 app.serviceHighRam = true; 17525 app.serviceb = true; 17526 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17527 } else { 17528 mNewNumAServiceProcs++; 17529 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17530 } 17531 } else { 17532 app.serviceHighRam = false; 17533 } 17534 } 17535 if (app.serviceb) { 17536 adj = ProcessList.SERVICE_B_ADJ; 17537 } 17538 } 17539 17540 app.curRawAdj = adj; 17541 17542 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17543 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17544 if (adj > app.maxAdj) { 17545 adj = app.maxAdj; 17546 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17547 schedGroup = Process.THREAD_GROUP_DEFAULT; 17548 } 17549 } 17550 17551 // Do final modification to adj. Everything we do between here and applying 17552 // the final setAdj must be done in this function, because we will also use 17553 // it when computing the final cached adj later. Note that we don't need to 17554 // worry about this for max adj above, since max adj will always be used to 17555 // keep it out of the cached vaues. 17556 app.curAdj = app.modifyRawOomAdj(adj); 17557 app.curSchedGroup = schedGroup; 17558 app.curProcState = procState; 17559 app.foregroundActivities = foregroundActivities; 17560 17561 return app.curRawAdj; 17562 } 17563 17564 /** 17565 * Record new PSS sample for a process. 17566 */ 17567 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17568 proc.lastPssTime = now; 17569 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17570 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17571 + ": " + pss + " lastPss=" + proc.lastPss 17572 + " state=" + ProcessList.makeProcStateString(procState)); 17573 if (proc.initialIdlePss == 0) { 17574 proc.initialIdlePss = pss; 17575 } 17576 proc.lastPss = pss; 17577 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17578 proc.lastCachedPss = pss; 17579 } 17580 } 17581 17582 /** 17583 * Schedule PSS collection of a process. 17584 */ 17585 void requestPssLocked(ProcessRecord proc, int procState) { 17586 if (mPendingPssProcesses.contains(proc)) { 17587 return; 17588 } 17589 if (mPendingPssProcesses.size() == 0) { 17590 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17591 } 17592 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17593 proc.pssProcState = procState; 17594 mPendingPssProcesses.add(proc); 17595 } 17596 17597 /** 17598 * Schedule PSS collection of all processes. 17599 */ 17600 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17601 if (!always) { 17602 if (now < (mLastFullPssTime + 17603 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17604 return; 17605 } 17606 } 17607 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17608 mLastFullPssTime = now; 17609 mFullPssPending = true; 17610 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17611 mPendingPssProcesses.clear(); 17612 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17613 ProcessRecord app = mLruProcesses.get(i); 17614 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17615 app.pssProcState = app.setProcState; 17616 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17617 mTestPssMode, isSleeping(), now); 17618 mPendingPssProcesses.add(app); 17619 } 17620 } 17621 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17622 } 17623 17624 public void setTestPssMode(boolean enabled) { 17625 synchronized (this) { 17626 mTestPssMode = enabled; 17627 if (enabled) { 17628 // Whenever we enable the mode, we want to take a snapshot all of current 17629 // process mem use. 17630 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17631 } 17632 } 17633 } 17634 17635 /** 17636 * Ask a given process to GC right now. 17637 */ 17638 final void performAppGcLocked(ProcessRecord app) { 17639 try { 17640 app.lastRequestedGc = SystemClock.uptimeMillis(); 17641 if (app.thread != null) { 17642 if (app.reportLowMemory) { 17643 app.reportLowMemory = false; 17644 app.thread.scheduleLowMemory(); 17645 } else { 17646 app.thread.processInBackground(); 17647 } 17648 } 17649 } catch (Exception e) { 17650 // whatever. 17651 } 17652 } 17653 17654 /** 17655 * Returns true if things are idle enough to perform GCs. 17656 */ 17657 private final boolean canGcNowLocked() { 17658 boolean processingBroadcasts = false; 17659 for (BroadcastQueue q : mBroadcastQueues) { 17660 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17661 processingBroadcasts = true; 17662 } 17663 } 17664 return !processingBroadcasts 17665 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17666 } 17667 17668 /** 17669 * Perform GCs on all processes that are waiting for it, but only 17670 * if things are idle. 17671 */ 17672 final void performAppGcsLocked() { 17673 final int N = mProcessesToGc.size(); 17674 if (N <= 0) { 17675 return; 17676 } 17677 if (canGcNowLocked()) { 17678 while (mProcessesToGc.size() > 0) { 17679 ProcessRecord proc = mProcessesToGc.remove(0); 17680 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17681 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17682 <= SystemClock.uptimeMillis()) { 17683 // To avoid spamming the system, we will GC processes one 17684 // at a time, waiting a few seconds between each. 17685 performAppGcLocked(proc); 17686 scheduleAppGcsLocked(); 17687 return; 17688 } else { 17689 // It hasn't been long enough since we last GCed this 17690 // process... put it in the list to wait for its time. 17691 addProcessToGcListLocked(proc); 17692 break; 17693 } 17694 } 17695 } 17696 17697 scheduleAppGcsLocked(); 17698 } 17699 } 17700 17701 /** 17702 * If all looks good, perform GCs on all processes waiting for them. 17703 */ 17704 final void performAppGcsIfAppropriateLocked() { 17705 if (canGcNowLocked()) { 17706 performAppGcsLocked(); 17707 return; 17708 } 17709 // Still not idle, wait some more. 17710 scheduleAppGcsLocked(); 17711 } 17712 17713 /** 17714 * Schedule the execution of all pending app GCs. 17715 */ 17716 final void scheduleAppGcsLocked() { 17717 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17718 17719 if (mProcessesToGc.size() > 0) { 17720 // Schedule a GC for the time to the next process. 17721 ProcessRecord proc = mProcessesToGc.get(0); 17722 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17723 17724 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17725 long now = SystemClock.uptimeMillis(); 17726 if (when < (now+GC_TIMEOUT)) { 17727 when = now + GC_TIMEOUT; 17728 } 17729 mHandler.sendMessageAtTime(msg, when); 17730 } 17731 } 17732 17733 /** 17734 * Add a process to the array of processes waiting to be GCed. Keeps the 17735 * list in sorted order by the last GC time. The process can't already be 17736 * on the list. 17737 */ 17738 final void addProcessToGcListLocked(ProcessRecord proc) { 17739 boolean added = false; 17740 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17741 if (mProcessesToGc.get(i).lastRequestedGc < 17742 proc.lastRequestedGc) { 17743 added = true; 17744 mProcessesToGc.add(i+1, proc); 17745 break; 17746 } 17747 } 17748 if (!added) { 17749 mProcessesToGc.add(0, proc); 17750 } 17751 } 17752 17753 /** 17754 * Set up to ask a process to GC itself. This will either do it 17755 * immediately, or put it on the list of processes to gc the next 17756 * time things are idle. 17757 */ 17758 final void scheduleAppGcLocked(ProcessRecord app) { 17759 long now = SystemClock.uptimeMillis(); 17760 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17761 return; 17762 } 17763 if (!mProcessesToGc.contains(app)) { 17764 addProcessToGcListLocked(app); 17765 scheduleAppGcsLocked(); 17766 } 17767 } 17768 17769 final void checkExcessivePowerUsageLocked(boolean doKills) { 17770 updateCpuStatsNow(); 17771 17772 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17773 boolean doWakeKills = doKills; 17774 boolean doCpuKills = doKills; 17775 if (mLastPowerCheckRealtime == 0) { 17776 doWakeKills = false; 17777 } 17778 if (mLastPowerCheckUptime == 0) { 17779 doCpuKills = false; 17780 } 17781 if (stats.isScreenOn()) { 17782 doWakeKills = false; 17783 } 17784 final long curRealtime = SystemClock.elapsedRealtime(); 17785 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17786 final long curUptime = SystemClock.uptimeMillis(); 17787 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17788 mLastPowerCheckRealtime = curRealtime; 17789 mLastPowerCheckUptime = curUptime; 17790 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17791 doWakeKills = false; 17792 } 17793 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17794 doCpuKills = false; 17795 } 17796 int i = mLruProcesses.size(); 17797 while (i > 0) { 17798 i--; 17799 ProcessRecord app = mLruProcesses.get(i); 17800 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17801 long wtime; 17802 synchronized (stats) { 17803 wtime = stats.getProcessWakeTime(app.info.uid, 17804 app.pid, curRealtime); 17805 } 17806 long wtimeUsed = wtime - app.lastWakeTime; 17807 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17808 if (DEBUG_POWER) { 17809 StringBuilder sb = new StringBuilder(128); 17810 sb.append("Wake for "); 17811 app.toShortString(sb); 17812 sb.append(": over "); 17813 TimeUtils.formatDuration(realtimeSince, sb); 17814 sb.append(" used "); 17815 TimeUtils.formatDuration(wtimeUsed, sb); 17816 sb.append(" ("); 17817 sb.append((wtimeUsed*100)/realtimeSince); 17818 sb.append("%)"); 17819 Slog.i(TAG, sb.toString()); 17820 sb.setLength(0); 17821 sb.append("CPU for "); 17822 app.toShortString(sb); 17823 sb.append(": over "); 17824 TimeUtils.formatDuration(uptimeSince, sb); 17825 sb.append(" used "); 17826 TimeUtils.formatDuration(cputimeUsed, sb); 17827 sb.append(" ("); 17828 sb.append((cputimeUsed*100)/uptimeSince); 17829 sb.append("%)"); 17830 Slog.i(TAG, sb.toString()); 17831 } 17832 // If a process has held a wake lock for more 17833 // than 50% of the time during this period, 17834 // that sounds bad. Kill! 17835 if (doWakeKills && realtimeSince > 0 17836 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17837 synchronized (stats) { 17838 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17839 realtimeSince, wtimeUsed); 17840 } 17841 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17842 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17843 } else if (doCpuKills && uptimeSince > 0 17844 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17845 synchronized (stats) { 17846 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17847 uptimeSince, cputimeUsed); 17848 } 17849 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17850 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17851 } else { 17852 app.lastWakeTime = wtime; 17853 app.lastCpuTime = app.curCpuTime; 17854 } 17855 } 17856 } 17857 } 17858 17859 private final boolean applyOomAdjLocked(ProcessRecord app, 17860 ProcessRecord TOP_APP, boolean doingAll, long now) { 17861 boolean success = true; 17862 17863 if (app.curRawAdj != app.setRawAdj) { 17864 app.setRawAdj = app.curRawAdj; 17865 } 17866 17867 int changes = 0; 17868 17869 if (app.curAdj != app.setAdj) { 17870 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17871 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17872 TAG, "Set " + app.pid + " " + app.processName + 17873 " adj " + app.curAdj + ": " + app.adjType); 17874 app.setAdj = app.curAdj; 17875 } 17876 17877 if (app.setSchedGroup != app.curSchedGroup) { 17878 app.setSchedGroup = app.curSchedGroup; 17879 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17880 "Setting process group of " + app.processName 17881 + " to " + app.curSchedGroup); 17882 if (app.waitingToKill != null && 17883 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17884 app.kill(app.waitingToKill, true); 17885 success = false; 17886 } else { 17887 if (true) { 17888 long oldId = Binder.clearCallingIdentity(); 17889 try { 17890 Process.setProcessGroup(app.pid, app.curSchedGroup); 17891 } catch (Exception e) { 17892 Slog.w(TAG, "Failed setting process group of " + app.pid 17893 + " to " + app.curSchedGroup); 17894 e.printStackTrace(); 17895 } finally { 17896 Binder.restoreCallingIdentity(oldId); 17897 } 17898 } else { 17899 if (app.thread != null) { 17900 try { 17901 app.thread.setSchedulingGroup(app.curSchedGroup); 17902 } catch (RemoteException e) { 17903 } 17904 } 17905 } 17906 Process.setSwappiness(app.pid, 17907 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17908 } 17909 } 17910 if (app.repForegroundActivities != app.foregroundActivities) { 17911 app.repForegroundActivities = app.foregroundActivities; 17912 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17913 } 17914 if (app.repProcState != app.curProcState) { 17915 app.repProcState = app.curProcState; 17916 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17917 if (app.thread != null) { 17918 try { 17919 if (false) { 17920 //RuntimeException h = new RuntimeException("here"); 17921 Slog.i(TAG, "Sending new process state " + app.repProcState 17922 + " to " + app /*, h*/); 17923 } 17924 app.thread.setProcessState(app.repProcState); 17925 } catch (RemoteException e) { 17926 } 17927 } 17928 } 17929 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17930 app.setProcState)) { 17931 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17932 // Experimental code to more aggressively collect pss while 17933 // running test... the problem is that this tends to collect 17934 // the data right when a process is transitioning between process 17935 // states, which well tend to give noisy data. 17936 long start = SystemClock.uptimeMillis(); 17937 long pss = Debug.getPss(app.pid, mTmpLong, null); 17938 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17939 mPendingPssProcesses.remove(app); 17940 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17941 + " to " + app.curProcState + ": " 17942 + (SystemClock.uptimeMillis()-start) + "ms"); 17943 } 17944 app.lastStateTime = now; 17945 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17946 mTestPssMode, isSleeping(), now); 17947 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17948 + ProcessList.makeProcStateString(app.setProcState) + " to " 17949 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17950 + (app.nextPssTime-now) + ": " + app); 17951 } else { 17952 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17953 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17954 mTestPssMode)))) { 17955 requestPssLocked(app, app.setProcState); 17956 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17957 mTestPssMode, isSleeping(), now); 17958 } else if (false && DEBUG_PSS) { 17959 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17960 } 17961 } 17962 if (app.setProcState != app.curProcState) { 17963 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17964 "Proc state change of " + app.processName 17965 + " to " + app.curProcState); 17966 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17967 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17968 if (setImportant && !curImportant) { 17969 // This app is no longer something we consider important enough to allow to 17970 // use arbitrary amounts of battery power. Note 17971 // its current wake lock time to later know to kill it if 17972 // it is not behaving well. 17973 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17974 synchronized (stats) { 17975 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17976 app.pid, SystemClock.elapsedRealtime()); 17977 } 17978 app.lastCpuTime = app.curCpuTime; 17979 17980 } 17981 app.setProcState = app.curProcState; 17982 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17983 app.notCachedSinceIdle = false; 17984 } 17985 if (!doingAll) { 17986 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17987 } else { 17988 app.procStateChanged = true; 17989 } 17990 } 17991 17992 if (changes != 0) { 17993 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17994 int i = mPendingProcessChanges.size()-1; 17995 ProcessChangeItem item = null; 17996 while (i >= 0) { 17997 item = mPendingProcessChanges.get(i); 17998 if (item.pid == app.pid) { 17999 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18000 break; 18001 } 18002 i--; 18003 } 18004 if (i < 0) { 18005 // No existing item in pending changes; need a new one. 18006 final int NA = mAvailProcessChanges.size(); 18007 if (NA > 0) { 18008 item = mAvailProcessChanges.remove(NA-1); 18009 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18010 } else { 18011 item = new ProcessChangeItem(); 18012 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18013 } 18014 item.changes = 0; 18015 item.pid = app.pid; 18016 item.uid = app.info.uid; 18017 if (mPendingProcessChanges.size() == 0) { 18018 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18019 "*** Enqueueing dispatch processes changed!"); 18020 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18021 } 18022 mPendingProcessChanges.add(item); 18023 } 18024 item.changes |= changes; 18025 item.processState = app.repProcState; 18026 item.foregroundActivities = app.repForegroundActivities; 18027 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18028 + Integer.toHexString(System.identityHashCode(item)) 18029 + " " + app.toShortString() + ": changes=" + item.changes 18030 + " procState=" + item.processState 18031 + " foreground=" + item.foregroundActivities 18032 + " type=" + app.adjType + " source=" + app.adjSource 18033 + " target=" + app.adjTarget); 18034 } 18035 18036 return success; 18037 } 18038 18039 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18040 if (proc.thread != null) { 18041 if (proc.baseProcessTracker != null) { 18042 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18043 } 18044 if (proc.repProcState >= 0) { 18045 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18046 proc.repProcState); 18047 } 18048 } 18049 } 18050 18051 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18052 ProcessRecord TOP_APP, boolean doingAll, long now) { 18053 if (app.thread == null) { 18054 return false; 18055 } 18056 18057 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18058 18059 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18060 } 18061 18062 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18063 boolean oomAdj) { 18064 if (isForeground != proc.foregroundServices) { 18065 proc.foregroundServices = isForeground; 18066 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18067 proc.info.uid); 18068 if (isForeground) { 18069 if (curProcs == null) { 18070 curProcs = new ArrayList<ProcessRecord>(); 18071 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18072 } 18073 if (!curProcs.contains(proc)) { 18074 curProcs.add(proc); 18075 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18076 proc.info.packageName, proc.info.uid); 18077 } 18078 } else { 18079 if (curProcs != null) { 18080 if (curProcs.remove(proc)) { 18081 mBatteryStatsService.noteEvent( 18082 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18083 proc.info.packageName, proc.info.uid); 18084 if (curProcs.size() <= 0) { 18085 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18086 } 18087 } 18088 } 18089 } 18090 if (oomAdj) { 18091 updateOomAdjLocked(); 18092 } 18093 } 18094 } 18095 18096 private final ActivityRecord resumedAppLocked() { 18097 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18098 String pkg; 18099 int uid; 18100 if (act != null) { 18101 pkg = act.packageName; 18102 uid = act.info.applicationInfo.uid; 18103 } else { 18104 pkg = null; 18105 uid = -1; 18106 } 18107 // Has the UID or resumed package name changed? 18108 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18109 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18110 if (mCurResumedPackage != null) { 18111 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18112 mCurResumedPackage, mCurResumedUid); 18113 } 18114 mCurResumedPackage = pkg; 18115 mCurResumedUid = uid; 18116 if (mCurResumedPackage != null) { 18117 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18118 mCurResumedPackage, mCurResumedUid); 18119 } 18120 } 18121 return act; 18122 } 18123 18124 final boolean updateOomAdjLocked(ProcessRecord app) { 18125 final ActivityRecord TOP_ACT = resumedAppLocked(); 18126 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18127 final boolean wasCached = app.cached; 18128 18129 mAdjSeq++; 18130 18131 // This is the desired cached adjusment we want to tell it to use. 18132 // If our app is currently cached, we know it, and that is it. Otherwise, 18133 // we don't know it yet, and it needs to now be cached we will then 18134 // need to do a complete oom adj. 18135 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18136 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18137 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18138 SystemClock.uptimeMillis()); 18139 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18140 // Changed to/from cached state, so apps after it in the LRU 18141 // list may also be changed. 18142 updateOomAdjLocked(); 18143 } 18144 return success; 18145 } 18146 18147 final void updateOomAdjLocked() { 18148 final ActivityRecord TOP_ACT = resumedAppLocked(); 18149 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18150 final long now = SystemClock.uptimeMillis(); 18151 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18152 final int N = mLruProcesses.size(); 18153 18154 if (false) { 18155 RuntimeException e = new RuntimeException(); 18156 e.fillInStackTrace(); 18157 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18158 } 18159 18160 mAdjSeq++; 18161 mNewNumServiceProcs = 0; 18162 mNewNumAServiceProcs = 0; 18163 18164 final int emptyProcessLimit; 18165 final int cachedProcessLimit; 18166 if (mProcessLimit <= 0) { 18167 emptyProcessLimit = cachedProcessLimit = 0; 18168 } else if (mProcessLimit == 1) { 18169 emptyProcessLimit = 1; 18170 cachedProcessLimit = 0; 18171 } else { 18172 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18173 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18174 } 18175 18176 // Let's determine how many processes we have running vs. 18177 // how many slots we have for background processes; we may want 18178 // to put multiple processes in a slot of there are enough of 18179 // them. 18180 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18181 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18182 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18183 if (numEmptyProcs > cachedProcessLimit) { 18184 // If there are more empty processes than our limit on cached 18185 // processes, then use the cached process limit for the factor. 18186 // This ensures that the really old empty processes get pushed 18187 // down to the bottom, so if we are running low on memory we will 18188 // have a better chance at keeping around more cached processes 18189 // instead of a gazillion empty processes. 18190 numEmptyProcs = cachedProcessLimit; 18191 } 18192 int emptyFactor = numEmptyProcs/numSlots; 18193 if (emptyFactor < 1) emptyFactor = 1; 18194 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18195 if (cachedFactor < 1) cachedFactor = 1; 18196 int stepCached = 0; 18197 int stepEmpty = 0; 18198 int numCached = 0; 18199 int numEmpty = 0; 18200 int numTrimming = 0; 18201 18202 mNumNonCachedProcs = 0; 18203 mNumCachedHiddenProcs = 0; 18204 18205 // First update the OOM adjustment for each of the 18206 // application processes based on their current state. 18207 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18208 int nextCachedAdj = curCachedAdj+1; 18209 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18210 int nextEmptyAdj = curEmptyAdj+2; 18211 for (int i=N-1; i>=0; i--) { 18212 ProcessRecord app = mLruProcesses.get(i); 18213 if (!app.killedByAm && app.thread != null) { 18214 app.procStateChanged = false; 18215 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18216 18217 // If we haven't yet assigned the final cached adj 18218 // to the process, do that now. 18219 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18220 switch (app.curProcState) { 18221 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18222 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18223 // This process is a cached process holding activities... 18224 // assign it the next cached value for that type, and then 18225 // step that cached level. 18226 app.curRawAdj = curCachedAdj; 18227 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18228 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18229 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18230 + ")"); 18231 if (curCachedAdj != nextCachedAdj) { 18232 stepCached++; 18233 if (stepCached >= cachedFactor) { 18234 stepCached = 0; 18235 curCachedAdj = nextCachedAdj; 18236 nextCachedAdj += 2; 18237 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18238 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18239 } 18240 } 18241 } 18242 break; 18243 default: 18244 // For everything else, assign next empty cached process 18245 // level and bump that up. Note that this means that 18246 // long-running services that have dropped down to the 18247 // cached level will be treated as empty (since their process 18248 // state is still as a service), which is what we want. 18249 app.curRawAdj = curEmptyAdj; 18250 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18251 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18252 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18253 + ")"); 18254 if (curEmptyAdj != nextEmptyAdj) { 18255 stepEmpty++; 18256 if (stepEmpty >= emptyFactor) { 18257 stepEmpty = 0; 18258 curEmptyAdj = nextEmptyAdj; 18259 nextEmptyAdj += 2; 18260 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18261 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18262 } 18263 } 18264 } 18265 break; 18266 } 18267 } 18268 18269 applyOomAdjLocked(app, TOP_APP, true, now); 18270 18271 // Count the number of process types. 18272 switch (app.curProcState) { 18273 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18274 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18275 mNumCachedHiddenProcs++; 18276 numCached++; 18277 if (numCached > cachedProcessLimit) { 18278 app.kill("cached #" + numCached, true); 18279 } 18280 break; 18281 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18282 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18283 && app.lastActivityTime < oldTime) { 18284 app.kill("empty for " 18285 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18286 / 1000) + "s", true); 18287 } else { 18288 numEmpty++; 18289 if (numEmpty > emptyProcessLimit) { 18290 app.kill("empty #" + numEmpty, true); 18291 } 18292 } 18293 break; 18294 default: 18295 mNumNonCachedProcs++; 18296 break; 18297 } 18298 18299 if (app.isolated && app.services.size() <= 0) { 18300 // If this is an isolated process, and there are no 18301 // services running in it, then the process is no longer 18302 // needed. We agressively kill these because we can by 18303 // definition not re-use the same process again, and it is 18304 // good to avoid having whatever code was running in them 18305 // left sitting around after no longer needed. 18306 app.kill("isolated not needed", true); 18307 } 18308 18309 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18310 && !app.killedByAm) { 18311 numTrimming++; 18312 } 18313 } 18314 } 18315 18316 mNumServiceProcs = mNewNumServiceProcs; 18317 18318 // Now determine the memory trimming level of background processes. 18319 // Unfortunately we need to start at the back of the list to do this 18320 // properly. We only do this if the number of background apps we 18321 // are managing to keep around is less than half the maximum we desire; 18322 // if we are keeping a good number around, we'll let them use whatever 18323 // memory they want. 18324 final int numCachedAndEmpty = numCached + numEmpty; 18325 int memFactor; 18326 if (numCached <= ProcessList.TRIM_CACHED_APPS 18327 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18328 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18329 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18330 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18331 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18332 } else { 18333 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18334 } 18335 } else { 18336 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18337 } 18338 // We always allow the memory level to go up (better). We only allow it to go 18339 // down if we are in a state where that is allowed, *and* the total number of processes 18340 // has gone down since last time. 18341 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18342 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18343 + " last=" + mLastNumProcesses); 18344 if (memFactor > mLastMemoryLevel) { 18345 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18346 memFactor = mLastMemoryLevel; 18347 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18348 } 18349 } 18350 mLastMemoryLevel = memFactor; 18351 mLastNumProcesses = mLruProcesses.size(); 18352 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18353 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18354 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18355 if (mLowRamStartTime == 0) { 18356 mLowRamStartTime = now; 18357 } 18358 int step = 0; 18359 int fgTrimLevel; 18360 switch (memFactor) { 18361 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18362 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18363 break; 18364 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18365 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18366 break; 18367 default: 18368 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18369 break; 18370 } 18371 int factor = numTrimming/3; 18372 int minFactor = 2; 18373 if (mHomeProcess != null) minFactor++; 18374 if (mPreviousProcess != null) minFactor++; 18375 if (factor < minFactor) factor = minFactor; 18376 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18377 for (int i=N-1; i>=0; i--) { 18378 ProcessRecord app = mLruProcesses.get(i); 18379 if (allChanged || app.procStateChanged) { 18380 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18381 app.procStateChanged = false; 18382 } 18383 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18384 && !app.killedByAm) { 18385 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18386 try { 18387 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18388 "Trimming memory of " + app.processName 18389 + " to " + curLevel); 18390 app.thread.scheduleTrimMemory(curLevel); 18391 } catch (RemoteException e) { 18392 } 18393 if (false) { 18394 // For now we won't do this; our memory trimming seems 18395 // to be good enough at this point that destroying 18396 // activities causes more harm than good. 18397 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18398 && app != mHomeProcess && app != mPreviousProcess) { 18399 // Need to do this on its own message because the stack may not 18400 // be in a consistent state at this point. 18401 // For these apps we will also finish their activities 18402 // to help them free memory. 18403 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18404 } 18405 } 18406 } 18407 app.trimMemoryLevel = curLevel; 18408 step++; 18409 if (step >= factor) { 18410 step = 0; 18411 switch (curLevel) { 18412 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18413 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18414 break; 18415 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18416 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18417 break; 18418 } 18419 } 18420 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18421 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18422 && app.thread != null) { 18423 try { 18424 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18425 "Trimming memory of heavy-weight " + app.processName 18426 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18427 app.thread.scheduleTrimMemory( 18428 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18429 } catch (RemoteException e) { 18430 } 18431 } 18432 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18433 } else { 18434 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18435 || app.systemNoUi) && app.pendingUiClean) { 18436 // If this application is now in the background and it 18437 // had done UI, then give it the special trim level to 18438 // have it free UI resources. 18439 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18440 if (app.trimMemoryLevel < level && app.thread != null) { 18441 try { 18442 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18443 "Trimming memory of bg-ui " + app.processName 18444 + " to " + level); 18445 app.thread.scheduleTrimMemory(level); 18446 } catch (RemoteException e) { 18447 } 18448 } 18449 app.pendingUiClean = false; 18450 } 18451 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18452 try { 18453 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18454 "Trimming memory of fg " + app.processName 18455 + " to " + fgTrimLevel); 18456 app.thread.scheduleTrimMemory(fgTrimLevel); 18457 } catch (RemoteException e) { 18458 } 18459 } 18460 app.trimMemoryLevel = fgTrimLevel; 18461 } 18462 } 18463 } else { 18464 if (mLowRamStartTime != 0) { 18465 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18466 mLowRamStartTime = 0; 18467 } 18468 for (int i=N-1; i>=0; i--) { 18469 ProcessRecord app = mLruProcesses.get(i); 18470 if (allChanged || app.procStateChanged) { 18471 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18472 app.procStateChanged = false; 18473 } 18474 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18475 || app.systemNoUi) && app.pendingUiClean) { 18476 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18477 && app.thread != null) { 18478 try { 18479 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18480 "Trimming memory of ui hidden " + app.processName 18481 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18482 app.thread.scheduleTrimMemory( 18483 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18484 } catch (RemoteException e) { 18485 } 18486 } 18487 app.pendingUiClean = false; 18488 } 18489 app.trimMemoryLevel = 0; 18490 } 18491 } 18492 18493 if (mAlwaysFinishActivities) { 18494 // Need to do this on its own message because the stack may not 18495 // be in a consistent state at this point. 18496 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18497 } 18498 18499 if (allChanged) { 18500 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18501 } 18502 18503 if (mProcessStats.shouldWriteNowLocked(now)) { 18504 mHandler.post(new Runnable() { 18505 @Override public void run() { 18506 synchronized (ActivityManagerService.this) { 18507 mProcessStats.writeStateAsyncLocked(); 18508 } 18509 } 18510 }); 18511 } 18512 18513 if (DEBUG_OOM_ADJ) { 18514 if (false) { 18515 RuntimeException here = new RuntimeException("here"); 18516 here.fillInStackTrace(); 18517 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18518 } else { 18519 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18520 } 18521 } 18522 } 18523 18524 final void trimApplications() { 18525 synchronized (this) { 18526 int i; 18527 18528 // First remove any unused application processes whose package 18529 // has been removed. 18530 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18531 final ProcessRecord app = mRemovedProcesses.get(i); 18532 if (app.activities.size() == 0 18533 && app.curReceiver == null && app.services.size() == 0) { 18534 Slog.i( 18535 TAG, "Exiting empty application process " 18536 + app.processName + " (" 18537 + (app.thread != null ? app.thread.asBinder() : null) 18538 + ")\n"); 18539 if (app.pid > 0 && app.pid != MY_PID) { 18540 app.kill("empty", false); 18541 } else { 18542 try { 18543 app.thread.scheduleExit(); 18544 } catch (Exception e) { 18545 // Ignore exceptions. 18546 } 18547 } 18548 cleanUpApplicationRecordLocked(app, false, true, -1); 18549 mRemovedProcesses.remove(i); 18550 18551 if (app.persistent) { 18552 addAppLocked(app.info, false, null /* ABI override */); 18553 } 18554 } 18555 } 18556 18557 // Now update the oom adj for all processes. 18558 updateOomAdjLocked(); 18559 } 18560 } 18561 18562 /** This method sends the specified signal to each of the persistent apps */ 18563 public void signalPersistentProcesses(int sig) throws RemoteException { 18564 if (sig != Process.SIGNAL_USR1) { 18565 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18566 } 18567 18568 synchronized (this) { 18569 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18570 != PackageManager.PERMISSION_GRANTED) { 18571 throw new SecurityException("Requires permission " 18572 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18573 } 18574 18575 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18576 ProcessRecord r = mLruProcesses.get(i); 18577 if (r.thread != null && r.persistent) { 18578 Process.sendSignal(r.pid, sig); 18579 } 18580 } 18581 } 18582 } 18583 18584 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18585 if (proc == null || proc == mProfileProc) { 18586 proc = mProfileProc; 18587 profileType = mProfileType; 18588 clearProfilerLocked(); 18589 } 18590 if (proc == null) { 18591 return; 18592 } 18593 try { 18594 proc.thread.profilerControl(false, null, profileType); 18595 } catch (RemoteException e) { 18596 throw new IllegalStateException("Process disappeared"); 18597 } 18598 } 18599 18600 private void clearProfilerLocked() { 18601 if (mProfileFd != null) { 18602 try { 18603 mProfileFd.close(); 18604 } catch (IOException e) { 18605 } 18606 } 18607 mProfileApp = null; 18608 mProfileProc = null; 18609 mProfileFile = null; 18610 mProfileType = 0; 18611 mAutoStopProfiler = false; 18612 mSamplingInterval = 0; 18613 } 18614 18615 public boolean profileControl(String process, int userId, boolean start, 18616 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18617 18618 try { 18619 synchronized (this) { 18620 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18621 // its own permission. 18622 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18623 != PackageManager.PERMISSION_GRANTED) { 18624 throw new SecurityException("Requires permission " 18625 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18626 } 18627 18628 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18629 throw new IllegalArgumentException("null profile info or fd"); 18630 } 18631 18632 ProcessRecord proc = null; 18633 if (process != null) { 18634 proc = findProcessLocked(process, userId, "profileControl"); 18635 } 18636 18637 if (start && (proc == null || proc.thread == null)) { 18638 throw new IllegalArgumentException("Unknown process: " + process); 18639 } 18640 18641 if (start) { 18642 stopProfilerLocked(null, 0); 18643 setProfileApp(proc.info, proc.processName, profilerInfo); 18644 mProfileProc = proc; 18645 mProfileType = profileType; 18646 ParcelFileDescriptor fd = profilerInfo.profileFd; 18647 try { 18648 fd = fd.dup(); 18649 } catch (IOException e) { 18650 fd = null; 18651 } 18652 profilerInfo.profileFd = fd; 18653 proc.thread.profilerControl(start, profilerInfo, profileType); 18654 fd = null; 18655 mProfileFd = null; 18656 } else { 18657 stopProfilerLocked(proc, profileType); 18658 if (profilerInfo != null && profilerInfo.profileFd != null) { 18659 try { 18660 profilerInfo.profileFd.close(); 18661 } catch (IOException e) { 18662 } 18663 } 18664 } 18665 18666 return true; 18667 } 18668 } catch (RemoteException e) { 18669 throw new IllegalStateException("Process disappeared"); 18670 } finally { 18671 if (profilerInfo != null && profilerInfo.profileFd != null) { 18672 try { 18673 profilerInfo.profileFd.close(); 18674 } catch (IOException e) { 18675 } 18676 } 18677 } 18678 } 18679 18680 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18681 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18682 userId, true, ALLOW_FULL_ONLY, callName, null); 18683 ProcessRecord proc = null; 18684 try { 18685 int pid = Integer.parseInt(process); 18686 synchronized (mPidsSelfLocked) { 18687 proc = mPidsSelfLocked.get(pid); 18688 } 18689 } catch (NumberFormatException e) { 18690 } 18691 18692 if (proc == null) { 18693 ArrayMap<String, SparseArray<ProcessRecord>> all 18694 = mProcessNames.getMap(); 18695 SparseArray<ProcessRecord> procs = all.get(process); 18696 if (procs != null && procs.size() > 0) { 18697 proc = procs.valueAt(0); 18698 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18699 for (int i=1; i<procs.size(); i++) { 18700 ProcessRecord thisProc = procs.valueAt(i); 18701 if (thisProc.userId == userId) { 18702 proc = thisProc; 18703 break; 18704 } 18705 } 18706 } 18707 } 18708 } 18709 18710 return proc; 18711 } 18712 18713 public boolean dumpHeap(String process, int userId, boolean managed, 18714 String path, ParcelFileDescriptor fd) throws RemoteException { 18715 18716 try { 18717 synchronized (this) { 18718 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18719 // its own permission (same as profileControl). 18720 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18721 != PackageManager.PERMISSION_GRANTED) { 18722 throw new SecurityException("Requires permission " 18723 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18724 } 18725 18726 if (fd == null) { 18727 throw new IllegalArgumentException("null fd"); 18728 } 18729 18730 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18731 if (proc == null || proc.thread == null) { 18732 throw new IllegalArgumentException("Unknown process: " + process); 18733 } 18734 18735 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18736 if (!isDebuggable) { 18737 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18738 throw new SecurityException("Process not debuggable: " + proc); 18739 } 18740 } 18741 18742 proc.thread.dumpHeap(managed, path, fd); 18743 fd = null; 18744 return true; 18745 } 18746 } catch (RemoteException e) { 18747 throw new IllegalStateException("Process disappeared"); 18748 } finally { 18749 if (fd != null) { 18750 try { 18751 fd.close(); 18752 } catch (IOException e) { 18753 } 18754 } 18755 } 18756 } 18757 18758 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18759 public void monitor() { 18760 synchronized (this) { } 18761 } 18762 18763 void onCoreSettingsChange(Bundle settings) { 18764 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18765 ProcessRecord processRecord = mLruProcesses.get(i); 18766 try { 18767 if (processRecord.thread != null) { 18768 processRecord.thread.setCoreSettings(settings); 18769 } 18770 } catch (RemoteException re) { 18771 /* ignore */ 18772 } 18773 } 18774 } 18775 18776 // Multi-user methods 18777 18778 /** 18779 * Start user, if its not already running, but don't bring it to foreground. 18780 */ 18781 @Override 18782 public boolean startUserInBackground(final int userId) { 18783 return startUser(userId, /* foreground */ false); 18784 } 18785 18786 /** 18787 * Start user, if its not already running, and bring it to foreground. 18788 */ 18789 boolean startUserInForeground(final int userId, Dialog dlg) { 18790 boolean result = startUser(userId, /* foreground */ true); 18791 dlg.dismiss(); 18792 return result; 18793 } 18794 18795 /** 18796 * Refreshes the list of users related to the current user when either a 18797 * user switch happens or when a new related user is started in the 18798 * background. 18799 */ 18800 private void updateCurrentProfileIdsLocked() { 18801 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18802 mCurrentUserId, false /* enabledOnly */); 18803 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18804 for (int i = 0; i < currentProfileIds.length; i++) { 18805 currentProfileIds[i] = profiles.get(i).id; 18806 } 18807 mCurrentProfileIds = currentProfileIds; 18808 18809 synchronized (mUserProfileGroupIdsSelfLocked) { 18810 mUserProfileGroupIdsSelfLocked.clear(); 18811 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18812 for (int i = 0; i < users.size(); i++) { 18813 UserInfo user = users.get(i); 18814 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18815 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18816 } 18817 } 18818 } 18819 } 18820 18821 private Set getProfileIdsLocked(int userId) { 18822 Set userIds = new HashSet<Integer>(); 18823 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18824 userId, false /* enabledOnly */); 18825 for (UserInfo user : profiles) { 18826 userIds.add(Integer.valueOf(user.id)); 18827 } 18828 return userIds; 18829 } 18830 18831 @Override 18832 public boolean switchUser(final int userId) { 18833 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18834 String userName; 18835 synchronized (this) { 18836 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18837 if (userInfo == null) { 18838 Slog.w(TAG, "No user info for user #" + userId); 18839 return false; 18840 } 18841 if (userInfo.isManagedProfile()) { 18842 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18843 return false; 18844 } 18845 userName = userInfo.name; 18846 mTargetUserId = userId; 18847 } 18848 mHandler.removeMessages(START_USER_SWITCH_MSG); 18849 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18850 return true; 18851 } 18852 18853 private void showUserSwitchDialog(int userId, String userName) { 18854 // The dialog will show and then initiate the user switch by calling startUserInForeground 18855 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18856 true /* above system */); 18857 d.show(); 18858 } 18859 18860 private boolean startUser(final int userId, final boolean foreground) { 18861 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18862 != PackageManager.PERMISSION_GRANTED) { 18863 String msg = "Permission Denial: switchUser() from pid=" 18864 + Binder.getCallingPid() 18865 + ", uid=" + Binder.getCallingUid() 18866 + " requires " + INTERACT_ACROSS_USERS_FULL; 18867 Slog.w(TAG, msg); 18868 throw new SecurityException(msg); 18869 } 18870 18871 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18872 18873 final long ident = Binder.clearCallingIdentity(); 18874 try { 18875 synchronized (this) { 18876 final int oldUserId = mCurrentUserId; 18877 if (oldUserId == userId) { 18878 return true; 18879 } 18880 18881 mStackSupervisor.setLockTaskModeLocked(null, false); 18882 18883 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18884 if (userInfo == null) { 18885 Slog.w(TAG, "No user info for user #" + userId); 18886 return false; 18887 } 18888 if (foreground && userInfo.isManagedProfile()) { 18889 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18890 return false; 18891 } 18892 18893 if (foreground) { 18894 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18895 R.anim.screen_user_enter); 18896 } 18897 18898 boolean needStart = false; 18899 18900 // If the user we are switching to is not currently started, then 18901 // we need to start it now. 18902 if (mStartedUsers.get(userId) == null) { 18903 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18904 updateStartedUserArrayLocked(); 18905 needStart = true; 18906 } 18907 18908 final Integer userIdInt = Integer.valueOf(userId); 18909 mUserLru.remove(userIdInt); 18910 mUserLru.add(userIdInt); 18911 18912 if (foreground) { 18913 mCurrentUserId = userId; 18914 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18915 updateCurrentProfileIdsLocked(); 18916 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18917 // Once the internal notion of the active user has switched, we lock the device 18918 // with the option to show the user switcher on the keyguard. 18919 mWindowManager.lockNow(null); 18920 } else { 18921 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18922 updateCurrentProfileIdsLocked(); 18923 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18924 mUserLru.remove(currentUserIdInt); 18925 mUserLru.add(currentUserIdInt); 18926 } 18927 18928 final UserStartedState uss = mStartedUsers.get(userId); 18929 18930 // Make sure user is in the started state. If it is currently 18931 // stopping, we need to knock that off. 18932 if (uss.mState == UserStartedState.STATE_STOPPING) { 18933 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18934 // so we can just fairly silently bring the user back from 18935 // the almost-dead. 18936 uss.mState = UserStartedState.STATE_RUNNING; 18937 updateStartedUserArrayLocked(); 18938 needStart = true; 18939 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18940 // This means ACTION_SHUTDOWN has been sent, so we will 18941 // need to treat this as a new boot of the user. 18942 uss.mState = UserStartedState.STATE_BOOTING; 18943 updateStartedUserArrayLocked(); 18944 needStart = true; 18945 } 18946 18947 if (uss.mState == UserStartedState.STATE_BOOTING) { 18948 // Booting up a new user, need to tell system services about it. 18949 // Note that this is on the same handler as scheduling of broadcasts, 18950 // which is important because it needs to go first. 18951 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18952 } 18953 18954 if (foreground) { 18955 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18956 oldUserId)); 18957 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18958 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18959 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18960 oldUserId, userId, uss)); 18961 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18962 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18963 } 18964 18965 if (needStart) { 18966 // Send USER_STARTED broadcast 18967 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18968 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18969 | Intent.FLAG_RECEIVER_FOREGROUND); 18970 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18971 broadcastIntentLocked(null, null, intent, 18972 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18973 false, false, MY_PID, Process.SYSTEM_UID, userId); 18974 } 18975 18976 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18977 if (userId != UserHandle.USER_OWNER) { 18978 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18979 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18980 broadcastIntentLocked(null, null, intent, null, 18981 new IIntentReceiver.Stub() { 18982 public void performReceive(Intent intent, int resultCode, 18983 String data, Bundle extras, boolean ordered, 18984 boolean sticky, int sendingUser) { 18985 onUserInitialized(uss, foreground, oldUserId, userId); 18986 } 18987 }, 0, null, null, null, AppOpsManager.OP_NONE, 18988 true, false, MY_PID, Process.SYSTEM_UID, 18989 userId); 18990 uss.initializing = true; 18991 } else { 18992 getUserManagerLocked().makeInitialized(userInfo.id); 18993 } 18994 } 18995 18996 if (foreground) { 18997 if (!uss.initializing) { 18998 moveUserToForeground(uss, oldUserId, userId); 18999 } 19000 } else { 19001 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19002 } 19003 19004 if (needStart) { 19005 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19006 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19007 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19008 broadcastIntentLocked(null, null, intent, 19009 null, new IIntentReceiver.Stub() { 19010 @Override 19011 public void performReceive(Intent intent, int resultCode, String data, 19012 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19013 throws RemoteException { 19014 } 19015 }, 0, null, null, 19016 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19017 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19018 } 19019 } 19020 } finally { 19021 Binder.restoreCallingIdentity(ident); 19022 } 19023 19024 return true; 19025 } 19026 19027 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19028 long ident = Binder.clearCallingIdentity(); 19029 try { 19030 Intent intent; 19031 if (oldUserId >= 0) { 19032 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19033 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19034 int count = profiles.size(); 19035 for (int i = 0; i < count; i++) { 19036 int profileUserId = profiles.get(i).id; 19037 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19038 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19039 | Intent.FLAG_RECEIVER_FOREGROUND); 19040 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19041 broadcastIntentLocked(null, null, intent, 19042 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19043 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19044 } 19045 } 19046 if (newUserId >= 0) { 19047 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19048 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19049 int count = profiles.size(); 19050 for (int i = 0; i < count; i++) { 19051 int profileUserId = profiles.get(i).id; 19052 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19053 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19054 | Intent.FLAG_RECEIVER_FOREGROUND); 19055 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19056 broadcastIntentLocked(null, null, intent, 19057 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19058 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19059 } 19060 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19061 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19062 | Intent.FLAG_RECEIVER_FOREGROUND); 19063 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19064 broadcastIntentLocked(null, null, intent, 19065 null, null, 0, null, null, 19066 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19067 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19068 } 19069 } finally { 19070 Binder.restoreCallingIdentity(ident); 19071 } 19072 } 19073 19074 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19075 final int newUserId) { 19076 final int N = mUserSwitchObservers.beginBroadcast(); 19077 if (N > 0) { 19078 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19079 int mCount = 0; 19080 @Override 19081 public void sendResult(Bundle data) throws RemoteException { 19082 synchronized (ActivityManagerService.this) { 19083 if (mCurUserSwitchCallback == this) { 19084 mCount++; 19085 if (mCount == N) { 19086 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19087 } 19088 } 19089 } 19090 } 19091 }; 19092 synchronized (this) { 19093 uss.switching = true; 19094 mCurUserSwitchCallback = callback; 19095 } 19096 for (int i=0; i<N; i++) { 19097 try { 19098 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19099 newUserId, callback); 19100 } catch (RemoteException e) { 19101 } 19102 } 19103 } else { 19104 synchronized (this) { 19105 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19106 } 19107 } 19108 mUserSwitchObservers.finishBroadcast(); 19109 } 19110 19111 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19112 synchronized (this) { 19113 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19114 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19115 } 19116 } 19117 19118 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19119 mCurUserSwitchCallback = null; 19120 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19121 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19122 oldUserId, newUserId, uss)); 19123 } 19124 19125 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19126 synchronized (this) { 19127 if (foreground) { 19128 moveUserToForeground(uss, oldUserId, newUserId); 19129 } 19130 } 19131 19132 completeSwitchAndInitalize(uss, newUserId, true, false); 19133 } 19134 19135 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19136 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19137 if (homeInFront) { 19138 startHomeActivityLocked(newUserId); 19139 } else { 19140 mStackSupervisor.resumeTopActivitiesLocked(); 19141 } 19142 EventLogTags.writeAmSwitchUser(newUserId); 19143 getUserManagerLocked().userForeground(newUserId); 19144 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19145 } 19146 19147 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19148 completeSwitchAndInitalize(uss, newUserId, false, true); 19149 } 19150 19151 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19152 boolean clearInitializing, boolean clearSwitching) { 19153 boolean unfrozen = false; 19154 synchronized (this) { 19155 if (clearInitializing) { 19156 uss.initializing = false; 19157 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19158 } 19159 if (clearSwitching) { 19160 uss.switching = false; 19161 } 19162 if (!uss.switching && !uss.initializing) { 19163 mWindowManager.stopFreezingScreen(); 19164 unfrozen = true; 19165 } 19166 } 19167 if (unfrozen) { 19168 final int N = mUserSwitchObservers.beginBroadcast(); 19169 for (int i=0; i<N; i++) { 19170 try { 19171 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19172 } catch (RemoteException e) { 19173 } 19174 } 19175 mUserSwitchObservers.finishBroadcast(); 19176 } 19177 stopGuestUserIfBackground(); 19178 } 19179 19180 /** 19181 * Stops the guest user if it has gone to the background. 19182 */ 19183 private void stopGuestUserIfBackground() { 19184 synchronized (this) { 19185 final int num = mUserLru.size(); 19186 for (int i = 0; i < num; i++) { 19187 Integer oldUserId = mUserLru.get(i); 19188 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19189 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19190 || oldUss.mState == UserStartedState.STATE_STOPPING 19191 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19192 continue; 19193 } 19194 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19195 if (userInfo.isGuest()) { 19196 // This is a user to be stopped. 19197 stopUserLocked(oldUserId, null); 19198 break; 19199 } 19200 } 19201 } 19202 } 19203 19204 void scheduleStartProfilesLocked() { 19205 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19206 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19207 DateUtils.SECOND_IN_MILLIS); 19208 } 19209 } 19210 19211 void startProfilesLocked() { 19212 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19213 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19214 mCurrentUserId, false /* enabledOnly */); 19215 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19216 for (UserInfo user : profiles) { 19217 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19218 && user.id != mCurrentUserId) { 19219 toStart.add(user); 19220 } 19221 } 19222 final int n = toStart.size(); 19223 int i = 0; 19224 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19225 startUserInBackground(toStart.get(i).id); 19226 } 19227 if (i < n) { 19228 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19229 } 19230 } 19231 19232 void finishUserBoot(UserStartedState uss) { 19233 synchronized (this) { 19234 if (uss.mState == UserStartedState.STATE_BOOTING 19235 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19236 uss.mState = UserStartedState.STATE_RUNNING; 19237 final int userId = uss.mHandle.getIdentifier(); 19238 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19239 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19240 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19241 broadcastIntentLocked(null, null, intent, 19242 null, null, 0, null, null, 19243 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19244 true, false, MY_PID, Process.SYSTEM_UID, userId); 19245 } 19246 } 19247 } 19248 19249 void finishUserSwitch(UserStartedState uss) { 19250 synchronized (this) { 19251 finishUserBoot(uss); 19252 19253 startProfilesLocked(); 19254 19255 int num = mUserLru.size(); 19256 int i = 0; 19257 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19258 Integer oldUserId = mUserLru.get(i); 19259 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19260 if (oldUss == null) { 19261 // Shouldn't happen, but be sane if it does. 19262 mUserLru.remove(i); 19263 num--; 19264 continue; 19265 } 19266 if (oldUss.mState == UserStartedState.STATE_STOPPING 19267 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19268 // This user is already stopping, doesn't count. 19269 num--; 19270 i++; 19271 continue; 19272 } 19273 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19274 // Owner and current can't be stopped, but count as running. 19275 i++; 19276 continue; 19277 } 19278 // This is a user to be stopped. 19279 stopUserLocked(oldUserId, null); 19280 num--; 19281 i++; 19282 } 19283 } 19284 } 19285 19286 @Override 19287 public int stopUser(final int userId, final IStopUserCallback callback) { 19288 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19289 != PackageManager.PERMISSION_GRANTED) { 19290 String msg = "Permission Denial: switchUser() from pid=" 19291 + Binder.getCallingPid() 19292 + ", uid=" + Binder.getCallingUid() 19293 + " requires " + INTERACT_ACROSS_USERS_FULL; 19294 Slog.w(TAG, msg); 19295 throw new SecurityException(msg); 19296 } 19297 if (userId <= 0) { 19298 throw new IllegalArgumentException("Can't stop primary user " + userId); 19299 } 19300 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19301 synchronized (this) { 19302 return stopUserLocked(userId, callback); 19303 } 19304 } 19305 19306 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19307 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19308 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19309 return ActivityManager.USER_OP_IS_CURRENT; 19310 } 19311 19312 final UserStartedState uss = mStartedUsers.get(userId); 19313 if (uss == null) { 19314 // User is not started, nothing to do... but we do need to 19315 // callback if requested. 19316 if (callback != null) { 19317 mHandler.post(new Runnable() { 19318 @Override 19319 public void run() { 19320 try { 19321 callback.userStopped(userId); 19322 } catch (RemoteException e) { 19323 } 19324 } 19325 }); 19326 } 19327 return ActivityManager.USER_OP_SUCCESS; 19328 } 19329 19330 if (callback != null) { 19331 uss.mStopCallbacks.add(callback); 19332 } 19333 19334 if (uss.mState != UserStartedState.STATE_STOPPING 19335 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19336 uss.mState = UserStartedState.STATE_STOPPING; 19337 updateStartedUserArrayLocked(); 19338 19339 long ident = Binder.clearCallingIdentity(); 19340 try { 19341 // We are going to broadcast ACTION_USER_STOPPING and then 19342 // once that is done send a final ACTION_SHUTDOWN and then 19343 // stop the user. 19344 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19345 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19346 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19347 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19348 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19349 // This is the result receiver for the final shutdown broadcast. 19350 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19351 @Override 19352 public void performReceive(Intent intent, int resultCode, String data, 19353 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19354 finishUserStop(uss); 19355 } 19356 }; 19357 // This is the result receiver for the initial stopping broadcast. 19358 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19359 @Override 19360 public void performReceive(Intent intent, int resultCode, String data, 19361 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19362 // On to the next. 19363 synchronized (ActivityManagerService.this) { 19364 if (uss.mState != UserStartedState.STATE_STOPPING) { 19365 // Whoops, we are being started back up. Abort, abort! 19366 return; 19367 } 19368 uss.mState = UserStartedState.STATE_SHUTDOWN; 19369 } 19370 mBatteryStatsService.noteEvent( 19371 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19372 Integer.toString(userId), userId); 19373 mSystemServiceManager.stopUser(userId); 19374 broadcastIntentLocked(null, null, shutdownIntent, 19375 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19376 true, false, MY_PID, Process.SYSTEM_UID, userId); 19377 } 19378 }; 19379 // Kick things off. 19380 broadcastIntentLocked(null, null, stoppingIntent, 19381 null, stoppingReceiver, 0, null, null, 19382 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19383 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19384 } finally { 19385 Binder.restoreCallingIdentity(ident); 19386 } 19387 } 19388 19389 return ActivityManager.USER_OP_SUCCESS; 19390 } 19391 19392 void finishUserStop(UserStartedState uss) { 19393 final int userId = uss.mHandle.getIdentifier(); 19394 boolean stopped; 19395 ArrayList<IStopUserCallback> callbacks; 19396 synchronized (this) { 19397 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19398 if (mStartedUsers.get(userId) != uss) { 19399 stopped = false; 19400 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19401 stopped = false; 19402 } else { 19403 stopped = true; 19404 // User can no longer run. 19405 mStartedUsers.remove(userId); 19406 mUserLru.remove(Integer.valueOf(userId)); 19407 updateStartedUserArrayLocked(); 19408 19409 // Clean up all state and processes associated with the user. 19410 // Kill all the processes for the user. 19411 forceStopUserLocked(userId, "finish user"); 19412 } 19413 19414 // Explicitly remove the old information in mRecentTasks. 19415 removeRecentTasksForUserLocked(userId); 19416 } 19417 19418 for (int i=0; i<callbacks.size(); i++) { 19419 try { 19420 if (stopped) callbacks.get(i).userStopped(userId); 19421 else callbacks.get(i).userStopAborted(userId); 19422 } catch (RemoteException e) { 19423 } 19424 } 19425 19426 if (stopped) { 19427 mSystemServiceManager.cleanupUser(userId); 19428 synchronized (this) { 19429 mStackSupervisor.removeUserLocked(userId); 19430 } 19431 } 19432 } 19433 19434 @Override 19435 public UserInfo getCurrentUser() { 19436 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19437 != PackageManager.PERMISSION_GRANTED) && ( 19438 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19439 != PackageManager.PERMISSION_GRANTED)) { 19440 String msg = "Permission Denial: getCurrentUser() from pid=" 19441 + Binder.getCallingPid() 19442 + ", uid=" + Binder.getCallingUid() 19443 + " requires " + INTERACT_ACROSS_USERS; 19444 Slog.w(TAG, msg); 19445 throw new SecurityException(msg); 19446 } 19447 synchronized (this) { 19448 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19449 return getUserManagerLocked().getUserInfo(userId); 19450 } 19451 } 19452 19453 int getCurrentUserIdLocked() { 19454 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19455 } 19456 19457 @Override 19458 public boolean isUserRunning(int userId, boolean orStopped) { 19459 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19460 != PackageManager.PERMISSION_GRANTED) { 19461 String msg = "Permission Denial: isUserRunning() from pid=" 19462 + Binder.getCallingPid() 19463 + ", uid=" + Binder.getCallingUid() 19464 + " requires " + INTERACT_ACROSS_USERS; 19465 Slog.w(TAG, msg); 19466 throw new SecurityException(msg); 19467 } 19468 synchronized (this) { 19469 return isUserRunningLocked(userId, orStopped); 19470 } 19471 } 19472 19473 boolean isUserRunningLocked(int userId, boolean orStopped) { 19474 UserStartedState state = mStartedUsers.get(userId); 19475 if (state == null) { 19476 return false; 19477 } 19478 if (orStopped) { 19479 return true; 19480 } 19481 return state.mState != UserStartedState.STATE_STOPPING 19482 && state.mState != UserStartedState.STATE_SHUTDOWN; 19483 } 19484 19485 @Override 19486 public int[] getRunningUserIds() { 19487 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19488 != PackageManager.PERMISSION_GRANTED) { 19489 String msg = "Permission Denial: isUserRunning() from pid=" 19490 + Binder.getCallingPid() 19491 + ", uid=" + Binder.getCallingUid() 19492 + " requires " + INTERACT_ACROSS_USERS; 19493 Slog.w(TAG, msg); 19494 throw new SecurityException(msg); 19495 } 19496 synchronized (this) { 19497 return mStartedUserArray; 19498 } 19499 } 19500 19501 private void updateStartedUserArrayLocked() { 19502 int num = 0; 19503 for (int i=0; i<mStartedUsers.size(); i++) { 19504 UserStartedState uss = mStartedUsers.valueAt(i); 19505 // This list does not include stopping users. 19506 if (uss.mState != UserStartedState.STATE_STOPPING 19507 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19508 num++; 19509 } 19510 } 19511 mStartedUserArray = new int[num]; 19512 num = 0; 19513 for (int i=0; i<mStartedUsers.size(); i++) { 19514 UserStartedState uss = mStartedUsers.valueAt(i); 19515 if (uss.mState != UserStartedState.STATE_STOPPING 19516 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19517 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19518 num++; 19519 } 19520 } 19521 } 19522 19523 @Override 19524 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19525 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19526 != PackageManager.PERMISSION_GRANTED) { 19527 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19528 + Binder.getCallingPid() 19529 + ", uid=" + Binder.getCallingUid() 19530 + " requires " + INTERACT_ACROSS_USERS_FULL; 19531 Slog.w(TAG, msg); 19532 throw new SecurityException(msg); 19533 } 19534 19535 mUserSwitchObservers.register(observer); 19536 } 19537 19538 @Override 19539 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19540 mUserSwitchObservers.unregister(observer); 19541 } 19542 19543 private boolean userExists(int userId) { 19544 if (userId == 0) { 19545 return true; 19546 } 19547 UserManagerService ums = getUserManagerLocked(); 19548 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19549 } 19550 19551 int[] getUsersLocked() { 19552 UserManagerService ums = getUserManagerLocked(); 19553 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19554 } 19555 19556 UserManagerService getUserManagerLocked() { 19557 if (mUserManager == null) { 19558 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19559 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19560 } 19561 return mUserManager; 19562 } 19563 19564 private int applyUserId(int uid, int userId) { 19565 return UserHandle.getUid(userId, uid); 19566 } 19567 19568 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19569 if (info == null) return null; 19570 ApplicationInfo newInfo = new ApplicationInfo(info); 19571 newInfo.uid = applyUserId(info.uid, userId); 19572 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19573 + info.packageName; 19574 return newInfo; 19575 } 19576 19577 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19578 if (aInfo == null 19579 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19580 return aInfo; 19581 } 19582 19583 ActivityInfo info = new ActivityInfo(aInfo); 19584 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19585 return info; 19586 } 19587 19588 private final class LocalService extends ActivityManagerInternal { 19589 @Override 19590 public void onWakefulnessChanged(int wakefulness) { 19591 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19592 } 19593 19594 @Override 19595 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19596 String processName, String abiOverride, int uid, Runnable crashHandler) { 19597 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19598 processName, abiOverride, uid, crashHandler); 19599 } 19600 } 19601 19602 /** 19603 * An implementation of IAppTask, that allows an app to manage its own tasks via 19604 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19605 * only the process that calls getAppTasks() can call the AppTask methods. 19606 */ 19607 class AppTaskImpl extends IAppTask.Stub { 19608 private int mTaskId; 19609 private int mCallingUid; 19610 19611 public AppTaskImpl(int taskId, int callingUid) { 19612 mTaskId = taskId; 19613 mCallingUid = callingUid; 19614 } 19615 19616 private void checkCaller() { 19617 if (mCallingUid != Binder.getCallingUid()) { 19618 throw new SecurityException("Caller " + mCallingUid 19619 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19620 } 19621 } 19622 19623 @Override 19624 public void finishAndRemoveTask() { 19625 checkCaller(); 19626 19627 synchronized (ActivityManagerService.this) { 19628 long origId = Binder.clearCallingIdentity(); 19629 try { 19630 if (!removeTaskByIdLocked(mTaskId, false)) { 19631 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19632 } 19633 } finally { 19634 Binder.restoreCallingIdentity(origId); 19635 } 19636 } 19637 } 19638 19639 @Override 19640 public ActivityManager.RecentTaskInfo getTaskInfo() { 19641 checkCaller(); 19642 19643 synchronized (ActivityManagerService.this) { 19644 long origId = Binder.clearCallingIdentity(); 19645 try { 19646 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19647 if (tr == null) { 19648 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19649 } 19650 return createRecentTaskInfoFromTaskRecord(tr); 19651 } finally { 19652 Binder.restoreCallingIdentity(origId); 19653 } 19654 } 19655 } 19656 19657 @Override 19658 public void moveToFront() { 19659 checkCaller(); 19660 // Will bring task to front if it already has a root activity. 19661 startActivityFromRecentsInner(mTaskId, null); 19662 } 19663 19664 @Override 19665 public int startActivity(IBinder whoThread, String callingPackage, 19666 Intent intent, String resolvedType, Bundle options) { 19667 checkCaller(); 19668 19669 int callingUser = UserHandle.getCallingUserId(); 19670 TaskRecord tr; 19671 IApplicationThread appThread; 19672 synchronized (ActivityManagerService.this) { 19673 tr = recentTaskForIdLocked(mTaskId); 19674 if (tr == null) { 19675 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19676 } 19677 appThread = ApplicationThreadNative.asInterface(whoThread); 19678 if (appThread == null) { 19679 throw new IllegalArgumentException("Bad app thread " + appThread); 19680 } 19681 } 19682 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19683 resolvedType, null, null, null, null, 0, 0, null, null, 19684 null, options, callingUser, null, tr); 19685 } 19686 19687 @Override 19688 public void setExcludeFromRecents(boolean exclude) { 19689 checkCaller(); 19690 19691 synchronized (ActivityManagerService.this) { 19692 long origId = Binder.clearCallingIdentity(); 19693 try { 19694 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19695 if (tr == null) { 19696 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19697 } 19698 Intent intent = tr.getBaseIntent(); 19699 if (exclude) { 19700 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19701 } else { 19702 intent.setFlags(intent.getFlags() 19703 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19704 } 19705 } finally { 19706 Binder.restoreCallingIdentity(origId); 19707 } 19708 } 19709 } 19710 } 19711} 19712