ActivityManagerService.java revision 7bc33c0d252b190af8258c827de8a8a5382210db
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 /** 753 * Backup/restore process management 754 */ 755 String mBackupAppName = null; 756 BackupRecord mBackupTarget = null; 757 758 final ProviderMap mProviderMap; 759 760 /** 761 * List of content providers who have clients waiting for them. The 762 * application is currently being launched and the provider will be 763 * removed from this list once it is published. 764 */ 765 final ArrayList<ContentProviderRecord> mLaunchingProviders 766 = new ArrayList<ContentProviderRecord>(); 767 768 /** 769 * File storing persisted {@link #mGrantedUriPermissions}. 770 */ 771 private final AtomicFile mGrantFile; 772 773 /** XML constants used in {@link #mGrantFile} */ 774 private static final String TAG_URI_GRANTS = "uri-grants"; 775 private static final String TAG_URI_GRANT = "uri-grant"; 776 private static final String ATTR_USER_HANDLE = "userHandle"; 777 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 778 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 779 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 780 private static final String ATTR_TARGET_PKG = "targetPkg"; 781 private static final String ATTR_URI = "uri"; 782 private static final String ATTR_MODE_FLAGS = "modeFlags"; 783 private static final String ATTR_CREATED_TIME = "createdTime"; 784 private static final String ATTR_PREFIX = "prefix"; 785 786 /** 787 * Global set of specific {@link Uri} permissions that have been granted. 788 * This optimized lookup structure maps from {@link UriPermission#targetUid} 789 * to {@link UriPermission#uri} to {@link UriPermission}. 790 */ 791 @GuardedBy("this") 792 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 793 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 794 795 public static class GrantUri { 796 public final int sourceUserId; 797 public final Uri uri; 798 public boolean prefix; 799 800 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 801 this.sourceUserId = sourceUserId; 802 this.uri = uri; 803 this.prefix = prefix; 804 } 805 806 @Override 807 public int hashCode() { 808 int hashCode = 1; 809 hashCode = 31 * hashCode + sourceUserId; 810 hashCode = 31 * hashCode + uri.hashCode(); 811 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 812 return hashCode; 813 } 814 815 @Override 816 public boolean equals(Object o) { 817 if (o instanceof GrantUri) { 818 GrantUri other = (GrantUri) o; 819 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 820 && prefix == other.prefix; 821 } 822 return false; 823 } 824 825 @Override 826 public String toString() { 827 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 828 if (prefix) result += " [prefix]"; 829 return result; 830 } 831 832 public String toSafeString() { 833 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 834 if (prefix) result += " [prefix]"; 835 return result; 836 } 837 838 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 839 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 840 ContentProvider.getUriWithoutUserId(uri), false); 841 } 842 } 843 844 CoreSettingsObserver mCoreSettingsObserver; 845 846 /** 847 * Thread-local storage used to carry caller permissions over through 848 * indirect content-provider access. 849 */ 850 private class Identity { 851 public final IBinder token; 852 public final int pid; 853 public final int uid; 854 855 Identity(IBinder _token, int _pid, int _uid) { 856 token = _token; 857 pid = _pid; 858 uid = _uid; 859 } 860 } 861 862 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 863 864 /** 865 * All information we have collected about the runtime performance of 866 * any user id that can impact battery performance. 867 */ 868 final BatteryStatsService mBatteryStatsService; 869 870 /** 871 * Information about component usage 872 */ 873 UsageStatsManagerInternal mUsageStatsService; 874 875 /** 876 * Information about and control over application operations 877 */ 878 final AppOpsService mAppOpsService; 879 880 /** 881 * Save recent tasks information across reboots. 882 */ 883 final TaskPersister mTaskPersister; 884 885 /** 886 * Current configuration information. HistoryRecord objects are given 887 * a reference to this object to indicate which configuration they are 888 * currently running in, so this object must be kept immutable. 889 */ 890 Configuration mConfiguration = new Configuration(); 891 892 /** 893 * Current sequencing integer of the configuration, for skipping old 894 * configurations. 895 */ 896 int mConfigurationSeq = 0; 897 898 /** 899 * Hardware-reported OpenGLES version. 900 */ 901 final int GL_ES_VERSION; 902 903 /** 904 * List of initialization arguments to pass to all processes when binding applications to them. 905 * For example, references to the commonly used services. 906 */ 907 HashMap<String, IBinder> mAppBindArgs; 908 909 /** 910 * Temporary to avoid allocations. Protected by main lock. 911 */ 912 final StringBuilder mStringBuilder = new StringBuilder(256); 913 914 /** 915 * Used to control how we initialize the service. 916 */ 917 ComponentName mTopComponent; 918 String mTopAction = Intent.ACTION_MAIN; 919 String mTopData; 920 boolean mProcessesReady = false; 921 boolean mSystemReady = false; 922 boolean mBooting = false; 923 boolean mCallFinishBooting = false; 924 boolean mBootAnimationComplete = false; 925 boolean mWaitingUpdate = false; 926 boolean mDidUpdate = false; 927 boolean mOnBattery = false; 928 boolean mLaunchWarningShown = false; 929 930 Context mContext; 931 932 int mFactoryTest; 933 934 boolean mCheckedForSetup; 935 936 /** 937 * The time at which we will allow normal application switches again, 938 * after a call to {@link #stopAppSwitches()}. 939 */ 940 long mAppSwitchesAllowedTime; 941 942 /** 943 * This is set to true after the first switch after mAppSwitchesAllowedTime 944 * is set; any switches after that will clear the time. 945 */ 946 boolean mDidAppSwitch; 947 948 /** 949 * Last time (in realtime) at which we checked for power usage. 950 */ 951 long mLastPowerCheckRealtime; 952 953 /** 954 * Last time (in uptime) at which we checked for power usage. 955 */ 956 long mLastPowerCheckUptime; 957 958 /** 959 * Set while we are wanting to sleep, to prevent any 960 * activities from being started/resumed. 961 */ 962 private boolean mSleeping = false; 963 964 /** 965 * Set while we are running a voice interaction. This overrides 966 * sleeping while it is active. 967 */ 968 private boolean mRunningVoice = false; 969 970 /** 971 * State of external calls telling us if the device is awake or asleep. 972 */ 973 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 974 975 static final int LOCK_SCREEN_HIDDEN = 0; 976 static final int LOCK_SCREEN_LEAVING = 1; 977 static final int LOCK_SCREEN_SHOWN = 2; 978 /** 979 * State of external call telling us if the lock screen is shown. 980 */ 981 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 982 983 /** 984 * Set if we are shutting down the system, similar to sleeping. 985 */ 986 boolean mShuttingDown = false; 987 988 /** 989 * Current sequence id for oom_adj computation traversal. 990 */ 991 int mAdjSeq = 0; 992 993 /** 994 * Current sequence id for process LRU updating. 995 */ 996 int mLruSeq = 0; 997 998 /** 999 * Keep track of the non-cached/empty process we last found, to help 1000 * determine how to distribute cached/empty processes next time. 1001 */ 1002 int mNumNonCachedProcs = 0; 1003 1004 /** 1005 * Keep track of the number of cached hidden procs, to balance oom adj 1006 * distribution between those and empty procs. 1007 */ 1008 int mNumCachedHiddenProcs = 0; 1009 1010 /** 1011 * Keep track of the number of service processes we last found, to 1012 * determine on the next iteration which should be B services. 1013 */ 1014 int mNumServiceProcs = 0; 1015 int mNewNumAServiceProcs = 0; 1016 int mNewNumServiceProcs = 0; 1017 1018 /** 1019 * Allow the current computed overall memory level of the system to go down? 1020 * This is set to false when we are killing processes for reasons other than 1021 * memory management, so that the now smaller process list will not be taken as 1022 * an indication that memory is tighter. 1023 */ 1024 boolean mAllowLowerMemLevel = false; 1025 1026 /** 1027 * The last computed memory level, for holding when we are in a state that 1028 * processes are going away for other reasons. 1029 */ 1030 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1031 1032 /** 1033 * The last total number of process we have, to determine if changes actually look 1034 * like a shrinking number of process due to lower RAM. 1035 */ 1036 int mLastNumProcesses; 1037 1038 /** 1039 * The uptime of the last time we performed idle maintenance. 1040 */ 1041 long mLastIdleTime = SystemClock.uptimeMillis(); 1042 1043 /** 1044 * Total time spent with RAM that has been added in the past since the last idle time. 1045 */ 1046 long mLowRamTimeSinceLastIdle = 0; 1047 1048 /** 1049 * If RAM is currently low, when that horrible situation started. 1050 */ 1051 long mLowRamStartTime = 0; 1052 1053 /** 1054 * For reporting to battery stats the current top application. 1055 */ 1056 private String mCurResumedPackage = null; 1057 private int mCurResumedUid = -1; 1058 1059 /** 1060 * For reporting to battery stats the apps currently running foreground 1061 * service. The ProcessMap is package/uid tuples; each of these contain 1062 * an array of the currently foreground processes. 1063 */ 1064 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1065 = new ProcessMap<ArrayList<ProcessRecord>>(); 1066 1067 /** 1068 * This is set if we had to do a delayed dexopt of an app before launching 1069 * it, to increase the ANR timeouts in that case. 1070 */ 1071 boolean mDidDexOpt; 1072 1073 /** 1074 * Set if the systemServer made a call to enterSafeMode. 1075 */ 1076 boolean mSafeMode; 1077 1078 /** 1079 * If true, we are running under a test environment so will sample PSS from processes 1080 * much more rapidly to try to collect better data when the tests are rapidly 1081 * running through apps. 1082 */ 1083 boolean mTestPssMode = false; 1084 1085 String mDebugApp = null; 1086 boolean mWaitForDebugger = false; 1087 boolean mDebugTransient = false; 1088 String mOrigDebugApp = null; 1089 boolean mOrigWaitForDebugger = false; 1090 boolean mAlwaysFinishActivities = false; 1091 IActivityController mController = null; 1092 String mProfileApp = null; 1093 ProcessRecord mProfileProc = null; 1094 String mProfileFile; 1095 ParcelFileDescriptor mProfileFd; 1096 int mSamplingInterval = 0; 1097 boolean mAutoStopProfiler = false; 1098 int mProfileType = 0; 1099 String mOpenGlTraceApp = null; 1100 1101 final long[] mTmpLong = new long[1]; 1102 1103 static class ProcessChangeItem { 1104 static final int CHANGE_ACTIVITIES = 1<<0; 1105 static final int CHANGE_PROCESS_STATE = 1<<1; 1106 int changes; 1107 int uid; 1108 int pid; 1109 int processState; 1110 boolean foregroundActivities; 1111 } 1112 1113 final RemoteCallbackList<IProcessObserver> mProcessObservers 1114 = new RemoteCallbackList<IProcessObserver>(); 1115 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1116 1117 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1118 = new ArrayList<ProcessChangeItem>(); 1119 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1120 = new ArrayList<ProcessChangeItem>(); 1121 1122 /** 1123 * Runtime CPU use collection thread. This object's lock is used to 1124 * perform synchronization with the thread (notifying it to run). 1125 */ 1126 final Thread mProcessCpuThread; 1127 1128 /** 1129 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1130 * Must acquire this object's lock when accessing it. 1131 * NOTE: this lock will be held while doing long operations (trawling 1132 * through all processes in /proc), so it should never be acquired by 1133 * any critical paths such as when holding the main activity manager lock. 1134 */ 1135 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1136 MONITOR_THREAD_CPU_USAGE); 1137 final AtomicLong mLastCpuTime = new AtomicLong(0); 1138 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1139 1140 long mLastWriteTime = 0; 1141 1142 /** 1143 * Used to retain an update lock when the foreground activity is in 1144 * immersive mode. 1145 */ 1146 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1147 1148 /** 1149 * Set to true after the system has finished booting. 1150 */ 1151 boolean mBooted = false; 1152 1153 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1154 int mProcessLimitOverride = -1; 1155 1156 WindowManagerService mWindowManager; 1157 1158 final ActivityThread mSystemThread; 1159 1160 // Holds the current foreground user's id 1161 int mCurrentUserId = 0; 1162 // Holds the target user's id during a user switch 1163 int mTargetUserId = UserHandle.USER_NULL; 1164 // If there are multiple profiles for the current user, their ids are here 1165 // Currently only the primary user can have managed profiles 1166 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1167 1168 /** 1169 * Mapping from each known user ID to the profile group ID it is associated with. 1170 */ 1171 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1172 1173 private UserManagerService mUserManager; 1174 1175 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1176 final ProcessRecord mApp; 1177 final int mPid; 1178 final IApplicationThread mAppThread; 1179 1180 AppDeathRecipient(ProcessRecord app, int pid, 1181 IApplicationThread thread) { 1182 if (localLOGV) Slog.v( 1183 TAG, "New death recipient " + this 1184 + " for thread " + thread.asBinder()); 1185 mApp = app; 1186 mPid = pid; 1187 mAppThread = thread; 1188 } 1189 1190 @Override 1191 public void binderDied() { 1192 if (localLOGV) Slog.v( 1193 TAG, "Death received in " + this 1194 + " for thread " + mAppThread.asBinder()); 1195 synchronized(ActivityManagerService.this) { 1196 appDiedLocked(mApp, mPid, mAppThread); 1197 } 1198 } 1199 } 1200 1201 static final int SHOW_ERROR_MSG = 1; 1202 static final int SHOW_NOT_RESPONDING_MSG = 2; 1203 static final int SHOW_FACTORY_ERROR_MSG = 3; 1204 static final int UPDATE_CONFIGURATION_MSG = 4; 1205 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1206 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1207 static final int SERVICE_TIMEOUT_MSG = 12; 1208 static final int UPDATE_TIME_ZONE = 13; 1209 static final int SHOW_UID_ERROR_MSG = 14; 1210 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1211 static final int PROC_START_TIMEOUT_MSG = 20; 1212 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1213 static final int KILL_APPLICATION_MSG = 22; 1214 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1215 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1216 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1217 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1218 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1219 static final int CLEAR_DNS_CACHE_MSG = 28; 1220 static final int UPDATE_HTTP_PROXY_MSG = 29; 1221 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1222 static final int DISPATCH_PROCESSES_CHANGED = 31; 1223 static final int DISPATCH_PROCESS_DIED = 32; 1224 static final int REPORT_MEM_USAGE_MSG = 33; 1225 static final int REPORT_USER_SWITCH_MSG = 34; 1226 static final int CONTINUE_USER_SWITCH_MSG = 35; 1227 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1228 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1229 static final int PERSIST_URI_GRANTS_MSG = 38; 1230 static final int REQUEST_ALL_PSS_MSG = 39; 1231 static final int START_PROFILES_MSG = 40; 1232 static final int UPDATE_TIME = 41; 1233 static final int SYSTEM_USER_START_MSG = 42; 1234 static final int SYSTEM_USER_CURRENT_MSG = 43; 1235 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1236 static final int FINISH_BOOTING_MSG = 45; 1237 static final int START_USER_SWITCH_MSG = 46; 1238 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1239 static final int DISMISS_DIALOG_MSG = 48; 1240 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1241 1242 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1243 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1244 static final int FIRST_COMPAT_MODE_MSG = 300; 1245 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1246 1247 CompatModeDialog mCompatModeDialog; 1248 long mLastMemUsageReportTime = 0; 1249 1250 /** 1251 * Flag whether the current user is a "monkey", i.e. whether 1252 * the UI is driven by a UI automation tool. 1253 */ 1254 private boolean mUserIsMonkey; 1255 1256 /** Flag whether the device has a Recents UI */ 1257 boolean mHasRecents; 1258 1259 /** The dimensions of the thumbnails in the Recents UI. */ 1260 int mThumbnailWidth; 1261 int mThumbnailHeight; 1262 1263 final ServiceThread mHandlerThread; 1264 final MainHandler mHandler; 1265 1266 final class MainHandler extends Handler { 1267 public MainHandler(Looper looper) { 1268 super(looper, null, true); 1269 } 1270 1271 @Override 1272 public void handleMessage(Message msg) { 1273 switch (msg.what) { 1274 case SHOW_ERROR_MSG: { 1275 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1276 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1277 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1278 synchronized (ActivityManagerService.this) { 1279 ProcessRecord proc = (ProcessRecord)data.get("app"); 1280 AppErrorResult res = (AppErrorResult) data.get("result"); 1281 if (proc != null && proc.crashDialog != null) { 1282 Slog.e(TAG, "App already has crash dialog: " + proc); 1283 if (res != null) { 1284 res.set(0); 1285 } 1286 return; 1287 } 1288 boolean isBackground = (UserHandle.getAppId(proc.uid) 1289 >= Process.FIRST_APPLICATION_UID 1290 && proc.pid != MY_PID); 1291 for (int userId : mCurrentProfileIds) { 1292 isBackground &= (proc.userId != userId); 1293 } 1294 if (isBackground && !showBackground) { 1295 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1296 if (res != null) { 1297 res.set(0); 1298 } 1299 return; 1300 } 1301 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1302 Dialog d = new AppErrorDialog(mContext, 1303 ActivityManagerService.this, res, proc); 1304 d.show(); 1305 proc.crashDialog = d; 1306 } else { 1307 // The device is asleep, so just pretend that the user 1308 // saw a crash dialog and hit "force quit". 1309 if (res != null) { 1310 res.set(0); 1311 } 1312 } 1313 } 1314 1315 ensureBootCompleted(); 1316 } break; 1317 case SHOW_NOT_RESPONDING_MSG: { 1318 synchronized (ActivityManagerService.this) { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 ProcessRecord proc = (ProcessRecord)data.get("app"); 1321 if (proc != null && proc.anrDialog != null) { 1322 Slog.e(TAG, "App already has anr dialog: " + proc); 1323 return; 1324 } 1325 1326 Intent intent = new Intent("android.intent.action.ANR"); 1327 if (!mProcessesReady) { 1328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1329 | Intent.FLAG_RECEIVER_FOREGROUND); 1330 } 1331 broadcastIntentLocked(null, null, intent, 1332 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1333 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1334 1335 if (mShowDialogs) { 1336 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1337 mContext, proc, (ActivityRecord)data.get("activity"), 1338 msg.arg1 != 0); 1339 d.show(); 1340 proc.anrDialog = d; 1341 } else { 1342 // Just kill the app if there is no dialog to be shown. 1343 killAppAtUsersRequest(proc, null); 1344 } 1345 } 1346 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1350 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1351 synchronized (ActivityManagerService.this) { 1352 ProcessRecord proc = (ProcessRecord) data.get("app"); 1353 if (proc == null) { 1354 Slog.e(TAG, "App not found when showing strict mode dialog."); 1355 break; 1356 } 1357 if (proc.crashDialog != null) { 1358 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1359 return; 1360 } 1361 AppErrorResult res = (AppErrorResult) data.get("result"); 1362 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1363 Dialog d = new StrictModeViolationDialog(mContext, 1364 ActivityManagerService.this, res, proc); 1365 d.show(); 1366 proc.crashDialog = d; 1367 } else { 1368 // The device is asleep, so just pretend that the user 1369 // saw a crash dialog and hit "force quit". 1370 res.set(0); 1371 } 1372 } 1373 ensureBootCompleted(); 1374 } break; 1375 case SHOW_FACTORY_ERROR_MSG: { 1376 Dialog d = new FactoryErrorDialog( 1377 mContext, msg.getData().getCharSequence("msg")); 1378 d.show(); 1379 ensureBootCompleted(); 1380 } break; 1381 case UPDATE_CONFIGURATION_MSG: { 1382 final ContentResolver resolver = mContext.getContentResolver(); 1383 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1384 } break; 1385 case GC_BACKGROUND_PROCESSES_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 performAppGcsIfAppropriateLocked(); 1388 } 1389 } break; 1390 case WAIT_FOR_DEBUGGER_MSG: { 1391 synchronized (ActivityManagerService.this) { 1392 ProcessRecord app = (ProcessRecord)msg.obj; 1393 if (msg.arg1 != 0) { 1394 if (!app.waitedForDebugger) { 1395 Dialog d = new AppWaitingForDebuggerDialog( 1396 ActivityManagerService.this, 1397 mContext, app); 1398 app.waitDialog = d; 1399 app.waitedForDebugger = true; 1400 d.show(); 1401 } 1402 } else { 1403 if (app.waitDialog != null) { 1404 app.waitDialog.dismiss(); 1405 app.waitDialog = null; 1406 } 1407 } 1408 } 1409 } break; 1410 case SERVICE_TIMEOUT_MSG: { 1411 if (mDidDexOpt) { 1412 mDidDexOpt = false; 1413 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1414 nmsg.obj = msg.obj; 1415 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1416 return; 1417 } 1418 mServices.serviceTimeout((ProcessRecord)msg.obj); 1419 } break; 1420 case UPDATE_TIME_ZONE: { 1421 synchronized (ActivityManagerService.this) { 1422 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1423 ProcessRecord r = mLruProcesses.get(i); 1424 if (r.thread != null) { 1425 try { 1426 r.thread.updateTimeZone(); 1427 } catch (RemoteException ex) { 1428 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1429 } 1430 } 1431 } 1432 } 1433 } break; 1434 case CLEAR_DNS_CACHE_MSG: { 1435 synchronized (ActivityManagerService.this) { 1436 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1437 ProcessRecord r = mLruProcesses.get(i); 1438 if (r.thread != null) { 1439 try { 1440 r.thread.clearDnsCache(); 1441 } catch (RemoteException ex) { 1442 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1443 } 1444 } 1445 } 1446 } 1447 } break; 1448 case UPDATE_HTTP_PROXY_MSG: { 1449 ProxyInfo proxy = (ProxyInfo)msg.obj; 1450 String host = ""; 1451 String port = ""; 1452 String exclList = ""; 1453 Uri pacFileUrl = Uri.EMPTY; 1454 if (proxy != null) { 1455 host = proxy.getHost(); 1456 port = Integer.toString(proxy.getPort()); 1457 exclList = proxy.getExclusionListAsString(); 1458 pacFileUrl = proxy.getPacFileUrl(); 1459 } 1460 synchronized (ActivityManagerService.this) { 1461 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1462 ProcessRecord r = mLruProcesses.get(i); 1463 if (r.thread != null) { 1464 try { 1465 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1466 } catch (RemoteException ex) { 1467 Slog.w(TAG, "Failed to update http proxy for: " + 1468 r.info.processName); 1469 } 1470 } 1471 } 1472 } 1473 } break; 1474 case SHOW_UID_ERROR_MSG: { 1475 if (mShowDialogs) { 1476 AlertDialog d = new BaseErrorDialog(mContext); 1477 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1478 d.setCancelable(false); 1479 d.setTitle(mContext.getText(R.string.android_system_label)); 1480 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1481 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1482 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1483 d.show(); 1484 } 1485 } break; 1486 case SHOW_FINGERPRINT_ERROR_MSG: { 1487 if (mShowDialogs) { 1488 AlertDialog d = new BaseErrorDialog(mContext); 1489 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1490 d.setCancelable(false); 1491 d.setTitle(mContext.getText(R.string.android_system_label)); 1492 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1493 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1494 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1495 d.show(); 1496 } 1497 } break; 1498 case PROC_START_TIMEOUT_MSG: { 1499 if (mDidDexOpt) { 1500 mDidDexOpt = false; 1501 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1502 nmsg.obj = msg.obj; 1503 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1504 return; 1505 } 1506 ProcessRecord app = (ProcessRecord)msg.obj; 1507 synchronized (ActivityManagerService.this) { 1508 processStartTimedOutLocked(app); 1509 } 1510 } break; 1511 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1512 synchronized (ActivityManagerService.this) { 1513 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1514 } 1515 } break; 1516 case KILL_APPLICATION_MSG: { 1517 synchronized (ActivityManagerService.this) { 1518 int appid = msg.arg1; 1519 boolean restart = (msg.arg2 == 1); 1520 Bundle bundle = (Bundle)msg.obj; 1521 String pkg = bundle.getString("pkg"); 1522 String reason = bundle.getString("reason"); 1523 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1524 false, UserHandle.USER_ALL, reason); 1525 } 1526 } break; 1527 case FINALIZE_PENDING_INTENT_MSG: { 1528 ((PendingIntentRecord)msg.obj).completeFinalize(); 1529 } break; 1530 case POST_HEAVY_NOTIFICATION_MSG: { 1531 INotificationManager inm = NotificationManager.getService(); 1532 if (inm == null) { 1533 return; 1534 } 1535 1536 ActivityRecord root = (ActivityRecord)msg.obj; 1537 ProcessRecord process = root.app; 1538 if (process == null) { 1539 return; 1540 } 1541 1542 try { 1543 Context context = mContext.createPackageContext(process.info.packageName, 0); 1544 String text = mContext.getString(R.string.heavy_weight_notification, 1545 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1546 Notification notification = new Notification(); 1547 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1548 notification.when = 0; 1549 notification.flags = Notification.FLAG_ONGOING_EVENT; 1550 notification.tickerText = text; 1551 notification.defaults = 0; // please be quiet 1552 notification.sound = null; 1553 notification.vibrate = null; 1554 notification.color = mContext.getResources().getColor( 1555 com.android.internal.R.color.system_notification_accent_color); 1556 notification.setLatestEventInfo(context, text, 1557 mContext.getText(R.string.heavy_weight_notification_detail), 1558 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1559 PendingIntent.FLAG_CANCEL_CURRENT, null, 1560 new UserHandle(root.userId))); 1561 1562 try { 1563 int[] outId = new int[1]; 1564 inm.enqueueNotificationWithTag("android", "android", null, 1565 R.string.heavy_weight_notification, 1566 notification, outId, root.userId); 1567 } catch (RuntimeException e) { 1568 Slog.w(ActivityManagerService.TAG, 1569 "Error showing notification for heavy-weight app", e); 1570 } catch (RemoteException e) { 1571 } 1572 } catch (NameNotFoundException e) { 1573 Slog.w(TAG, "Unable to create context for heavy notification", e); 1574 } 1575 } break; 1576 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1577 INotificationManager inm = NotificationManager.getService(); 1578 if (inm == null) { 1579 return; 1580 } 1581 try { 1582 inm.cancelNotificationWithTag("android", null, 1583 R.string.heavy_weight_notification, msg.arg1); 1584 } catch (RuntimeException e) { 1585 Slog.w(ActivityManagerService.TAG, 1586 "Error canceling notification for service", e); 1587 } catch (RemoteException e) { 1588 } 1589 } break; 1590 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1591 synchronized (ActivityManagerService.this) { 1592 checkExcessivePowerUsageLocked(true); 1593 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1594 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1595 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1596 } 1597 } break; 1598 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1599 synchronized (ActivityManagerService.this) { 1600 ActivityRecord ar = (ActivityRecord)msg.obj; 1601 if (mCompatModeDialog != null) { 1602 if (mCompatModeDialog.mAppInfo.packageName.equals( 1603 ar.info.applicationInfo.packageName)) { 1604 return; 1605 } 1606 mCompatModeDialog.dismiss(); 1607 mCompatModeDialog = null; 1608 } 1609 if (ar != null && false) { 1610 if (mCompatModePackages.getPackageAskCompatModeLocked( 1611 ar.packageName)) { 1612 int mode = mCompatModePackages.computeCompatModeLocked( 1613 ar.info.applicationInfo); 1614 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1615 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1616 mCompatModeDialog = new CompatModeDialog( 1617 ActivityManagerService.this, mContext, 1618 ar.info.applicationInfo); 1619 mCompatModeDialog.show(); 1620 } 1621 } 1622 } 1623 } 1624 break; 1625 } 1626 case DISPATCH_PROCESSES_CHANGED: { 1627 dispatchProcessesChanged(); 1628 break; 1629 } 1630 case DISPATCH_PROCESS_DIED: { 1631 final int pid = msg.arg1; 1632 final int uid = msg.arg2; 1633 dispatchProcessDied(pid, uid); 1634 break; 1635 } 1636 case REPORT_MEM_USAGE_MSG: { 1637 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1638 Thread thread = new Thread() { 1639 @Override public void run() { 1640 reportMemUsage(memInfos); 1641 } 1642 }; 1643 thread.start(); 1644 break; 1645 } 1646 case START_USER_SWITCH_MSG: { 1647 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1648 break; 1649 } 1650 case REPORT_USER_SWITCH_MSG: { 1651 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1652 break; 1653 } 1654 case CONTINUE_USER_SWITCH_MSG: { 1655 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1656 break; 1657 } 1658 case USER_SWITCH_TIMEOUT_MSG: { 1659 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1660 break; 1661 } 1662 case IMMERSIVE_MODE_LOCK_MSG: { 1663 final boolean nextState = (msg.arg1 != 0); 1664 if (mUpdateLock.isHeld() != nextState) { 1665 if (DEBUG_IMMERSIVE) { 1666 final ActivityRecord r = (ActivityRecord) msg.obj; 1667 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1668 } 1669 if (nextState) { 1670 mUpdateLock.acquire(); 1671 } else { 1672 mUpdateLock.release(); 1673 } 1674 } 1675 break; 1676 } 1677 case PERSIST_URI_GRANTS_MSG: { 1678 writeGrantedUriPermissions(); 1679 break; 1680 } 1681 case REQUEST_ALL_PSS_MSG: { 1682 synchronized (ActivityManagerService.this) { 1683 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1684 } 1685 break; 1686 } 1687 case START_PROFILES_MSG: { 1688 synchronized (ActivityManagerService.this) { 1689 startProfilesLocked(); 1690 } 1691 break; 1692 } 1693 case UPDATE_TIME: { 1694 synchronized (ActivityManagerService.this) { 1695 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1696 ProcessRecord r = mLruProcesses.get(i); 1697 if (r.thread != null) { 1698 try { 1699 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1700 } catch (RemoteException ex) { 1701 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1702 } 1703 } 1704 } 1705 } 1706 break; 1707 } 1708 case SYSTEM_USER_START_MSG: { 1709 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1710 Integer.toString(msg.arg1), msg.arg1); 1711 mSystemServiceManager.startUser(msg.arg1); 1712 break; 1713 } 1714 case SYSTEM_USER_CURRENT_MSG: { 1715 mBatteryStatsService.noteEvent( 1716 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1717 Integer.toString(msg.arg2), msg.arg2); 1718 mBatteryStatsService.noteEvent( 1719 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1720 Integer.toString(msg.arg1), msg.arg1); 1721 mSystemServiceManager.switchUser(msg.arg1); 1722 break; 1723 } 1724 case ENTER_ANIMATION_COMPLETE_MSG: { 1725 synchronized (ActivityManagerService.this) { 1726 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1727 if (r != null && r.app != null && r.app.thread != null) { 1728 try { 1729 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1730 } catch (RemoteException e) { 1731 } 1732 } 1733 } 1734 break; 1735 } 1736 case FINISH_BOOTING_MSG: { 1737 if (msg.arg1 != 0) { 1738 finishBooting(); 1739 } 1740 if (msg.arg2 != 0) { 1741 enableScreenAfterBoot(); 1742 } 1743 break; 1744 } 1745 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1746 try { 1747 Locale l = (Locale) msg.obj; 1748 IBinder service = ServiceManager.getService("mount"); 1749 IMountService mountService = IMountService.Stub.asInterface(service); 1750 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1751 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1752 } catch (RemoteException e) { 1753 Log.e(TAG, "Error storing locale for decryption UI", e); 1754 } 1755 break; 1756 } 1757 case DISMISS_DIALOG_MSG: { 1758 final Dialog d = (Dialog) msg.obj; 1759 d.dismiss(); 1760 break; 1761 } 1762 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1763 synchronized (ActivityManagerService.this) { 1764 int i = mTaskStackListeners.beginBroadcast(); 1765 while (i > 0) { 1766 i--; 1767 try { 1768 // Make a one-way callback to the listener 1769 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1770 } catch (RemoteException e){ 1771 // Handled by the RemoteCallbackList 1772 } 1773 } 1774 mTaskStackListeners.finishBroadcast(); 1775 } 1776 break; 1777 } 1778 } 1779 } 1780 }; 1781 1782 static final int COLLECT_PSS_BG_MSG = 1; 1783 1784 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1785 @Override 1786 public void handleMessage(Message msg) { 1787 switch (msg.what) { 1788 case COLLECT_PSS_BG_MSG: { 1789 long start = SystemClock.uptimeMillis(); 1790 MemInfoReader memInfo = null; 1791 synchronized (ActivityManagerService.this) { 1792 if (mFullPssPending) { 1793 mFullPssPending = false; 1794 memInfo = new MemInfoReader(); 1795 } 1796 } 1797 if (memInfo != null) { 1798 updateCpuStatsNow(); 1799 long nativeTotalPss = 0; 1800 synchronized (mProcessCpuTracker) { 1801 final int N = mProcessCpuTracker.countStats(); 1802 for (int j=0; j<N; j++) { 1803 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1804 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1805 // This is definitely an application process; skip it. 1806 continue; 1807 } 1808 synchronized (mPidsSelfLocked) { 1809 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1810 // This is one of our own processes; skip it. 1811 continue; 1812 } 1813 } 1814 nativeTotalPss += Debug.getPss(st.pid, null, null); 1815 } 1816 } 1817 memInfo.readMemInfo(); 1818 synchronized (ActivityManagerService.this) { 1819 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1820 + (SystemClock.uptimeMillis()-start) + "ms"); 1821 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1822 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1823 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1824 } 1825 } 1826 1827 int num = 0; 1828 long[] tmp = new long[1]; 1829 do { 1830 ProcessRecord proc; 1831 int procState; 1832 int pid; 1833 long lastPssTime; 1834 synchronized (ActivityManagerService.this) { 1835 if (mPendingPssProcesses.size() <= 0) { 1836 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1837 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1838 mPendingPssProcesses.clear(); 1839 return; 1840 } 1841 proc = mPendingPssProcesses.remove(0); 1842 procState = proc.pssProcState; 1843 lastPssTime = proc.lastPssTime; 1844 if (proc.thread != null && procState == proc.setProcState 1845 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1846 < SystemClock.uptimeMillis()) { 1847 pid = proc.pid; 1848 } else { 1849 proc = null; 1850 pid = 0; 1851 } 1852 } 1853 if (proc != null) { 1854 long pss = Debug.getPss(pid, tmp, null); 1855 synchronized (ActivityManagerService.this) { 1856 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1857 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1858 num++; 1859 recordPssSample(proc, procState, pss, tmp[0], 1860 SystemClock.uptimeMillis()); 1861 } 1862 } 1863 } 1864 } while (true); 1865 } 1866 } 1867 } 1868 }; 1869 1870 public void setSystemProcess() { 1871 try { 1872 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1873 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1874 ServiceManager.addService("meminfo", new MemBinder(this)); 1875 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1876 ServiceManager.addService("dbinfo", new DbBinder(this)); 1877 if (MONITOR_CPU_USAGE) { 1878 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1879 } 1880 ServiceManager.addService("permission", new PermissionController(this)); 1881 1882 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1883 "android", STOCK_PM_FLAGS); 1884 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1885 1886 synchronized (this) { 1887 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1888 app.persistent = true; 1889 app.pid = MY_PID; 1890 app.maxAdj = ProcessList.SYSTEM_ADJ; 1891 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1892 mProcessNames.put(app.processName, app.uid, app); 1893 synchronized (mPidsSelfLocked) { 1894 mPidsSelfLocked.put(app.pid, app); 1895 } 1896 updateLruProcessLocked(app, false, null); 1897 updateOomAdjLocked(); 1898 } 1899 } catch (PackageManager.NameNotFoundException e) { 1900 throw new RuntimeException( 1901 "Unable to find android system package", e); 1902 } 1903 } 1904 1905 public void setWindowManager(WindowManagerService wm) { 1906 mWindowManager = wm; 1907 mStackSupervisor.setWindowManager(wm); 1908 } 1909 1910 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1911 mUsageStatsService = usageStatsManager; 1912 } 1913 1914 public void startObservingNativeCrashes() { 1915 final NativeCrashListener ncl = new NativeCrashListener(this); 1916 ncl.start(); 1917 } 1918 1919 public IAppOpsService getAppOpsService() { 1920 return mAppOpsService; 1921 } 1922 1923 static class MemBinder extends Binder { 1924 ActivityManagerService mActivityManagerService; 1925 MemBinder(ActivityManagerService activityManagerService) { 1926 mActivityManagerService = activityManagerService; 1927 } 1928 1929 @Override 1930 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1931 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1932 != PackageManager.PERMISSION_GRANTED) { 1933 pw.println("Permission Denial: can't dump meminfo from from pid=" 1934 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1935 + " without permission " + android.Manifest.permission.DUMP); 1936 return; 1937 } 1938 1939 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1940 } 1941 } 1942 1943 static class GraphicsBinder extends Binder { 1944 ActivityManagerService mActivityManagerService; 1945 GraphicsBinder(ActivityManagerService activityManagerService) { 1946 mActivityManagerService = activityManagerService; 1947 } 1948 1949 @Override 1950 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1951 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1952 != PackageManager.PERMISSION_GRANTED) { 1953 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1954 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1955 + " without permission " + android.Manifest.permission.DUMP); 1956 return; 1957 } 1958 1959 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1960 } 1961 } 1962 1963 static class DbBinder extends Binder { 1964 ActivityManagerService mActivityManagerService; 1965 DbBinder(ActivityManagerService activityManagerService) { 1966 mActivityManagerService = activityManagerService; 1967 } 1968 1969 @Override 1970 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1971 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1972 != PackageManager.PERMISSION_GRANTED) { 1973 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1974 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1975 + " without permission " + android.Manifest.permission.DUMP); 1976 return; 1977 } 1978 1979 mActivityManagerService.dumpDbInfo(fd, pw, args); 1980 } 1981 } 1982 1983 static class CpuBinder extends Binder { 1984 ActivityManagerService mActivityManagerService; 1985 CpuBinder(ActivityManagerService activityManagerService) { 1986 mActivityManagerService = activityManagerService; 1987 } 1988 1989 @Override 1990 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1991 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1992 != PackageManager.PERMISSION_GRANTED) { 1993 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1994 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1995 + " without permission " + android.Manifest.permission.DUMP); 1996 return; 1997 } 1998 1999 synchronized (mActivityManagerService.mProcessCpuTracker) { 2000 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2001 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2002 SystemClock.uptimeMillis())); 2003 } 2004 } 2005 } 2006 2007 public static final class Lifecycle extends SystemService { 2008 private final ActivityManagerService mService; 2009 2010 public Lifecycle(Context context) { 2011 super(context); 2012 mService = new ActivityManagerService(context); 2013 } 2014 2015 @Override 2016 public void onStart() { 2017 mService.start(); 2018 } 2019 2020 public ActivityManagerService getService() { 2021 return mService; 2022 } 2023 } 2024 2025 // Note: This method is invoked on the main thread but may need to attach various 2026 // handlers to other threads. So take care to be explicit about the looper. 2027 public ActivityManagerService(Context systemContext) { 2028 mContext = systemContext; 2029 mFactoryTest = FactoryTest.getMode(); 2030 mSystemThread = ActivityThread.currentActivityThread(); 2031 2032 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2033 2034 mHandlerThread = new ServiceThread(TAG, 2035 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2036 mHandlerThread.start(); 2037 mHandler = new MainHandler(mHandlerThread.getLooper()); 2038 2039 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2040 "foreground", BROADCAST_FG_TIMEOUT, false); 2041 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2042 "background", BROADCAST_BG_TIMEOUT, true); 2043 mBroadcastQueues[0] = mFgBroadcastQueue; 2044 mBroadcastQueues[1] = mBgBroadcastQueue; 2045 2046 mServices = new ActiveServices(this); 2047 mProviderMap = new ProviderMap(this); 2048 2049 // TODO: Move creation of battery stats service outside of activity manager service. 2050 File dataDir = Environment.getDataDirectory(); 2051 File systemDir = new File(dataDir, "system"); 2052 systemDir.mkdirs(); 2053 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2054 mBatteryStatsService.getActiveStatistics().readLocked(); 2055 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2056 mOnBattery = DEBUG_POWER ? true 2057 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2058 mBatteryStatsService.getActiveStatistics().setCallback(this); 2059 2060 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2061 2062 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2063 2064 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2065 2066 // User 0 is the first and only user that runs at boot. 2067 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2068 mUserLru.add(Integer.valueOf(0)); 2069 updateStartedUserArrayLocked(); 2070 2071 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2072 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2073 2074 mConfiguration.setToDefaults(); 2075 mConfiguration.setLocale(Locale.getDefault()); 2076 2077 mConfigurationSeq = mConfiguration.seq = 1; 2078 mProcessCpuTracker.init(); 2079 2080 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2081 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2082 mStackSupervisor = new ActivityStackSupervisor(this); 2083 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2084 2085 mProcessCpuThread = new Thread("CpuTracker") { 2086 @Override 2087 public void run() { 2088 while (true) { 2089 try { 2090 try { 2091 synchronized(this) { 2092 final long now = SystemClock.uptimeMillis(); 2093 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2094 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2095 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2096 // + ", write delay=" + nextWriteDelay); 2097 if (nextWriteDelay < nextCpuDelay) { 2098 nextCpuDelay = nextWriteDelay; 2099 } 2100 if (nextCpuDelay > 0) { 2101 mProcessCpuMutexFree.set(true); 2102 this.wait(nextCpuDelay); 2103 } 2104 } 2105 } catch (InterruptedException e) { 2106 } 2107 updateCpuStatsNow(); 2108 } catch (Exception e) { 2109 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2110 } 2111 } 2112 } 2113 }; 2114 2115 Watchdog.getInstance().addMonitor(this); 2116 Watchdog.getInstance().addThread(mHandler); 2117 } 2118 2119 public void setSystemServiceManager(SystemServiceManager mgr) { 2120 mSystemServiceManager = mgr; 2121 } 2122 2123 public void setInstaller(Installer installer) { 2124 mInstaller = installer; 2125 } 2126 2127 private void start() { 2128 Process.removeAllProcessGroups(); 2129 mProcessCpuThread.start(); 2130 2131 mBatteryStatsService.publish(mContext); 2132 mAppOpsService.publish(mContext); 2133 Slog.d("AppOps", "AppOpsService published"); 2134 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2135 } 2136 2137 public void initPowerManagement() { 2138 mStackSupervisor.initPowerManagement(); 2139 mBatteryStatsService.initPowerManagement(); 2140 } 2141 2142 @Override 2143 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2144 throws RemoteException { 2145 if (code == SYSPROPS_TRANSACTION) { 2146 // We need to tell all apps about the system property change. 2147 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2148 synchronized(this) { 2149 final int NP = mProcessNames.getMap().size(); 2150 for (int ip=0; ip<NP; ip++) { 2151 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2152 final int NA = apps.size(); 2153 for (int ia=0; ia<NA; ia++) { 2154 ProcessRecord app = apps.valueAt(ia); 2155 if (app.thread != null) { 2156 procs.add(app.thread.asBinder()); 2157 } 2158 } 2159 } 2160 } 2161 2162 int N = procs.size(); 2163 for (int i=0; i<N; i++) { 2164 Parcel data2 = Parcel.obtain(); 2165 try { 2166 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2167 } catch (RemoteException e) { 2168 } 2169 data2.recycle(); 2170 } 2171 } 2172 try { 2173 return super.onTransact(code, data, reply, flags); 2174 } catch (RuntimeException e) { 2175 // The activity manager only throws security exceptions, so let's 2176 // log all others. 2177 if (!(e instanceof SecurityException)) { 2178 Slog.wtf(TAG, "Activity Manager Crash", e); 2179 } 2180 throw e; 2181 } 2182 } 2183 2184 void updateCpuStats() { 2185 final long now = SystemClock.uptimeMillis(); 2186 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2187 return; 2188 } 2189 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2190 synchronized (mProcessCpuThread) { 2191 mProcessCpuThread.notify(); 2192 } 2193 } 2194 } 2195 2196 void updateCpuStatsNow() { 2197 synchronized (mProcessCpuTracker) { 2198 mProcessCpuMutexFree.set(false); 2199 final long now = SystemClock.uptimeMillis(); 2200 boolean haveNewCpuStats = false; 2201 2202 if (MONITOR_CPU_USAGE && 2203 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2204 mLastCpuTime.set(now); 2205 haveNewCpuStats = true; 2206 mProcessCpuTracker.update(); 2207 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2208 //Slog.i(TAG, "Total CPU usage: " 2209 // + mProcessCpu.getTotalCpuPercent() + "%"); 2210 2211 // Slog the cpu usage if the property is set. 2212 if ("true".equals(SystemProperties.get("events.cpu"))) { 2213 int user = mProcessCpuTracker.getLastUserTime(); 2214 int system = mProcessCpuTracker.getLastSystemTime(); 2215 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2216 int irq = mProcessCpuTracker.getLastIrqTime(); 2217 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2218 int idle = mProcessCpuTracker.getLastIdleTime(); 2219 2220 int total = user + system + iowait + irq + softIrq + idle; 2221 if (total == 0) total = 1; 2222 2223 EventLog.writeEvent(EventLogTags.CPU, 2224 ((user+system+iowait+irq+softIrq) * 100) / total, 2225 (user * 100) / total, 2226 (system * 100) / total, 2227 (iowait * 100) / total, 2228 (irq * 100) / total, 2229 (softIrq * 100) / total); 2230 } 2231 } 2232 2233 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2234 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2235 synchronized(bstats) { 2236 synchronized(mPidsSelfLocked) { 2237 if (haveNewCpuStats) { 2238 if (mOnBattery) { 2239 int perc = bstats.startAddingCpuLocked(); 2240 int totalUTime = 0; 2241 int totalSTime = 0; 2242 final int N = mProcessCpuTracker.countStats(); 2243 for (int i=0; i<N; i++) { 2244 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2245 if (!st.working) { 2246 continue; 2247 } 2248 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2249 int otherUTime = (st.rel_utime*perc)/100; 2250 int otherSTime = (st.rel_stime*perc)/100; 2251 totalUTime += otherUTime; 2252 totalSTime += otherSTime; 2253 if (pr != null) { 2254 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2255 if (ps == null || !ps.isActive()) { 2256 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2257 pr.info.uid, pr.processName); 2258 } 2259 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2260 st.rel_stime-otherSTime); 2261 ps.addSpeedStepTimes(cpuSpeedTimes); 2262 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2263 } else { 2264 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2265 if (ps == null || !ps.isActive()) { 2266 st.batteryStats = ps = bstats.getProcessStatsLocked( 2267 bstats.mapUid(st.uid), st.name); 2268 } 2269 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2270 st.rel_stime-otherSTime); 2271 ps.addSpeedStepTimes(cpuSpeedTimes); 2272 } 2273 } 2274 bstats.finishAddingCpuLocked(perc, totalUTime, 2275 totalSTime, cpuSpeedTimes); 2276 } 2277 } 2278 } 2279 2280 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2281 mLastWriteTime = now; 2282 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2283 } 2284 } 2285 } 2286 } 2287 2288 @Override 2289 public void batteryNeedsCpuUpdate() { 2290 updateCpuStatsNow(); 2291 } 2292 2293 @Override 2294 public void batteryPowerChanged(boolean onBattery) { 2295 // When plugging in, update the CPU stats first before changing 2296 // the plug state. 2297 updateCpuStatsNow(); 2298 synchronized (this) { 2299 synchronized(mPidsSelfLocked) { 2300 mOnBattery = DEBUG_POWER ? true : onBattery; 2301 } 2302 } 2303 } 2304 2305 /** 2306 * Initialize the application bind args. These are passed to each 2307 * process when the bindApplication() IPC is sent to the process. They're 2308 * lazily setup to make sure the services are running when they're asked for. 2309 */ 2310 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2311 if (mAppBindArgs == null) { 2312 mAppBindArgs = new HashMap<>(); 2313 2314 // Isolated processes won't get this optimization, so that we don't 2315 // violate the rules about which services they have access to. 2316 if (!isolated) { 2317 // Setup the application init args 2318 mAppBindArgs.put("package", ServiceManager.getService("package")); 2319 mAppBindArgs.put("window", ServiceManager.getService("window")); 2320 mAppBindArgs.put(Context.ALARM_SERVICE, 2321 ServiceManager.getService(Context.ALARM_SERVICE)); 2322 } 2323 } 2324 return mAppBindArgs; 2325 } 2326 2327 final void setFocusedActivityLocked(ActivityRecord r) { 2328 if (mFocusedActivity != r) { 2329 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2330 mFocusedActivity = r; 2331 if (r.task != null && r.task.voiceInteractor != null) { 2332 startRunningVoiceLocked(); 2333 } else { 2334 finishRunningVoiceLocked(); 2335 } 2336 mStackSupervisor.setFocusedStack(r); 2337 if (r != null) { 2338 mWindowManager.setFocusedApp(r.appToken, true); 2339 } 2340 applyUpdateLockStateLocked(r); 2341 } 2342 } 2343 2344 final void clearFocusedActivity(ActivityRecord r) { 2345 if (mFocusedActivity == r) { 2346 mFocusedActivity = null; 2347 } 2348 } 2349 2350 @Override 2351 public void setFocusedStack(int stackId) { 2352 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2353 synchronized (ActivityManagerService.this) { 2354 ActivityStack stack = mStackSupervisor.getStack(stackId); 2355 if (stack != null) { 2356 ActivityRecord r = stack.topRunningActivityLocked(null); 2357 if (r != null) { 2358 setFocusedActivityLocked(r); 2359 } 2360 } 2361 } 2362 } 2363 2364 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2365 @Override 2366 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2367 synchronized (ActivityManagerService.this) { 2368 if (listener != null) { 2369 mTaskStackListeners.register(listener); 2370 } 2371 } 2372 } 2373 2374 @Override 2375 public void notifyActivityDrawn(IBinder token) { 2376 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2377 synchronized (this) { 2378 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2379 if (r != null) { 2380 r.task.stack.notifyActivityDrawnLocked(r); 2381 } 2382 } 2383 } 2384 2385 final void applyUpdateLockStateLocked(ActivityRecord r) { 2386 // Modifications to the UpdateLock state are done on our handler, outside 2387 // the activity manager's locks. The new state is determined based on the 2388 // state *now* of the relevant activity record. The object is passed to 2389 // the handler solely for logging detail, not to be consulted/modified. 2390 final boolean nextState = r != null && r.immersive; 2391 mHandler.sendMessage( 2392 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2393 } 2394 2395 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2396 Message msg = Message.obtain(); 2397 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2398 msg.obj = r.task.askedCompatMode ? null : r; 2399 mHandler.sendMessage(msg); 2400 } 2401 2402 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2403 String what, Object obj, ProcessRecord srcApp) { 2404 app.lastActivityTime = now; 2405 2406 if (app.activities.size() > 0) { 2407 // Don't want to touch dependent processes that are hosting activities. 2408 return index; 2409 } 2410 2411 int lrui = mLruProcesses.lastIndexOf(app); 2412 if (lrui < 0) { 2413 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2414 + what + " " + obj + " from " + srcApp); 2415 return index; 2416 } 2417 2418 if (lrui >= index) { 2419 // Don't want to cause this to move dependent processes *back* in the 2420 // list as if they were less frequently used. 2421 return index; 2422 } 2423 2424 if (lrui >= mLruProcessActivityStart) { 2425 // Don't want to touch dependent processes that are hosting activities. 2426 return index; 2427 } 2428 2429 mLruProcesses.remove(lrui); 2430 if (index > 0) { 2431 index--; 2432 } 2433 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2434 + " in LRU list: " + app); 2435 mLruProcesses.add(index, app); 2436 return index; 2437 } 2438 2439 final void removeLruProcessLocked(ProcessRecord app) { 2440 int lrui = mLruProcesses.lastIndexOf(app); 2441 if (lrui >= 0) { 2442 if (!app.killed) { 2443 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2444 Process.killProcessQuiet(app.pid); 2445 Process.killProcessGroup(app.info.uid, app.pid); 2446 } 2447 if (lrui <= mLruProcessActivityStart) { 2448 mLruProcessActivityStart--; 2449 } 2450 if (lrui <= mLruProcessServiceStart) { 2451 mLruProcessServiceStart--; 2452 } 2453 mLruProcesses.remove(lrui); 2454 } 2455 } 2456 2457 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2458 ProcessRecord client) { 2459 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2460 || app.treatLikeActivity; 2461 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2462 if (!activityChange && hasActivity) { 2463 // The process has activities, so we are only allowing activity-based adjustments 2464 // to move it. It should be kept in the front of the list with other 2465 // processes that have activities, and we don't want those to change their 2466 // order except due to activity operations. 2467 return; 2468 } 2469 2470 mLruSeq++; 2471 final long now = SystemClock.uptimeMillis(); 2472 app.lastActivityTime = now; 2473 2474 // First a quick reject: if the app is already at the position we will 2475 // put it, then there is nothing to do. 2476 if (hasActivity) { 2477 final int N = mLruProcesses.size(); 2478 if (N > 0 && mLruProcesses.get(N-1) == app) { 2479 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2480 return; 2481 } 2482 } else { 2483 if (mLruProcessServiceStart > 0 2484 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2485 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2486 return; 2487 } 2488 } 2489 2490 int lrui = mLruProcesses.lastIndexOf(app); 2491 2492 if (app.persistent && lrui >= 0) { 2493 // We don't care about the position of persistent processes, as long as 2494 // they are in the list. 2495 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2496 return; 2497 } 2498 2499 /* In progress: compute new position first, so we can avoid doing work 2500 if the process is not actually going to move. Not yet working. 2501 int addIndex; 2502 int nextIndex; 2503 boolean inActivity = false, inService = false; 2504 if (hasActivity) { 2505 // Process has activities, put it at the very tipsy-top. 2506 addIndex = mLruProcesses.size(); 2507 nextIndex = mLruProcessServiceStart; 2508 inActivity = true; 2509 } else if (hasService) { 2510 // Process has services, put it at the top of the service list. 2511 addIndex = mLruProcessActivityStart; 2512 nextIndex = mLruProcessServiceStart; 2513 inActivity = true; 2514 inService = true; 2515 } else { 2516 // Process not otherwise of interest, it goes to the top of the non-service area. 2517 addIndex = mLruProcessServiceStart; 2518 if (client != null) { 2519 int clientIndex = mLruProcesses.lastIndexOf(client); 2520 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2521 + app); 2522 if (clientIndex >= 0 && addIndex > clientIndex) { 2523 addIndex = clientIndex; 2524 } 2525 } 2526 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2527 } 2528 2529 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2530 + mLruProcessActivityStart + "): " + app); 2531 */ 2532 2533 if (lrui >= 0) { 2534 if (lrui < mLruProcessActivityStart) { 2535 mLruProcessActivityStart--; 2536 } 2537 if (lrui < mLruProcessServiceStart) { 2538 mLruProcessServiceStart--; 2539 } 2540 /* 2541 if (addIndex > lrui) { 2542 addIndex--; 2543 } 2544 if (nextIndex > lrui) { 2545 nextIndex--; 2546 } 2547 */ 2548 mLruProcesses.remove(lrui); 2549 } 2550 2551 /* 2552 mLruProcesses.add(addIndex, app); 2553 if (inActivity) { 2554 mLruProcessActivityStart++; 2555 } 2556 if (inService) { 2557 mLruProcessActivityStart++; 2558 } 2559 */ 2560 2561 int nextIndex; 2562 if (hasActivity) { 2563 final int N = mLruProcesses.size(); 2564 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2565 // Process doesn't have activities, but has clients with 2566 // activities... move it up, but one below the top (the top 2567 // should always have a real activity). 2568 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2569 mLruProcesses.add(N-1, app); 2570 // To keep it from spamming the LRU list (by making a bunch of clients), 2571 // we will push down any other entries owned by the app. 2572 final int uid = app.info.uid; 2573 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2574 ProcessRecord subProc = mLruProcesses.get(i); 2575 if (subProc.info.uid == uid) { 2576 // We want to push this one down the list. If the process after 2577 // it is for the same uid, however, don't do so, because we don't 2578 // want them internally to be re-ordered. 2579 if (mLruProcesses.get(i-1).info.uid != uid) { 2580 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2581 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2582 ProcessRecord tmp = mLruProcesses.get(i); 2583 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2584 mLruProcesses.set(i-1, tmp); 2585 i--; 2586 } 2587 } else { 2588 // A gap, we can stop here. 2589 break; 2590 } 2591 } 2592 } else { 2593 // Process has activities, put it at the very tipsy-top. 2594 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2595 mLruProcesses.add(app); 2596 } 2597 nextIndex = mLruProcessServiceStart; 2598 } else if (hasService) { 2599 // Process has services, put it at the top of the service list. 2600 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2601 mLruProcesses.add(mLruProcessActivityStart, app); 2602 nextIndex = mLruProcessServiceStart; 2603 mLruProcessActivityStart++; 2604 } else { 2605 // Process not otherwise of interest, it goes to the top of the non-service area. 2606 int index = mLruProcessServiceStart; 2607 if (client != null) { 2608 // If there is a client, don't allow the process to be moved up higher 2609 // in the list than that client. 2610 int clientIndex = mLruProcesses.lastIndexOf(client); 2611 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2612 + " when updating " + app); 2613 if (clientIndex <= lrui) { 2614 // Don't allow the client index restriction to push it down farther in the 2615 // list than it already is. 2616 clientIndex = lrui; 2617 } 2618 if (clientIndex >= 0 && index > clientIndex) { 2619 index = clientIndex; 2620 } 2621 } 2622 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2623 mLruProcesses.add(index, app); 2624 nextIndex = index-1; 2625 mLruProcessActivityStart++; 2626 mLruProcessServiceStart++; 2627 } 2628 2629 // If the app is currently using a content provider or service, 2630 // bump those processes as well. 2631 for (int j=app.connections.size()-1; j>=0; j--) { 2632 ConnectionRecord cr = app.connections.valueAt(j); 2633 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2634 && cr.binding.service.app != null 2635 && cr.binding.service.app.lruSeq != mLruSeq 2636 && !cr.binding.service.app.persistent) { 2637 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2638 "service connection", cr, app); 2639 } 2640 } 2641 for (int j=app.conProviders.size()-1; j>=0; j--) { 2642 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2643 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2644 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2645 "provider reference", cpr, app); 2646 } 2647 } 2648 } 2649 2650 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2651 if (uid == Process.SYSTEM_UID) { 2652 // The system gets to run in any process. If there are multiple 2653 // processes with the same uid, just pick the first (this 2654 // should never happen). 2655 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2656 if (procs == null) return null; 2657 final int N = procs.size(); 2658 for (int i = 0; i < N; i++) { 2659 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2660 } 2661 } 2662 ProcessRecord proc = mProcessNames.get(processName, uid); 2663 if (false && proc != null && !keepIfLarge 2664 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2665 && proc.lastCachedPss >= 4000) { 2666 // Turn this condition on to cause killing to happen regularly, for testing. 2667 if (proc.baseProcessTracker != null) { 2668 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2669 } 2670 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2671 } else if (proc != null && !keepIfLarge 2672 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2673 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2674 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2675 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2676 if (proc.baseProcessTracker != null) { 2677 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2678 } 2679 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2680 } 2681 } 2682 return proc; 2683 } 2684 2685 void ensurePackageDexOpt(String packageName) { 2686 IPackageManager pm = AppGlobals.getPackageManager(); 2687 try { 2688 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2689 mDidDexOpt = true; 2690 } 2691 } catch (RemoteException e) { 2692 } 2693 } 2694 2695 boolean isNextTransitionForward() { 2696 int transit = mWindowManager.getPendingAppTransition(); 2697 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2698 || transit == AppTransition.TRANSIT_TASK_OPEN 2699 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2700 } 2701 2702 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2703 String processName, String abiOverride, int uid, Runnable crashHandler) { 2704 synchronized(this) { 2705 ApplicationInfo info = new ApplicationInfo(); 2706 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2707 // For isolated processes, the former contains the parent's uid and the latter the 2708 // actual uid of the isolated process. 2709 // In the special case introduced by this method (which is, starting an isolated 2710 // process directly from the SystemServer without an actual parent app process) the 2711 // closest thing to a parent's uid is SYSTEM_UID. 2712 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2713 // the |isolated| logic in the ProcessRecord constructor. 2714 info.uid = Process.SYSTEM_UID; 2715 info.processName = processName; 2716 info.className = entryPoint; 2717 info.packageName = "android"; 2718 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2719 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2720 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2721 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2722 crashHandler); 2723 return proc != null ? proc.pid : 0; 2724 } 2725 } 2726 2727 final ProcessRecord startProcessLocked(String processName, 2728 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2729 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2730 boolean isolated, boolean keepIfLarge) { 2731 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2732 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2733 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2734 null /* crashHandler */); 2735 } 2736 2737 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2738 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2739 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2740 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2741 long startTime = SystemClock.elapsedRealtime(); 2742 ProcessRecord app; 2743 if (!isolated) { 2744 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2745 checkTime(startTime, "startProcess: after getProcessRecord"); 2746 } else { 2747 // If this is an isolated process, it can't re-use an existing process. 2748 app = null; 2749 } 2750 // We don't have to do anything more if: 2751 // (1) There is an existing application record; and 2752 // (2) The caller doesn't think it is dead, OR there is no thread 2753 // object attached to it so we know it couldn't have crashed; and 2754 // (3) There is a pid assigned to it, so it is either starting or 2755 // already running. 2756 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2757 + " app=" + app + " knownToBeDead=" + knownToBeDead 2758 + " thread=" + (app != null ? app.thread : null) 2759 + " pid=" + (app != null ? app.pid : -1)); 2760 if (app != null && app.pid > 0) { 2761 if (!knownToBeDead || app.thread == null) { 2762 // We already have the app running, or are waiting for it to 2763 // come up (we have a pid but not yet its thread), so keep it. 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2765 // If this is a new package in the process, add the package to the list 2766 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2767 checkTime(startTime, "startProcess: done, added package to proc"); 2768 return app; 2769 } 2770 2771 // An application record is attached to a previous process, 2772 // clean it up now. 2773 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2774 checkTime(startTime, "startProcess: bad proc running, killing"); 2775 Process.killProcessGroup(app.info.uid, app.pid); 2776 handleAppDiedLocked(app, true, true); 2777 checkTime(startTime, "startProcess: done killing old proc"); 2778 } 2779 2780 String hostingNameStr = hostingName != null 2781 ? hostingName.flattenToShortString() : null; 2782 2783 if (!isolated) { 2784 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2785 // If we are in the background, then check to see if this process 2786 // is bad. If so, we will just silently fail. 2787 if (mBadProcesses.get(info.processName, info.uid) != null) { 2788 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2789 + "/" + info.processName); 2790 return null; 2791 } 2792 } else { 2793 // When the user is explicitly starting a process, then clear its 2794 // crash count so that we won't make it bad until they see at 2795 // least one crash dialog again, and make the process good again 2796 // if it had been bad. 2797 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2798 + "/" + info.processName); 2799 mProcessCrashTimes.remove(info.processName, info.uid); 2800 if (mBadProcesses.get(info.processName, info.uid) != null) { 2801 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2802 UserHandle.getUserId(info.uid), info.uid, 2803 info.processName); 2804 mBadProcesses.remove(info.processName, info.uid); 2805 if (app != null) { 2806 app.bad = false; 2807 } 2808 } 2809 } 2810 } 2811 2812 if (app == null) { 2813 checkTime(startTime, "startProcess: creating new process record"); 2814 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2815 if (app == null) { 2816 Slog.w(TAG, "Failed making new process record for " 2817 + processName + "/" + info.uid + " isolated=" + isolated); 2818 return null; 2819 } 2820 app.crashHandler = crashHandler; 2821 mProcessNames.put(processName, app.uid, app); 2822 if (isolated) { 2823 mIsolatedProcesses.put(app.uid, app); 2824 } 2825 checkTime(startTime, "startProcess: done creating new process record"); 2826 } else { 2827 // If this is a new package in the process, add the package to the list 2828 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2829 checkTime(startTime, "startProcess: added package to existing proc"); 2830 } 2831 2832 // If the system is not ready yet, then hold off on starting this 2833 // process until it is. 2834 if (!mProcessesReady 2835 && !isAllowedWhileBooting(info) 2836 && !allowWhileBooting) { 2837 if (!mProcessesOnHold.contains(app)) { 2838 mProcessesOnHold.add(app); 2839 } 2840 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2841 checkTime(startTime, "startProcess: returning with proc on hold"); 2842 return app; 2843 } 2844 2845 checkTime(startTime, "startProcess: stepping in to startProcess"); 2846 startProcessLocked( 2847 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2848 checkTime(startTime, "startProcess: done starting proc!"); 2849 return (app.pid != 0) ? app : null; 2850 } 2851 2852 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2853 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2854 } 2855 2856 private final void startProcessLocked(ProcessRecord app, 2857 String hostingType, String hostingNameStr) { 2858 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2859 null /* entryPoint */, null /* entryPointArgs */); 2860 } 2861 2862 private final void startProcessLocked(ProcessRecord app, String hostingType, 2863 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2864 long startTime = SystemClock.elapsedRealtime(); 2865 if (app.pid > 0 && app.pid != MY_PID) { 2866 checkTime(startTime, "startProcess: removing from pids map"); 2867 synchronized (mPidsSelfLocked) { 2868 mPidsSelfLocked.remove(app.pid); 2869 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2870 } 2871 checkTime(startTime, "startProcess: done removing from pids map"); 2872 app.setPid(0); 2873 } 2874 2875 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2876 "startProcessLocked removing on hold: " + app); 2877 mProcessesOnHold.remove(app); 2878 2879 checkTime(startTime, "startProcess: starting to update cpu stats"); 2880 updateCpuStats(); 2881 checkTime(startTime, "startProcess: done updating cpu stats"); 2882 2883 try { 2884 int uid = app.uid; 2885 2886 int[] gids = null; 2887 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2888 if (!app.isolated) { 2889 int[] permGids = null; 2890 try { 2891 checkTime(startTime, "startProcess: getting gids from package manager"); 2892 final PackageManager pm = mContext.getPackageManager(); 2893 permGids = pm.getPackageGids(app.info.packageName); 2894 2895 if (Environment.isExternalStorageEmulated()) { 2896 checkTime(startTime, "startProcess: checking external storage perm"); 2897 if (pm.checkPermission( 2898 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2899 app.info.packageName) == PERMISSION_GRANTED) { 2900 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2901 } else { 2902 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2903 } 2904 } 2905 } catch (PackageManager.NameNotFoundException e) { 2906 Slog.w(TAG, "Unable to retrieve gids", e); 2907 } 2908 2909 /* 2910 * Add shared application and profile GIDs so applications can share some 2911 * resources like shared libraries and access user-wide resources 2912 */ 2913 if (permGids == null) { 2914 gids = new int[2]; 2915 } else { 2916 gids = new int[permGids.length + 2]; 2917 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2918 } 2919 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2920 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2921 } 2922 checkTime(startTime, "startProcess: building args"); 2923 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2924 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2925 && mTopComponent != null 2926 && app.processName.equals(mTopComponent.getPackageName())) { 2927 uid = 0; 2928 } 2929 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2930 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2931 uid = 0; 2932 } 2933 } 2934 int debugFlags = 0; 2935 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2936 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2937 // Also turn on CheckJNI for debuggable apps. It's quite 2938 // awkward to turn on otherwise. 2939 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2940 } 2941 // Run the app in safe mode if its manifest requests so or the 2942 // system is booted in safe mode. 2943 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2944 mSafeMode == true) { 2945 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2946 } 2947 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2948 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2949 } 2950 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2951 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2952 } 2953 if ("1".equals(SystemProperties.get("debug.assert"))) { 2954 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2955 } 2956 2957 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2958 if (requiredAbi == null) { 2959 requiredAbi = Build.SUPPORTED_ABIS[0]; 2960 } 2961 2962 String instructionSet = null; 2963 if (app.info.primaryCpuAbi != null) { 2964 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2965 } 2966 2967 // Start the process. It will either succeed and return a result containing 2968 // the PID of the new process, or else throw a RuntimeException. 2969 boolean isActivityProcess = (entryPoint == null); 2970 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2971 checkTime(startTime, "startProcess: asking zygote to start proc"); 2972 Process.ProcessStartResult startResult = Process.start(entryPoint, 2973 app.processName, uid, uid, gids, debugFlags, mountExternal, 2974 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2975 app.info.dataDir, entryPointArgs); 2976 checkTime(startTime, "startProcess: returned from zygote!"); 2977 2978 if (app.isolated) { 2979 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2980 } 2981 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2982 checkTime(startTime, "startProcess: done updating battery stats"); 2983 2984 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2985 UserHandle.getUserId(uid), startResult.pid, uid, 2986 app.processName, hostingType, 2987 hostingNameStr != null ? hostingNameStr : ""); 2988 2989 if (app.persistent) { 2990 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2991 } 2992 2993 checkTime(startTime, "startProcess: building log message"); 2994 StringBuilder buf = mStringBuilder; 2995 buf.setLength(0); 2996 buf.append("Start proc "); 2997 buf.append(app.processName); 2998 if (!isActivityProcess) { 2999 buf.append(" ["); 3000 buf.append(entryPoint); 3001 buf.append("]"); 3002 } 3003 buf.append(" for "); 3004 buf.append(hostingType); 3005 if (hostingNameStr != null) { 3006 buf.append(" "); 3007 buf.append(hostingNameStr); 3008 } 3009 buf.append(": pid="); 3010 buf.append(startResult.pid); 3011 buf.append(" uid="); 3012 buf.append(uid); 3013 buf.append(" gids={"); 3014 if (gids != null) { 3015 for (int gi=0; gi<gids.length; gi++) { 3016 if (gi != 0) buf.append(", "); 3017 buf.append(gids[gi]); 3018 3019 } 3020 } 3021 buf.append("}"); 3022 if (requiredAbi != null) { 3023 buf.append(" abi="); 3024 buf.append(requiredAbi); 3025 } 3026 Slog.i(TAG, buf.toString()); 3027 app.setPid(startResult.pid); 3028 app.usingWrapper = startResult.usingWrapper; 3029 app.removed = false; 3030 app.killed = false; 3031 app.killedByAm = false; 3032 checkTime(startTime, "startProcess: starting to update pids map"); 3033 synchronized (mPidsSelfLocked) { 3034 this.mPidsSelfLocked.put(startResult.pid, app); 3035 if (isActivityProcess) { 3036 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3037 msg.obj = app; 3038 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3039 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3040 } 3041 } 3042 checkTime(startTime, "startProcess: done updating pids map"); 3043 } catch (RuntimeException e) { 3044 // XXX do better error recovery. 3045 app.setPid(0); 3046 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3047 if (app.isolated) { 3048 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3049 } 3050 Slog.e(TAG, "Failure starting process " + app.processName, e); 3051 } 3052 } 3053 3054 void updateUsageStats(ActivityRecord component, boolean resumed) { 3055 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3056 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3057 if (resumed) { 3058 if (mUsageStatsService != null) { 3059 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3060 UsageEvents.Event.MOVE_TO_FOREGROUND); 3061 } 3062 synchronized (stats) { 3063 stats.noteActivityResumedLocked(component.app.uid); 3064 } 3065 } else { 3066 if (mUsageStatsService != null) { 3067 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3068 UsageEvents.Event.MOVE_TO_BACKGROUND); 3069 } 3070 synchronized (stats) { 3071 stats.noteActivityPausedLocked(component.app.uid); 3072 } 3073 } 3074 } 3075 3076 Intent getHomeIntent() { 3077 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3078 intent.setComponent(mTopComponent); 3079 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3080 intent.addCategory(Intent.CATEGORY_HOME); 3081 } 3082 return intent; 3083 } 3084 3085 boolean startHomeActivityLocked(int userId) { 3086 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3087 && mTopAction == null) { 3088 // We are running in factory test mode, but unable to find 3089 // the factory test app, so just sit around displaying the 3090 // error message and don't try to start anything. 3091 return false; 3092 } 3093 Intent intent = getHomeIntent(); 3094 ActivityInfo aInfo = 3095 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3096 if (aInfo != null) { 3097 intent.setComponent(new ComponentName( 3098 aInfo.applicationInfo.packageName, aInfo.name)); 3099 // Don't do this if the home app is currently being 3100 // instrumented. 3101 aInfo = new ActivityInfo(aInfo); 3102 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3103 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3104 aInfo.applicationInfo.uid, true); 3105 if (app == null || app.instrumentationClass == null) { 3106 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3107 mStackSupervisor.startHomeActivity(intent, aInfo); 3108 } 3109 } 3110 3111 return true; 3112 } 3113 3114 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3115 ActivityInfo ai = null; 3116 ComponentName comp = intent.getComponent(); 3117 try { 3118 if (comp != null) { 3119 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3120 } else { 3121 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3122 intent, 3123 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3124 flags, userId); 3125 3126 if (info != null) { 3127 ai = info.activityInfo; 3128 } 3129 } 3130 } catch (RemoteException e) { 3131 // ignore 3132 } 3133 3134 return ai; 3135 } 3136 3137 /** 3138 * Starts the "new version setup screen" if appropriate. 3139 */ 3140 void startSetupActivityLocked() { 3141 // Only do this once per boot. 3142 if (mCheckedForSetup) { 3143 return; 3144 } 3145 3146 // We will show this screen if the current one is a different 3147 // version than the last one shown, and we are not running in 3148 // low-level factory test mode. 3149 final ContentResolver resolver = mContext.getContentResolver(); 3150 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3151 Settings.Global.getInt(resolver, 3152 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3153 mCheckedForSetup = true; 3154 3155 // See if we should be showing the platform update setup UI. 3156 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3157 List<ResolveInfo> ris = mContext.getPackageManager() 3158 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3159 3160 // We don't allow third party apps to replace this. 3161 ResolveInfo ri = null; 3162 for (int i=0; ris != null && i<ris.size(); i++) { 3163 if ((ris.get(i).activityInfo.applicationInfo.flags 3164 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3165 ri = ris.get(i); 3166 break; 3167 } 3168 } 3169 3170 if (ri != null) { 3171 String vers = ri.activityInfo.metaData != null 3172 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3173 : null; 3174 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3175 vers = ri.activityInfo.applicationInfo.metaData.getString( 3176 Intent.METADATA_SETUP_VERSION); 3177 } 3178 String lastVers = Settings.Secure.getString( 3179 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3180 if (vers != null && !vers.equals(lastVers)) { 3181 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3182 intent.setComponent(new ComponentName( 3183 ri.activityInfo.packageName, ri.activityInfo.name)); 3184 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3185 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3186 null); 3187 } 3188 } 3189 } 3190 } 3191 3192 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3193 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3194 } 3195 3196 void enforceNotIsolatedCaller(String caller) { 3197 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3198 throw new SecurityException("Isolated process not allowed to call " + caller); 3199 } 3200 } 3201 3202 void enforceShellRestriction(String restriction, int userHandle) { 3203 if (Binder.getCallingUid() == Process.SHELL_UID) { 3204 if (userHandle < 0 3205 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3206 throw new SecurityException("Shell does not have permission to access user " 3207 + userHandle); 3208 } 3209 } 3210 } 3211 3212 @Override 3213 public int getFrontActivityScreenCompatMode() { 3214 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3215 synchronized (this) { 3216 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3217 } 3218 } 3219 3220 @Override 3221 public void setFrontActivityScreenCompatMode(int mode) { 3222 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3223 "setFrontActivityScreenCompatMode"); 3224 synchronized (this) { 3225 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3226 } 3227 } 3228 3229 @Override 3230 public int getPackageScreenCompatMode(String packageName) { 3231 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3232 synchronized (this) { 3233 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3234 } 3235 } 3236 3237 @Override 3238 public void setPackageScreenCompatMode(String packageName, int mode) { 3239 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3240 "setPackageScreenCompatMode"); 3241 synchronized (this) { 3242 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3243 } 3244 } 3245 3246 @Override 3247 public boolean getPackageAskScreenCompat(String packageName) { 3248 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3249 synchronized (this) { 3250 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3251 } 3252 } 3253 3254 @Override 3255 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3256 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3257 "setPackageAskScreenCompat"); 3258 synchronized (this) { 3259 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3260 } 3261 } 3262 3263 private void dispatchProcessesChanged() { 3264 int N; 3265 synchronized (this) { 3266 N = mPendingProcessChanges.size(); 3267 if (mActiveProcessChanges.length < N) { 3268 mActiveProcessChanges = new ProcessChangeItem[N]; 3269 } 3270 mPendingProcessChanges.toArray(mActiveProcessChanges); 3271 mAvailProcessChanges.addAll(mPendingProcessChanges); 3272 mPendingProcessChanges.clear(); 3273 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3274 } 3275 3276 int i = mProcessObservers.beginBroadcast(); 3277 while (i > 0) { 3278 i--; 3279 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3280 if (observer != null) { 3281 try { 3282 for (int j=0; j<N; j++) { 3283 ProcessChangeItem item = mActiveProcessChanges[j]; 3284 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3286 + item.pid + " uid=" + item.uid + ": " 3287 + item.foregroundActivities); 3288 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3289 item.foregroundActivities); 3290 } 3291 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3292 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3293 + item.pid + " uid=" + item.uid + ": " + item.processState); 3294 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3295 } 3296 } 3297 } catch (RemoteException e) { 3298 } 3299 } 3300 } 3301 mProcessObservers.finishBroadcast(); 3302 } 3303 3304 private void dispatchProcessDied(int pid, int uid) { 3305 int i = mProcessObservers.beginBroadcast(); 3306 while (i > 0) { 3307 i--; 3308 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3309 if (observer != null) { 3310 try { 3311 observer.onProcessDied(pid, uid); 3312 } catch (RemoteException e) { 3313 } 3314 } 3315 } 3316 mProcessObservers.finishBroadcast(); 3317 } 3318 3319 @Override 3320 public final int startActivity(IApplicationThread caller, String callingPackage, 3321 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3322 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3323 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3324 resultWho, requestCode, startFlags, profilerInfo, options, 3325 UserHandle.getCallingUserId()); 3326 } 3327 3328 @Override 3329 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3330 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3331 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3332 enforceNotIsolatedCaller("startActivity"); 3333 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3334 false, ALLOW_FULL_ONLY, "startActivity", null); 3335 // TODO: Switch to user app stacks here. 3336 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3337 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3338 profilerInfo, null, null, options, userId, null, null); 3339 } 3340 3341 @Override 3342 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3343 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3344 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3345 3346 // This is very dangerous -- it allows you to perform a start activity (including 3347 // permission grants) as any app that may launch one of your own activities. So 3348 // we will only allow this to be done from activities that are part of the core framework, 3349 // and then only when they are running as the system. 3350 final ActivityRecord sourceRecord; 3351 final int targetUid; 3352 final String targetPackage; 3353 synchronized (this) { 3354 if (resultTo == null) { 3355 throw new SecurityException("Must be called from an activity"); 3356 } 3357 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3358 if (sourceRecord == null) { 3359 throw new SecurityException("Called with bad activity token: " + resultTo); 3360 } 3361 if (!sourceRecord.info.packageName.equals("android")) { 3362 throw new SecurityException( 3363 "Must be called from an activity that is declared in the android package"); 3364 } 3365 if (sourceRecord.app == null) { 3366 throw new SecurityException("Called without a process attached to activity"); 3367 } 3368 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3369 // This is still okay, as long as this activity is running under the 3370 // uid of the original calling activity. 3371 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3372 throw new SecurityException( 3373 "Calling activity in uid " + sourceRecord.app.uid 3374 + " must be system uid or original calling uid " 3375 + sourceRecord.launchedFromUid); 3376 } 3377 } 3378 targetUid = sourceRecord.launchedFromUid; 3379 targetPackage = sourceRecord.launchedFromPackage; 3380 } 3381 3382 if (userId == UserHandle.USER_NULL) { 3383 userId = UserHandle.getUserId(sourceRecord.app.uid); 3384 } 3385 3386 // TODO: Switch to user app stacks here. 3387 try { 3388 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3389 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3390 null, null, options, userId, null, null); 3391 return ret; 3392 } catch (SecurityException e) { 3393 // XXX need to figure out how to propagate to original app. 3394 // A SecurityException here is generally actually a fault of the original 3395 // calling activity (such as a fairly granting permissions), so propagate it 3396 // back to them. 3397 /* 3398 StringBuilder msg = new StringBuilder(); 3399 msg.append("While launching"); 3400 msg.append(intent.toString()); 3401 msg.append(": "); 3402 msg.append(e.getMessage()); 3403 */ 3404 throw e; 3405 } 3406 } 3407 3408 @Override 3409 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3410 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3411 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3412 enforceNotIsolatedCaller("startActivityAndWait"); 3413 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3414 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3415 WaitResult res = new WaitResult(); 3416 // TODO: Switch to user app stacks here. 3417 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3418 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3419 options, userId, null, null); 3420 return res; 3421 } 3422 3423 @Override 3424 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3425 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3426 int startFlags, Configuration config, Bundle options, int userId) { 3427 enforceNotIsolatedCaller("startActivityWithConfig"); 3428 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3429 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3430 // TODO: Switch to user app stacks here. 3431 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3432 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3433 null, null, config, options, userId, null, null); 3434 return ret; 3435 } 3436 3437 @Override 3438 public int startActivityIntentSender(IApplicationThread caller, 3439 IntentSender intent, Intent fillInIntent, String resolvedType, 3440 IBinder resultTo, String resultWho, int requestCode, 3441 int flagsMask, int flagsValues, Bundle options) { 3442 enforceNotIsolatedCaller("startActivityIntentSender"); 3443 // Refuse possible leaked file descriptors 3444 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3445 throw new IllegalArgumentException("File descriptors passed in Intent"); 3446 } 3447 3448 IIntentSender sender = intent.getTarget(); 3449 if (!(sender instanceof PendingIntentRecord)) { 3450 throw new IllegalArgumentException("Bad PendingIntent object"); 3451 } 3452 3453 PendingIntentRecord pir = (PendingIntentRecord)sender; 3454 3455 synchronized (this) { 3456 // If this is coming from the currently resumed activity, it is 3457 // effectively saying that app switches are allowed at this point. 3458 final ActivityStack stack = getFocusedStack(); 3459 if (stack.mResumedActivity != null && 3460 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3461 mAppSwitchesAllowedTime = 0; 3462 } 3463 } 3464 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3465 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3466 return ret; 3467 } 3468 3469 @Override 3470 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3471 Intent intent, String resolvedType, IVoiceInteractionSession session, 3472 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3473 Bundle options, int userId) { 3474 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3475 != PackageManager.PERMISSION_GRANTED) { 3476 String msg = "Permission Denial: startVoiceActivity() from pid=" 3477 + Binder.getCallingPid() 3478 + ", uid=" + Binder.getCallingUid() 3479 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3480 Slog.w(TAG, msg); 3481 throw new SecurityException(msg); 3482 } 3483 if (session == null || interactor == null) { 3484 throw new NullPointerException("null session or interactor"); 3485 } 3486 userId = handleIncomingUser(callingPid, callingUid, userId, 3487 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3488 // TODO: Switch to user app stacks here. 3489 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3490 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3491 null, options, userId, null, null); 3492 } 3493 3494 @Override 3495 public boolean startNextMatchingActivity(IBinder callingActivity, 3496 Intent intent, Bundle options) { 3497 // Refuse possible leaked file descriptors 3498 if (intent != null && intent.hasFileDescriptors() == true) { 3499 throw new IllegalArgumentException("File descriptors passed in Intent"); 3500 } 3501 3502 synchronized (this) { 3503 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3504 if (r == null) { 3505 ActivityOptions.abort(options); 3506 return false; 3507 } 3508 if (r.app == null || r.app.thread == null) { 3509 // The caller is not running... d'oh! 3510 ActivityOptions.abort(options); 3511 return false; 3512 } 3513 intent = new Intent(intent); 3514 // The caller is not allowed to change the data. 3515 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3516 // And we are resetting to find the next component... 3517 intent.setComponent(null); 3518 3519 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3520 3521 ActivityInfo aInfo = null; 3522 try { 3523 List<ResolveInfo> resolves = 3524 AppGlobals.getPackageManager().queryIntentActivities( 3525 intent, r.resolvedType, 3526 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3527 UserHandle.getCallingUserId()); 3528 3529 // Look for the original activity in the list... 3530 final int N = resolves != null ? resolves.size() : 0; 3531 for (int i=0; i<N; i++) { 3532 ResolveInfo rInfo = resolves.get(i); 3533 if (rInfo.activityInfo.packageName.equals(r.packageName) 3534 && rInfo.activityInfo.name.equals(r.info.name)) { 3535 // We found the current one... the next matching is 3536 // after it. 3537 i++; 3538 if (i<N) { 3539 aInfo = resolves.get(i).activityInfo; 3540 } 3541 if (debug) { 3542 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3543 + "/" + r.info.name); 3544 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3545 + "/" + aInfo.name); 3546 } 3547 break; 3548 } 3549 } 3550 } catch (RemoteException e) { 3551 } 3552 3553 if (aInfo == null) { 3554 // Nobody who is next! 3555 ActivityOptions.abort(options); 3556 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3557 return false; 3558 } 3559 3560 intent.setComponent(new ComponentName( 3561 aInfo.applicationInfo.packageName, aInfo.name)); 3562 intent.setFlags(intent.getFlags()&~( 3563 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3564 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3565 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3566 Intent.FLAG_ACTIVITY_NEW_TASK)); 3567 3568 // Okay now we need to start the new activity, replacing the 3569 // currently running activity. This is a little tricky because 3570 // we want to start the new one as if the current one is finished, 3571 // but not finish the current one first so that there is no flicker. 3572 // And thus... 3573 final boolean wasFinishing = r.finishing; 3574 r.finishing = true; 3575 3576 // Propagate reply information over to the new activity. 3577 final ActivityRecord resultTo = r.resultTo; 3578 final String resultWho = r.resultWho; 3579 final int requestCode = r.requestCode; 3580 r.resultTo = null; 3581 if (resultTo != null) { 3582 resultTo.removeResultsLocked(r, resultWho, requestCode); 3583 } 3584 3585 final long origId = Binder.clearCallingIdentity(); 3586 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3587 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3588 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3589 -1, r.launchedFromUid, 0, options, false, null, null, null); 3590 Binder.restoreCallingIdentity(origId); 3591 3592 r.finishing = wasFinishing; 3593 if (res != ActivityManager.START_SUCCESS) { 3594 return false; 3595 } 3596 return true; 3597 } 3598 } 3599 3600 @Override 3601 public final int startActivityFromRecents(int taskId, Bundle options) { 3602 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3603 String msg = "Permission Denial: startActivityFromRecents called without " + 3604 START_TASKS_FROM_RECENTS; 3605 Slog.w(TAG, msg); 3606 throw new SecurityException(msg); 3607 } 3608 return startActivityFromRecentsInner(taskId, options); 3609 } 3610 3611 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3612 final TaskRecord task; 3613 final int callingUid; 3614 final String callingPackage; 3615 final Intent intent; 3616 final int userId; 3617 synchronized (this) { 3618 task = recentTaskForIdLocked(taskId); 3619 if (task == null) { 3620 throw new IllegalArgumentException("Task " + taskId + " not found."); 3621 } 3622 if (task.getRootActivity() != null) { 3623 moveTaskToFrontLocked(task.taskId, 0, null); 3624 return ActivityManager.START_TASK_TO_FRONT; 3625 } 3626 callingUid = task.mCallingUid; 3627 callingPackage = task.mCallingPackage; 3628 intent = task.intent; 3629 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3630 userId = task.userId; 3631 } 3632 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3633 options, userId, null, task); 3634 } 3635 3636 final int startActivityInPackage(int uid, String callingPackage, 3637 Intent intent, String resolvedType, IBinder resultTo, 3638 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3639 IActivityContainer container, TaskRecord inTask) { 3640 3641 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3642 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3643 3644 // TODO: Switch to user app stacks here. 3645 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3646 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3647 null, null, null, options, userId, container, inTask); 3648 return ret; 3649 } 3650 3651 @Override 3652 public final int startActivities(IApplicationThread caller, String callingPackage, 3653 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3654 int userId) { 3655 enforceNotIsolatedCaller("startActivities"); 3656 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3657 false, ALLOW_FULL_ONLY, "startActivity", null); 3658 // TODO: Switch to user app stacks here. 3659 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3660 resolvedTypes, resultTo, options, userId); 3661 return ret; 3662 } 3663 3664 final int startActivitiesInPackage(int uid, String callingPackage, 3665 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3666 Bundle options, int userId) { 3667 3668 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3669 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3670 // TODO: Switch to user app stacks here. 3671 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3672 resultTo, options, userId); 3673 return ret; 3674 } 3675 3676 //explicitly remove thd old information in mRecentTasks when removing existing user. 3677 private void removeRecentTasksForUserLocked(int userId) { 3678 if(userId <= 0) { 3679 Slog.i(TAG, "Can't remove recent task on user " + userId); 3680 return; 3681 } 3682 3683 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3684 TaskRecord tr = mRecentTasks.get(i); 3685 if (tr.userId == userId) { 3686 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3687 + " when finishing user" + userId); 3688 mRecentTasks.remove(i); 3689 tr.removedFromRecents(); 3690 } 3691 } 3692 3693 // Remove tasks from persistent storage. 3694 notifyTaskPersisterLocked(null, true); 3695 } 3696 3697 // Sort by taskId 3698 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3699 @Override 3700 public int compare(TaskRecord lhs, TaskRecord rhs) { 3701 return rhs.taskId - lhs.taskId; 3702 } 3703 }; 3704 3705 // Extract the affiliates of the chain containing mRecentTasks[start]. 3706 private int processNextAffiliateChainLocked(int start) { 3707 final TaskRecord startTask = mRecentTasks.get(start); 3708 final int affiliateId = startTask.mAffiliatedTaskId; 3709 3710 // Quick identification of isolated tasks. I.e. those not launched behind. 3711 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3712 startTask.mNextAffiliate == null) { 3713 // There is still a slim chance that there are other tasks that point to this task 3714 // and that the chain is so messed up that this task no longer points to them but 3715 // the gain of this optimization outweighs the risk. 3716 startTask.inRecents = true; 3717 return start + 1; 3718 } 3719 3720 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3721 mTmpRecents.clear(); 3722 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3723 final TaskRecord task = mRecentTasks.get(i); 3724 if (task.mAffiliatedTaskId == affiliateId) { 3725 mRecentTasks.remove(i); 3726 mTmpRecents.add(task); 3727 } 3728 } 3729 3730 // Sort them all by taskId. That is the order they were create in and that order will 3731 // always be correct. 3732 Collections.sort(mTmpRecents, mTaskRecordComparator); 3733 3734 // Go through and fix up the linked list. 3735 // The first one is the end of the chain and has no next. 3736 final TaskRecord first = mTmpRecents.get(0); 3737 first.inRecents = true; 3738 if (first.mNextAffiliate != null) { 3739 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3740 first.setNextAffiliate(null); 3741 notifyTaskPersisterLocked(first, false); 3742 } 3743 // Everything in the middle is doubly linked from next to prev. 3744 final int tmpSize = mTmpRecents.size(); 3745 for (int i = 0; i < tmpSize - 1; ++i) { 3746 final TaskRecord next = mTmpRecents.get(i); 3747 final TaskRecord prev = mTmpRecents.get(i + 1); 3748 if (next.mPrevAffiliate != prev) { 3749 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3750 " setting prev=" + prev); 3751 next.setPrevAffiliate(prev); 3752 notifyTaskPersisterLocked(next, false); 3753 } 3754 if (prev.mNextAffiliate != next) { 3755 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3756 " setting next=" + next); 3757 prev.setNextAffiliate(next); 3758 notifyTaskPersisterLocked(prev, false); 3759 } 3760 prev.inRecents = true; 3761 } 3762 // The last one is the beginning of the list and has no prev. 3763 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3764 if (last.mPrevAffiliate != null) { 3765 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3766 last.setPrevAffiliate(null); 3767 notifyTaskPersisterLocked(last, false); 3768 } 3769 3770 // Insert the group back into mRecentTasks at start. 3771 mRecentTasks.addAll(start, mTmpRecents); 3772 3773 // Let the caller know where we left off. 3774 return start + tmpSize; 3775 } 3776 3777 /** 3778 * Update the recent tasks lists: make sure tasks should still be here (their 3779 * applications / activities still exist), update their availability, fixup ordering 3780 * of affiliations. 3781 */ 3782 void cleanupRecentTasksLocked(int userId) { 3783 if (mRecentTasks == null) { 3784 // Happens when called from the packagemanager broadcast before boot. 3785 return; 3786 } 3787 3788 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3789 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3790 final IPackageManager pm = AppGlobals.getPackageManager(); 3791 final ActivityInfo dummyAct = new ActivityInfo(); 3792 final ApplicationInfo dummyApp = new ApplicationInfo(); 3793 3794 int N = mRecentTasks.size(); 3795 3796 int[] users = userId == UserHandle.USER_ALL 3797 ? getUsersLocked() : new int[] { userId }; 3798 for (int user : users) { 3799 for (int i = 0; i < N; i++) { 3800 TaskRecord task = mRecentTasks.get(i); 3801 if (task.userId != user) { 3802 // Only look at tasks for the user ID of interest. 3803 continue; 3804 } 3805 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3806 // This situation is broken, and we should just get rid of it now. 3807 mRecentTasks.remove(i); 3808 task.removedFromRecents(); 3809 i--; 3810 N--; 3811 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3812 continue; 3813 } 3814 // Check whether this activity is currently available. 3815 if (task.realActivity != null) { 3816 ActivityInfo ai = availActCache.get(task.realActivity); 3817 if (ai == null) { 3818 try { 3819 ai = pm.getActivityInfo(task.realActivity, 3820 PackageManager.GET_UNINSTALLED_PACKAGES 3821 | PackageManager.GET_DISABLED_COMPONENTS, user); 3822 } catch (RemoteException e) { 3823 // Will never happen. 3824 continue; 3825 } 3826 if (ai == null) { 3827 ai = dummyAct; 3828 } 3829 availActCache.put(task.realActivity, ai); 3830 } 3831 if (ai == dummyAct) { 3832 // This could be either because the activity no longer exists, or the 3833 // app is temporarily gone. For the former we want to remove the recents 3834 // entry; for the latter we want to mark it as unavailable. 3835 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3836 if (app == null) { 3837 try { 3838 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3839 PackageManager.GET_UNINSTALLED_PACKAGES 3840 | PackageManager.GET_DISABLED_COMPONENTS, user); 3841 } catch (RemoteException e) { 3842 // Will never happen. 3843 continue; 3844 } 3845 if (app == null) { 3846 app = dummyApp; 3847 } 3848 availAppCache.put(task.realActivity.getPackageName(), app); 3849 } 3850 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3851 // Doesn't exist any more! Good-bye. 3852 mRecentTasks.remove(i); 3853 task.removedFromRecents(); 3854 i--; 3855 N--; 3856 Slog.w(TAG, "Removing no longer valid recent: " + task); 3857 continue; 3858 } else { 3859 // Otherwise just not available for now. 3860 if (task.isAvailable) { 3861 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3862 + task); 3863 } 3864 task.isAvailable = false; 3865 } 3866 } else { 3867 if (!ai.enabled || !ai.applicationInfo.enabled 3868 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3869 if (task.isAvailable) { 3870 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3871 + task + " (enabled=" + ai.enabled + "/" 3872 + ai.applicationInfo.enabled + " flags=" 3873 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3874 } 3875 task.isAvailable = false; 3876 } else { 3877 if (!task.isAvailable) { 3878 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3879 + task); 3880 } 3881 task.isAvailable = true; 3882 } 3883 } 3884 } 3885 } 3886 } 3887 3888 // Verify the affiliate chain for each task. 3889 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3890 } 3891 3892 mTmpRecents.clear(); 3893 // mRecentTasks is now in sorted, affiliated order. 3894 } 3895 3896 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3897 int N = mRecentTasks.size(); 3898 TaskRecord top = task; 3899 int topIndex = taskIndex; 3900 while (top.mNextAffiliate != null && topIndex > 0) { 3901 top = top.mNextAffiliate; 3902 topIndex--; 3903 } 3904 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3905 + topIndex + " from intial " + taskIndex); 3906 // Find the end of the chain, doing a sanity check along the way. 3907 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3908 int endIndex = topIndex; 3909 TaskRecord prev = top; 3910 while (endIndex < N) { 3911 TaskRecord cur = mRecentTasks.get(endIndex); 3912 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3913 + endIndex + " " + cur); 3914 if (cur == top) { 3915 // Verify start of the chain. 3916 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3917 Slog.wtf(TAG, "Bad chain @" + endIndex 3918 + ": first task has next affiliate: " + prev); 3919 sane = false; 3920 break; 3921 } 3922 } else { 3923 // Verify middle of the chain's next points back to the one before. 3924 if (cur.mNextAffiliate != prev 3925 || cur.mNextAffiliateTaskId != prev.taskId) { 3926 Slog.wtf(TAG, "Bad chain @" + endIndex 3927 + ": middle task " + cur + " @" + endIndex 3928 + " has bad next affiliate " 3929 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3930 + ", expected " + prev); 3931 sane = false; 3932 break; 3933 } 3934 } 3935 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3936 // Chain ends here. 3937 if (cur.mPrevAffiliate != null) { 3938 Slog.wtf(TAG, "Bad chain @" + endIndex 3939 + ": last task " + cur + " has previous affiliate " 3940 + cur.mPrevAffiliate); 3941 sane = false; 3942 } 3943 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3944 break; 3945 } else { 3946 // Verify middle of the chain's prev points to a valid item. 3947 if (cur.mPrevAffiliate == null) { 3948 Slog.wtf(TAG, "Bad chain @" + endIndex 3949 + ": task " + cur + " has previous affiliate " 3950 + cur.mPrevAffiliate + " but should be id " 3951 + cur.mPrevAffiliate); 3952 sane = false; 3953 break; 3954 } 3955 } 3956 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3957 Slog.wtf(TAG, "Bad chain @" + endIndex 3958 + ": task " + cur + " has affiliated id " 3959 + cur.mAffiliatedTaskId + " but should be " 3960 + task.mAffiliatedTaskId); 3961 sane = false; 3962 break; 3963 } 3964 prev = cur; 3965 endIndex++; 3966 if (endIndex >= N) { 3967 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3968 + ": last task " + prev); 3969 sane = false; 3970 break; 3971 } 3972 } 3973 if (sane) { 3974 if (endIndex < taskIndex) { 3975 Slog.wtf(TAG, "Bad chain @" + endIndex 3976 + ": did not extend to task " + task + " @" + taskIndex); 3977 sane = false; 3978 } 3979 } 3980 if (sane) { 3981 // All looks good, we can just move all of the affiliated tasks 3982 // to the top. 3983 for (int i=topIndex; i<=endIndex; i++) { 3984 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3985 + " from " + i + " to " + (i-topIndex)); 3986 TaskRecord cur = mRecentTasks.remove(i); 3987 mRecentTasks.add(i-topIndex, cur); 3988 } 3989 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3990 + " to " + endIndex); 3991 return true; 3992 } 3993 3994 // Whoops, couldn't do it. 3995 return false; 3996 } 3997 3998 final void addRecentTaskLocked(TaskRecord task) { 3999 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4000 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4001 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4002 4003 int N = mRecentTasks.size(); 4004 // Quick case: check if the top-most recent task is the same. 4005 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4006 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4007 return; 4008 } 4009 // Another quick case: check if this is part of a set of affiliated 4010 // tasks that are at the top. 4011 if (isAffiliated && N > 0 && task.inRecents 4012 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4013 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4014 + " at top when adding " + task); 4015 return; 4016 } 4017 // Another quick case: never add voice sessions. 4018 if (task.voiceSession != null) { 4019 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4020 return; 4021 } 4022 4023 boolean needAffiliationFix = false; 4024 4025 // Slightly less quick case: the task is already in recents, so all we need 4026 // to do is move it. 4027 if (task.inRecents) { 4028 int taskIndex = mRecentTasks.indexOf(task); 4029 if (taskIndex >= 0) { 4030 if (!isAffiliated) { 4031 // Simple case: this is not an affiliated task, so we just move it to the front. 4032 mRecentTasks.remove(taskIndex); 4033 mRecentTasks.add(0, task); 4034 notifyTaskPersisterLocked(task, false); 4035 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4036 + " from " + taskIndex); 4037 return; 4038 } else { 4039 // More complicated: need to keep all affiliated tasks together. 4040 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4041 // All went well. 4042 return; 4043 } 4044 4045 // Uh oh... something bad in the affiliation chain, try to rebuild 4046 // everything and then go through our general path of adding a new task. 4047 needAffiliationFix = true; 4048 } 4049 } else { 4050 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4051 needAffiliationFix = true; 4052 } 4053 } 4054 4055 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4056 trimRecentsForTaskLocked(task, true); 4057 4058 N = mRecentTasks.size(); 4059 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4060 final TaskRecord tr = mRecentTasks.remove(N - 1); 4061 tr.removedFromRecents(); 4062 N--; 4063 } 4064 task.inRecents = true; 4065 if (!isAffiliated || needAffiliationFix) { 4066 // If this is a simple non-affiliated task, or we had some failure trying to 4067 // handle it as part of an affilated task, then just place it at the top. 4068 mRecentTasks.add(0, task); 4069 } else if (isAffiliated) { 4070 // If this is a new affiliated task, then move all of the affiliated tasks 4071 // to the front and insert this new one. 4072 TaskRecord other = task.mNextAffiliate; 4073 if (other == null) { 4074 other = task.mPrevAffiliate; 4075 } 4076 if (other != null) { 4077 int otherIndex = mRecentTasks.indexOf(other); 4078 if (otherIndex >= 0) { 4079 // Insert new task at appropriate location. 4080 int taskIndex; 4081 if (other == task.mNextAffiliate) { 4082 // We found the index of our next affiliation, which is who is 4083 // before us in the list, so add after that point. 4084 taskIndex = otherIndex+1; 4085 } else { 4086 // We found the index of our previous affiliation, which is who is 4087 // after us in the list, so add at their position. 4088 taskIndex = otherIndex; 4089 } 4090 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4091 + taskIndex + ": " + task); 4092 mRecentTasks.add(taskIndex, task); 4093 4094 // Now move everything to the front. 4095 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4096 // All went well. 4097 return; 4098 } 4099 4100 // Uh oh... something bad in the affiliation chain, try to rebuild 4101 // everything and then go through our general path of adding a new task. 4102 needAffiliationFix = true; 4103 } else { 4104 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4105 + other); 4106 needAffiliationFix = true; 4107 } 4108 } else { 4109 if (DEBUG_RECENTS) Slog.d(TAG, 4110 "addRecent: adding affiliated task without next/prev:" + task); 4111 needAffiliationFix = true; 4112 } 4113 } 4114 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4115 4116 if (needAffiliationFix) { 4117 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4118 cleanupRecentTasksLocked(task.userId); 4119 } 4120 } 4121 4122 /** 4123 * If needed, remove oldest existing entries in recents that are for the same kind 4124 * of task as the given one. 4125 */ 4126 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4127 int N = mRecentTasks.size(); 4128 final Intent intent = task.intent; 4129 final boolean document = intent != null && intent.isDocument(); 4130 4131 int maxRecents = task.maxRecents - 1; 4132 for (int i=0; i<N; i++) { 4133 final TaskRecord tr = mRecentTasks.get(i); 4134 if (task != tr) { 4135 if (task.userId != tr.userId) { 4136 continue; 4137 } 4138 if (i > MAX_RECENT_BITMAPS) { 4139 tr.freeLastThumbnail(); 4140 } 4141 final Intent trIntent = tr.intent; 4142 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4143 (intent == null || !intent.filterEquals(trIntent))) { 4144 continue; 4145 } 4146 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4147 if (document && trIsDocument) { 4148 // These are the same document activity (not necessarily the same doc). 4149 if (maxRecents > 0) { 4150 --maxRecents; 4151 continue; 4152 } 4153 // Hit the maximum number of documents for this task. Fall through 4154 // and remove this document from recents. 4155 } else if (document || trIsDocument) { 4156 // Only one of these is a document. Not the droid we're looking for. 4157 continue; 4158 } 4159 } 4160 4161 if (!doTrim) { 4162 // If the caller is not actually asking for a trim, just tell them we reached 4163 // a point where the trim would happen. 4164 return i; 4165 } 4166 4167 // Either task and tr are the same or, their affinities match or their intents match 4168 // and neither of them is a document, or they are documents using the same activity 4169 // and their maxRecents has been reached. 4170 tr.disposeThumbnail(); 4171 mRecentTasks.remove(i); 4172 if (task != tr) { 4173 tr.removedFromRecents(); 4174 } 4175 i--; 4176 N--; 4177 if (task.intent == null) { 4178 // If the new recent task we are adding is not fully 4179 // specified, then replace it with the existing recent task. 4180 task = tr; 4181 } 4182 notifyTaskPersisterLocked(tr, false); 4183 } 4184 4185 return -1; 4186 } 4187 4188 @Override 4189 public void reportActivityFullyDrawn(IBinder token) { 4190 synchronized (this) { 4191 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4192 if (r == null) { 4193 return; 4194 } 4195 r.reportFullyDrawnLocked(); 4196 } 4197 } 4198 4199 @Override 4200 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4201 synchronized (this) { 4202 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4203 if (r == null) { 4204 return; 4205 } 4206 final long origId = Binder.clearCallingIdentity(); 4207 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4208 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4209 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4210 if (config != null) { 4211 r.frozenBeforeDestroy = true; 4212 if (!updateConfigurationLocked(config, r, false, false)) { 4213 mStackSupervisor.resumeTopActivitiesLocked(); 4214 } 4215 } 4216 Binder.restoreCallingIdentity(origId); 4217 } 4218 } 4219 4220 @Override 4221 public int getRequestedOrientation(IBinder token) { 4222 synchronized (this) { 4223 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4224 if (r == null) { 4225 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4226 } 4227 return mWindowManager.getAppOrientation(r.appToken); 4228 } 4229 } 4230 4231 /** 4232 * This is the internal entry point for handling Activity.finish(). 4233 * 4234 * @param token The Binder token referencing the Activity we want to finish. 4235 * @param resultCode Result code, if any, from this Activity. 4236 * @param resultData Result data (Intent), if any, from this Activity. 4237 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4238 * the root Activity in the task. 4239 * 4240 * @return Returns true if the activity successfully finished, or false if it is still running. 4241 */ 4242 @Override 4243 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4244 boolean finishTask) { 4245 // Refuse possible leaked file descriptors 4246 if (resultData != null && resultData.hasFileDescriptors() == true) { 4247 throw new IllegalArgumentException("File descriptors passed in Intent"); 4248 } 4249 4250 synchronized(this) { 4251 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4252 if (r == null) { 4253 return true; 4254 } 4255 // Keep track of the root activity of the task before we finish it 4256 TaskRecord tr = r.task; 4257 ActivityRecord rootR = tr.getRootActivity(); 4258 if (rootR == null) { 4259 Slog.w(TAG, "Finishing task with all activities already finished"); 4260 } 4261 // Do not allow task to finish in Lock Task mode. 4262 if (tr == mStackSupervisor.mLockTaskModeTask) { 4263 if (rootR == r) { 4264 Slog.i(TAG, "Not finishing task in lock task mode"); 4265 mStackSupervisor.showLockTaskToast(); 4266 return false; 4267 } 4268 } 4269 if (mController != null) { 4270 // Find the first activity that is not finishing. 4271 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4272 if (next != null) { 4273 // ask watcher if this is allowed 4274 boolean resumeOK = true; 4275 try { 4276 resumeOK = mController.activityResuming(next.packageName); 4277 } catch (RemoteException e) { 4278 mController = null; 4279 Watchdog.getInstance().setActivityController(null); 4280 } 4281 4282 if (!resumeOK) { 4283 Slog.i(TAG, "Not finishing activity because controller resumed"); 4284 return false; 4285 } 4286 } 4287 } 4288 final long origId = Binder.clearCallingIdentity(); 4289 try { 4290 boolean res; 4291 if (finishTask && r == rootR) { 4292 // If requested, remove the task that is associated to this activity only if it 4293 // was the root activity in the task. The result code and data is ignored 4294 // because we don't support returning them across task boundaries. 4295 res = removeTaskByIdLocked(tr.taskId, false); 4296 if (!res) { 4297 Slog.i(TAG, "Removing task failed to finish activity"); 4298 } 4299 } else { 4300 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4301 resultData, "app-request", true); 4302 if (!res) { 4303 Slog.i(TAG, "Failed to finish by app-request"); 4304 } 4305 } 4306 return res; 4307 } finally { 4308 Binder.restoreCallingIdentity(origId); 4309 } 4310 } 4311 } 4312 4313 @Override 4314 public final void finishHeavyWeightApp() { 4315 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4316 != PackageManager.PERMISSION_GRANTED) { 4317 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4318 + Binder.getCallingPid() 4319 + ", uid=" + Binder.getCallingUid() 4320 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4321 Slog.w(TAG, msg); 4322 throw new SecurityException(msg); 4323 } 4324 4325 synchronized(this) { 4326 if (mHeavyWeightProcess == null) { 4327 return; 4328 } 4329 4330 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4331 mHeavyWeightProcess.activities); 4332 for (int i=0; i<activities.size(); i++) { 4333 ActivityRecord r = activities.get(i); 4334 if (!r.finishing) { 4335 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4336 null, "finish-heavy", true); 4337 } 4338 } 4339 4340 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4341 mHeavyWeightProcess.userId, 0)); 4342 mHeavyWeightProcess = null; 4343 } 4344 } 4345 4346 @Override 4347 public void crashApplication(int uid, int initialPid, String packageName, 4348 String message) { 4349 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4350 != PackageManager.PERMISSION_GRANTED) { 4351 String msg = "Permission Denial: crashApplication() from pid=" 4352 + Binder.getCallingPid() 4353 + ", uid=" + Binder.getCallingUid() 4354 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4355 Slog.w(TAG, msg); 4356 throw new SecurityException(msg); 4357 } 4358 4359 synchronized(this) { 4360 ProcessRecord proc = null; 4361 4362 // Figure out which process to kill. We don't trust that initialPid 4363 // still has any relation to current pids, so must scan through the 4364 // list. 4365 synchronized (mPidsSelfLocked) { 4366 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4367 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4368 if (p.uid != uid) { 4369 continue; 4370 } 4371 if (p.pid == initialPid) { 4372 proc = p; 4373 break; 4374 } 4375 if (p.pkgList.containsKey(packageName)) { 4376 proc = p; 4377 } 4378 } 4379 } 4380 4381 if (proc == null) { 4382 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4383 + " initialPid=" + initialPid 4384 + " packageName=" + packageName); 4385 return; 4386 } 4387 4388 if (proc.thread != null) { 4389 if (proc.pid == Process.myPid()) { 4390 Log.w(TAG, "crashApplication: trying to crash self!"); 4391 return; 4392 } 4393 long ident = Binder.clearCallingIdentity(); 4394 try { 4395 proc.thread.scheduleCrash(message); 4396 } catch (RemoteException e) { 4397 } 4398 Binder.restoreCallingIdentity(ident); 4399 } 4400 } 4401 } 4402 4403 @Override 4404 public final void finishSubActivity(IBinder token, String resultWho, 4405 int requestCode) { 4406 synchronized(this) { 4407 final long origId = Binder.clearCallingIdentity(); 4408 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4409 if (r != null) { 4410 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4411 } 4412 Binder.restoreCallingIdentity(origId); 4413 } 4414 } 4415 4416 @Override 4417 public boolean finishActivityAffinity(IBinder token) { 4418 synchronized(this) { 4419 final long origId = Binder.clearCallingIdentity(); 4420 try { 4421 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4422 4423 ActivityRecord rootR = r.task.getRootActivity(); 4424 // Do not allow task to finish in Lock Task mode. 4425 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4426 if (rootR == r) { 4427 mStackSupervisor.showLockTaskToast(); 4428 return false; 4429 } 4430 } 4431 boolean res = false; 4432 if (r != null) { 4433 res = r.task.stack.finishActivityAffinityLocked(r); 4434 } 4435 return res; 4436 } finally { 4437 Binder.restoreCallingIdentity(origId); 4438 } 4439 } 4440 } 4441 4442 @Override 4443 public void finishVoiceTask(IVoiceInteractionSession session) { 4444 synchronized(this) { 4445 final long origId = Binder.clearCallingIdentity(); 4446 try { 4447 mStackSupervisor.finishVoiceTask(session); 4448 } finally { 4449 Binder.restoreCallingIdentity(origId); 4450 } 4451 } 4452 4453 } 4454 4455 @Override 4456 public boolean releaseActivityInstance(IBinder token) { 4457 synchronized(this) { 4458 final long origId = Binder.clearCallingIdentity(); 4459 try { 4460 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4461 if (r.task == null || r.task.stack == null) { 4462 return false; 4463 } 4464 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4465 } finally { 4466 Binder.restoreCallingIdentity(origId); 4467 } 4468 } 4469 } 4470 4471 @Override 4472 public void releaseSomeActivities(IApplicationThread appInt) { 4473 synchronized(this) { 4474 final long origId = Binder.clearCallingIdentity(); 4475 try { 4476 ProcessRecord app = getRecordForAppLocked(appInt); 4477 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4478 } finally { 4479 Binder.restoreCallingIdentity(origId); 4480 } 4481 } 4482 } 4483 4484 @Override 4485 public boolean willActivityBeVisible(IBinder token) { 4486 synchronized(this) { 4487 ActivityStack stack = ActivityRecord.getStackLocked(token); 4488 if (stack != null) { 4489 return stack.willActivityBeVisibleLocked(token); 4490 } 4491 return false; 4492 } 4493 } 4494 4495 @Override 4496 public void overridePendingTransition(IBinder token, String packageName, 4497 int enterAnim, int exitAnim) { 4498 synchronized(this) { 4499 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4500 if (self == null) { 4501 return; 4502 } 4503 4504 final long origId = Binder.clearCallingIdentity(); 4505 4506 if (self.state == ActivityState.RESUMED 4507 || self.state == ActivityState.PAUSING) { 4508 mWindowManager.overridePendingAppTransition(packageName, 4509 enterAnim, exitAnim, null); 4510 } 4511 4512 Binder.restoreCallingIdentity(origId); 4513 } 4514 } 4515 4516 /** 4517 * Main function for removing an existing process from the activity manager 4518 * as a result of that process going away. Clears out all connections 4519 * to the process. 4520 */ 4521 private final void handleAppDiedLocked(ProcessRecord app, 4522 boolean restarting, boolean allowRestart) { 4523 int pid = app.pid; 4524 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4525 if (!kept && !restarting) { 4526 removeLruProcessLocked(app); 4527 if (pid > 0) { 4528 ProcessList.remove(pid); 4529 } 4530 } 4531 4532 if (mProfileProc == app) { 4533 clearProfilerLocked(); 4534 } 4535 4536 // Remove this application's activities from active lists. 4537 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4538 4539 app.activities.clear(); 4540 4541 if (app.instrumentationClass != null) { 4542 Slog.w(TAG, "Crash of app " + app.processName 4543 + " running instrumentation " + app.instrumentationClass); 4544 Bundle info = new Bundle(); 4545 info.putString("shortMsg", "Process crashed."); 4546 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4547 } 4548 4549 if (!restarting) { 4550 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4551 // If there was nothing to resume, and we are not already 4552 // restarting this process, but there is a visible activity that 4553 // is hosted by the process... then make sure all visible 4554 // activities are running, taking care of restarting this 4555 // process. 4556 if (hasVisibleActivities) { 4557 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4558 } 4559 } 4560 } 4561 } 4562 4563 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4564 IBinder threadBinder = thread.asBinder(); 4565 // Find the application record. 4566 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4567 ProcessRecord rec = mLruProcesses.get(i); 4568 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4569 return i; 4570 } 4571 } 4572 return -1; 4573 } 4574 4575 final ProcessRecord getRecordForAppLocked( 4576 IApplicationThread thread) { 4577 if (thread == null) { 4578 return null; 4579 } 4580 4581 int appIndex = getLRURecordIndexForAppLocked(thread); 4582 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4583 } 4584 4585 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4586 // If there are no longer any background processes running, 4587 // and the app that died was not running instrumentation, 4588 // then tell everyone we are now low on memory. 4589 boolean haveBg = false; 4590 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4591 ProcessRecord rec = mLruProcesses.get(i); 4592 if (rec.thread != null 4593 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4594 haveBg = true; 4595 break; 4596 } 4597 } 4598 4599 if (!haveBg) { 4600 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4601 if (doReport) { 4602 long now = SystemClock.uptimeMillis(); 4603 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4604 doReport = false; 4605 } else { 4606 mLastMemUsageReportTime = now; 4607 } 4608 } 4609 final ArrayList<ProcessMemInfo> memInfos 4610 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4611 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4612 long now = SystemClock.uptimeMillis(); 4613 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4614 ProcessRecord rec = mLruProcesses.get(i); 4615 if (rec == dyingProc || rec.thread == null) { 4616 continue; 4617 } 4618 if (doReport) { 4619 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4620 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4621 } 4622 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4623 // The low memory report is overriding any current 4624 // state for a GC request. Make sure to do 4625 // heavy/important/visible/foreground processes first. 4626 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4627 rec.lastRequestedGc = 0; 4628 } else { 4629 rec.lastRequestedGc = rec.lastLowMemory; 4630 } 4631 rec.reportLowMemory = true; 4632 rec.lastLowMemory = now; 4633 mProcessesToGc.remove(rec); 4634 addProcessToGcListLocked(rec); 4635 } 4636 } 4637 if (doReport) { 4638 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4639 mHandler.sendMessage(msg); 4640 } 4641 scheduleAppGcsLocked(); 4642 } 4643 } 4644 4645 final void appDiedLocked(ProcessRecord app) { 4646 appDiedLocked(app, app.pid, app.thread); 4647 } 4648 4649 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4650 // First check if this ProcessRecord is actually active for the pid. 4651 synchronized (mPidsSelfLocked) { 4652 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4653 if (curProc != app) { 4654 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4655 return; 4656 } 4657 } 4658 4659 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4660 synchronized (stats) { 4661 stats.noteProcessDiedLocked(app.info.uid, pid); 4662 } 4663 4664 if (!app.killed) { 4665 Process.killProcessQuiet(pid); 4666 Process.killProcessGroup(app.info.uid, pid); 4667 app.killed = true; 4668 } 4669 4670 // Clean up already done if the process has been re-started. 4671 if (app.pid == pid && app.thread != null && 4672 app.thread.asBinder() == thread.asBinder()) { 4673 boolean doLowMem = app.instrumentationClass == null; 4674 boolean doOomAdj = doLowMem; 4675 if (!app.killedByAm) { 4676 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4677 + ") has died"); 4678 mAllowLowerMemLevel = true; 4679 } else { 4680 // Note that we always want to do oom adj to update our state with the 4681 // new number of procs. 4682 mAllowLowerMemLevel = false; 4683 doLowMem = false; 4684 } 4685 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4686 if (DEBUG_CLEANUP) Slog.v( 4687 TAG, "Dying app: " + app + ", pid: " + pid 4688 + ", thread: " + thread.asBinder()); 4689 handleAppDiedLocked(app, false, true); 4690 4691 if (doOomAdj) { 4692 updateOomAdjLocked(); 4693 } 4694 if (doLowMem) { 4695 doLowMemReportIfNeededLocked(app); 4696 } 4697 } else if (app.pid != pid) { 4698 // A new process has already been started. 4699 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4700 + ") has died and restarted (pid " + app.pid + ")."); 4701 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4702 } else if (DEBUG_PROCESSES) { 4703 Slog.d(TAG, "Received spurious death notification for thread " 4704 + thread.asBinder()); 4705 } 4706 } 4707 4708 /** 4709 * If a stack trace dump file is configured, dump process stack traces. 4710 * @param clearTraces causes the dump file to be erased prior to the new 4711 * traces being written, if true; when false, the new traces will be 4712 * appended to any existing file content. 4713 * @param firstPids of dalvik VM processes to dump stack traces for first 4714 * @param lastPids of dalvik VM processes to dump stack traces for last 4715 * @param nativeProcs optional list of native process names to dump stack crawls 4716 * @return file containing stack traces, or null if no dump file is configured 4717 */ 4718 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4719 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4720 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4721 if (tracesPath == null || tracesPath.length() == 0) { 4722 return null; 4723 } 4724 4725 File tracesFile = new File(tracesPath); 4726 try { 4727 File tracesDir = tracesFile.getParentFile(); 4728 if (!tracesDir.exists()) { 4729 tracesDir.mkdirs(); 4730 if (!SELinux.restorecon(tracesDir)) { 4731 return null; 4732 } 4733 } 4734 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4735 4736 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4737 tracesFile.createNewFile(); 4738 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4739 } catch (IOException e) { 4740 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4741 return null; 4742 } 4743 4744 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4745 return tracesFile; 4746 } 4747 4748 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4749 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4750 // Use a FileObserver to detect when traces finish writing. 4751 // The order of traces is considered important to maintain for legibility. 4752 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4753 @Override 4754 public synchronized void onEvent(int event, String path) { notify(); } 4755 }; 4756 4757 try { 4758 observer.startWatching(); 4759 4760 // First collect all of the stacks of the most important pids. 4761 if (firstPids != null) { 4762 try { 4763 int num = firstPids.size(); 4764 for (int i = 0; i < num; i++) { 4765 synchronized (observer) { 4766 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4767 observer.wait(200); // Wait for write-close, give up after 200msec 4768 } 4769 } 4770 } catch (InterruptedException e) { 4771 Slog.wtf(TAG, e); 4772 } 4773 } 4774 4775 // Next collect the stacks of the native pids 4776 if (nativeProcs != null) { 4777 int[] pids = Process.getPidsForCommands(nativeProcs); 4778 if (pids != null) { 4779 for (int pid : pids) { 4780 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4781 } 4782 } 4783 } 4784 4785 // Lastly, measure CPU usage. 4786 if (processCpuTracker != null) { 4787 processCpuTracker.init(); 4788 System.gc(); 4789 processCpuTracker.update(); 4790 try { 4791 synchronized (processCpuTracker) { 4792 processCpuTracker.wait(500); // measure over 1/2 second. 4793 } 4794 } catch (InterruptedException e) { 4795 } 4796 processCpuTracker.update(); 4797 4798 // We'll take the stack crawls of just the top apps using CPU. 4799 final int N = processCpuTracker.countWorkingStats(); 4800 int numProcs = 0; 4801 for (int i=0; i<N && numProcs<5; i++) { 4802 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4803 if (lastPids.indexOfKey(stats.pid) >= 0) { 4804 numProcs++; 4805 try { 4806 synchronized (observer) { 4807 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4808 observer.wait(200); // Wait for write-close, give up after 200msec 4809 } 4810 } catch (InterruptedException e) { 4811 Slog.wtf(TAG, e); 4812 } 4813 4814 } 4815 } 4816 } 4817 } finally { 4818 observer.stopWatching(); 4819 } 4820 } 4821 4822 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4823 if (true || IS_USER_BUILD) { 4824 return; 4825 } 4826 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4827 if (tracesPath == null || tracesPath.length() == 0) { 4828 return; 4829 } 4830 4831 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4832 StrictMode.allowThreadDiskWrites(); 4833 try { 4834 final File tracesFile = new File(tracesPath); 4835 final File tracesDir = tracesFile.getParentFile(); 4836 final File tracesTmp = new File(tracesDir, "__tmp__"); 4837 try { 4838 if (!tracesDir.exists()) { 4839 tracesDir.mkdirs(); 4840 if (!SELinux.restorecon(tracesDir.getPath())) { 4841 return; 4842 } 4843 } 4844 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4845 4846 if (tracesFile.exists()) { 4847 tracesTmp.delete(); 4848 tracesFile.renameTo(tracesTmp); 4849 } 4850 StringBuilder sb = new StringBuilder(); 4851 Time tobj = new Time(); 4852 tobj.set(System.currentTimeMillis()); 4853 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4854 sb.append(": "); 4855 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4856 sb.append(" since "); 4857 sb.append(msg); 4858 FileOutputStream fos = new FileOutputStream(tracesFile); 4859 fos.write(sb.toString().getBytes()); 4860 if (app == null) { 4861 fos.write("\n*** No application process!".getBytes()); 4862 } 4863 fos.close(); 4864 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4865 } catch (IOException e) { 4866 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4867 return; 4868 } 4869 4870 if (app != null) { 4871 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4872 firstPids.add(app.pid); 4873 dumpStackTraces(tracesPath, firstPids, null, null, null); 4874 } 4875 4876 File lastTracesFile = null; 4877 File curTracesFile = null; 4878 for (int i=9; i>=0; i--) { 4879 String name = String.format(Locale.US, "slow%02d.txt", i); 4880 curTracesFile = new File(tracesDir, name); 4881 if (curTracesFile.exists()) { 4882 if (lastTracesFile != null) { 4883 curTracesFile.renameTo(lastTracesFile); 4884 } else { 4885 curTracesFile.delete(); 4886 } 4887 } 4888 lastTracesFile = curTracesFile; 4889 } 4890 tracesFile.renameTo(curTracesFile); 4891 if (tracesTmp.exists()) { 4892 tracesTmp.renameTo(tracesFile); 4893 } 4894 } finally { 4895 StrictMode.setThreadPolicy(oldPolicy); 4896 } 4897 } 4898 4899 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4900 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4901 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4902 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4903 4904 if (mController != null) { 4905 try { 4906 // 0 == continue, -1 = kill process immediately 4907 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4908 if (res < 0 && app.pid != MY_PID) { 4909 app.kill("anr", true); 4910 } 4911 } catch (RemoteException e) { 4912 mController = null; 4913 Watchdog.getInstance().setActivityController(null); 4914 } 4915 } 4916 4917 long anrTime = SystemClock.uptimeMillis(); 4918 if (MONITOR_CPU_USAGE) { 4919 updateCpuStatsNow(); 4920 } 4921 4922 synchronized (this) { 4923 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4924 if (mShuttingDown) { 4925 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4926 return; 4927 } else if (app.notResponding) { 4928 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4929 return; 4930 } else if (app.crashing) { 4931 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4932 return; 4933 } 4934 4935 // In case we come through here for the same app before completing 4936 // this one, mark as anring now so we will bail out. 4937 app.notResponding = true; 4938 4939 // Log the ANR to the event log. 4940 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4941 app.processName, app.info.flags, annotation); 4942 4943 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4944 firstPids.add(app.pid); 4945 4946 int parentPid = app.pid; 4947 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4948 if (parentPid != app.pid) firstPids.add(parentPid); 4949 4950 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4951 4952 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4953 ProcessRecord r = mLruProcesses.get(i); 4954 if (r != null && r.thread != null) { 4955 int pid = r.pid; 4956 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4957 if (r.persistent) { 4958 firstPids.add(pid); 4959 } else { 4960 lastPids.put(pid, Boolean.TRUE); 4961 } 4962 } 4963 } 4964 } 4965 } 4966 4967 // Log the ANR to the main log. 4968 StringBuilder info = new StringBuilder(); 4969 info.setLength(0); 4970 info.append("ANR in ").append(app.processName); 4971 if (activity != null && activity.shortComponentName != null) { 4972 info.append(" (").append(activity.shortComponentName).append(")"); 4973 } 4974 info.append("\n"); 4975 info.append("PID: ").append(app.pid).append("\n"); 4976 if (annotation != null) { 4977 info.append("Reason: ").append(annotation).append("\n"); 4978 } 4979 if (parent != null && parent != activity) { 4980 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4981 } 4982 4983 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4984 4985 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4986 NATIVE_STACKS_OF_INTEREST); 4987 4988 String cpuInfo = null; 4989 if (MONITOR_CPU_USAGE) { 4990 updateCpuStatsNow(); 4991 synchronized (mProcessCpuTracker) { 4992 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4993 } 4994 info.append(processCpuTracker.printCurrentLoad()); 4995 info.append(cpuInfo); 4996 } 4997 4998 info.append(processCpuTracker.printCurrentState(anrTime)); 4999 5000 Slog.e(TAG, info.toString()); 5001 if (tracesFile == null) { 5002 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5003 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5004 } 5005 5006 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5007 cpuInfo, tracesFile, null); 5008 5009 if (mController != null) { 5010 try { 5011 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5012 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5013 if (res != 0) { 5014 if (res < 0 && app.pid != MY_PID) { 5015 app.kill("anr", true); 5016 } else { 5017 synchronized (this) { 5018 mServices.scheduleServiceTimeoutLocked(app); 5019 } 5020 } 5021 return; 5022 } 5023 } catch (RemoteException e) { 5024 mController = null; 5025 Watchdog.getInstance().setActivityController(null); 5026 } 5027 } 5028 5029 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5030 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5031 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5032 5033 synchronized (this) { 5034 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5035 5036 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5037 app.kill("bg anr", true); 5038 return; 5039 } 5040 5041 // Set the app's notResponding state, and look up the errorReportReceiver 5042 makeAppNotRespondingLocked(app, 5043 activity != null ? activity.shortComponentName : null, 5044 annotation != null ? "ANR " + annotation : "ANR", 5045 info.toString()); 5046 5047 // Bring up the infamous App Not Responding dialog 5048 Message msg = Message.obtain(); 5049 HashMap<String, Object> map = new HashMap<String, Object>(); 5050 msg.what = SHOW_NOT_RESPONDING_MSG; 5051 msg.obj = map; 5052 msg.arg1 = aboveSystem ? 1 : 0; 5053 map.put("app", app); 5054 if (activity != null) { 5055 map.put("activity", activity); 5056 } 5057 5058 mHandler.sendMessage(msg); 5059 } 5060 } 5061 5062 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5063 if (!mLaunchWarningShown) { 5064 mLaunchWarningShown = true; 5065 mHandler.post(new Runnable() { 5066 @Override 5067 public void run() { 5068 synchronized (ActivityManagerService.this) { 5069 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5070 d.show(); 5071 mHandler.postDelayed(new Runnable() { 5072 @Override 5073 public void run() { 5074 synchronized (ActivityManagerService.this) { 5075 d.dismiss(); 5076 mLaunchWarningShown = false; 5077 } 5078 } 5079 }, 4000); 5080 } 5081 } 5082 }); 5083 } 5084 } 5085 5086 @Override 5087 public boolean clearApplicationUserData(final String packageName, 5088 final IPackageDataObserver observer, int userId) { 5089 enforceNotIsolatedCaller("clearApplicationUserData"); 5090 int uid = Binder.getCallingUid(); 5091 int pid = Binder.getCallingPid(); 5092 userId = handleIncomingUser(pid, uid, 5093 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5094 long callingId = Binder.clearCallingIdentity(); 5095 try { 5096 IPackageManager pm = AppGlobals.getPackageManager(); 5097 int pkgUid = -1; 5098 synchronized(this) { 5099 try { 5100 pkgUid = pm.getPackageUid(packageName, userId); 5101 } catch (RemoteException e) { 5102 } 5103 if (pkgUid == -1) { 5104 Slog.w(TAG, "Invalid packageName: " + packageName); 5105 if (observer != null) { 5106 try { 5107 observer.onRemoveCompleted(packageName, false); 5108 } catch (RemoteException e) { 5109 Slog.i(TAG, "Observer no longer exists."); 5110 } 5111 } 5112 return false; 5113 } 5114 if (uid == pkgUid || checkComponentPermission( 5115 android.Manifest.permission.CLEAR_APP_USER_DATA, 5116 pid, uid, -1, true) 5117 == PackageManager.PERMISSION_GRANTED) { 5118 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5119 } else { 5120 throw new SecurityException("PID " + pid + " does not have permission " 5121 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5122 + " of package " + packageName); 5123 } 5124 5125 // Remove all tasks match the cleared application package and user 5126 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5127 final TaskRecord tr = mRecentTasks.get(i); 5128 final String taskPackageName = 5129 tr.getBaseIntent().getComponent().getPackageName(); 5130 if (tr.userId != userId) continue; 5131 if (!taskPackageName.equals(packageName)) continue; 5132 removeTaskByIdLocked(tr.taskId, false); 5133 } 5134 } 5135 5136 try { 5137 // Clear application user data 5138 pm.clearApplicationUserData(packageName, observer, userId); 5139 5140 synchronized(this) { 5141 // Remove all permissions granted from/to this package 5142 removeUriPermissionsForPackageLocked(packageName, userId, true); 5143 } 5144 5145 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5146 Uri.fromParts("package", packageName, null)); 5147 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5148 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5149 null, null, 0, null, null, null, false, false, userId); 5150 } catch (RemoteException e) { 5151 } 5152 } finally { 5153 Binder.restoreCallingIdentity(callingId); 5154 } 5155 return true; 5156 } 5157 5158 @Override 5159 public void killBackgroundProcesses(final String packageName, int userId) { 5160 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5161 != PackageManager.PERMISSION_GRANTED && 5162 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5163 != PackageManager.PERMISSION_GRANTED) { 5164 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5165 + Binder.getCallingPid() 5166 + ", uid=" + Binder.getCallingUid() 5167 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5168 Slog.w(TAG, msg); 5169 throw new SecurityException(msg); 5170 } 5171 5172 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5173 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5174 long callingId = Binder.clearCallingIdentity(); 5175 try { 5176 IPackageManager pm = AppGlobals.getPackageManager(); 5177 synchronized(this) { 5178 int appId = -1; 5179 try { 5180 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5181 } catch (RemoteException e) { 5182 } 5183 if (appId == -1) { 5184 Slog.w(TAG, "Invalid packageName: " + packageName); 5185 return; 5186 } 5187 killPackageProcessesLocked(packageName, appId, userId, 5188 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5189 } 5190 } finally { 5191 Binder.restoreCallingIdentity(callingId); 5192 } 5193 } 5194 5195 @Override 5196 public void killAllBackgroundProcesses() { 5197 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5198 != PackageManager.PERMISSION_GRANTED) { 5199 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5200 + Binder.getCallingPid() 5201 + ", uid=" + Binder.getCallingUid() 5202 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5203 Slog.w(TAG, msg); 5204 throw new SecurityException(msg); 5205 } 5206 5207 long callingId = Binder.clearCallingIdentity(); 5208 try { 5209 synchronized(this) { 5210 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5211 final int NP = mProcessNames.getMap().size(); 5212 for (int ip=0; ip<NP; ip++) { 5213 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5214 final int NA = apps.size(); 5215 for (int ia=0; ia<NA; ia++) { 5216 ProcessRecord app = apps.valueAt(ia); 5217 if (app.persistent) { 5218 // we don't kill persistent processes 5219 continue; 5220 } 5221 if (app.removed) { 5222 procs.add(app); 5223 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5224 app.removed = true; 5225 procs.add(app); 5226 } 5227 } 5228 } 5229 5230 int N = procs.size(); 5231 for (int i=0; i<N; i++) { 5232 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5233 } 5234 mAllowLowerMemLevel = true; 5235 updateOomAdjLocked(); 5236 doLowMemReportIfNeededLocked(null); 5237 } 5238 } finally { 5239 Binder.restoreCallingIdentity(callingId); 5240 } 5241 } 5242 5243 @Override 5244 public void forceStopPackage(final String packageName, int userId) { 5245 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5246 != PackageManager.PERMISSION_GRANTED) { 5247 String msg = "Permission Denial: forceStopPackage() from pid=" 5248 + Binder.getCallingPid() 5249 + ", uid=" + Binder.getCallingUid() 5250 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5251 Slog.w(TAG, msg); 5252 throw new SecurityException(msg); 5253 } 5254 final int callingPid = Binder.getCallingPid(); 5255 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5256 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5257 long callingId = Binder.clearCallingIdentity(); 5258 try { 5259 IPackageManager pm = AppGlobals.getPackageManager(); 5260 synchronized(this) { 5261 int[] users = userId == UserHandle.USER_ALL 5262 ? getUsersLocked() : new int[] { userId }; 5263 for (int user : users) { 5264 int pkgUid = -1; 5265 try { 5266 pkgUid = pm.getPackageUid(packageName, user); 5267 } catch (RemoteException e) { 5268 } 5269 if (pkgUid == -1) { 5270 Slog.w(TAG, "Invalid packageName: " + packageName); 5271 continue; 5272 } 5273 try { 5274 pm.setPackageStoppedState(packageName, true, user); 5275 } catch (RemoteException e) { 5276 } catch (IllegalArgumentException e) { 5277 Slog.w(TAG, "Failed trying to unstop package " 5278 + packageName + ": " + e); 5279 } 5280 if (isUserRunningLocked(user, false)) { 5281 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5282 } 5283 } 5284 } 5285 } finally { 5286 Binder.restoreCallingIdentity(callingId); 5287 } 5288 } 5289 5290 @Override 5291 public void addPackageDependency(String packageName) { 5292 synchronized (this) { 5293 int callingPid = Binder.getCallingPid(); 5294 if (callingPid == Process.myPid()) { 5295 // Yeah, um, no. 5296 Slog.w(TAG, "Can't addPackageDependency on system process"); 5297 return; 5298 } 5299 ProcessRecord proc; 5300 synchronized (mPidsSelfLocked) { 5301 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5302 } 5303 if (proc != null) { 5304 if (proc.pkgDeps == null) { 5305 proc.pkgDeps = new ArraySet<String>(1); 5306 } 5307 proc.pkgDeps.add(packageName); 5308 } 5309 } 5310 } 5311 5312 /* 5313 * The pkg name and app id have to be specified. 5314 */ 5315 @Override 5316 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5317 if (pkg == null) { 5318 return; 5319 } 5320 // Make sure the uid is valid. 5321 if (appid < 0) { 5322 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5323 return; 5324 } 5325 int callerUid = Binder.getCallingUid(); 5326 // Only the system server can kill an application 5327 if (callerUid == Process.SYSTEM_UID) { 5328 // Post an aysnc message to kill the application 5329 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5330 msg.arg1 = appid; 5331 msg.arg2 = 0; 5332 Bundle bundle = new Bundle(); 5333 bundle.putString("pkg", pkg); 5334 bundle.putString("reason", reason); 5335 msg.obj = bundle; 5336 mHandler.sendMessage(msg); 5337 } else { 5338 throw new SecurityException(callerUid + " cannot kill pkg: " + 5339 pkg); 5340 } 5341 } 5342 5343 @Override 5344 public void closeSystemDialogs(String reason) { 5345 enforceNotIsolatedCaller("closeSystemDialogs"); 5346 5347 final int pid = Binder.getCallingPid(); 5348 final int uid = Binder.getCallingUid(); 5349 final long origId = Binder.clearCallingIdentity(); 5350 try { 5351 synchronized (this) { 5352 // Only allow this from foreground processes, so that background 5353 // applications can't abuse it to prevent system UI from being shown. 5354 if (uid >= Process.FIRST_APPLICATION_UID) { 5355 ProcessRecord proc; 5356 synchronized (mPidsSelfLocked) { 5357 proc = mPidsSelfLocked.get(pid); 5358 } 5359 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5360 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5361 + " from background process " + proc); 5362 return; 5363 } 5364 } 5365 closeSystemDialogsLocked(reason); 5366 } 5367 } finally { 5368 Binder.restoreCallingIdentity(origId); 5369 } 5370 } 5371 5372 void closeSystemDialogsLocked(String reason) { 5373 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5374 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5375 | Intent.FLAG_RECEIVER_FOREGROUND); 5376 if (reason != null) { 5377 intent.putExtra("reason", reason); 5378 } 5379 mWindowManager.closeSystemDialogs(reason); 5380 5381 mStackSupervisor.closeSystemDialogsLocked(); 5382 5383 broadcastIntentLocked(null, null, intent, null, 5384 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5385 Process.SYSTEM_UID, UserHandle.USER_ALL); 5386 } 5387 5388 @Override 5389 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5390 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5391 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5392 for (int i=pids.length-1; i>=0; i--) { 5393 ProcessRecord proc; 5394 int oomAdj; 5395 synchronized (this) { 5396 synchronized (mPidsSelfLocked) { 5397 proc = mPidsSelfLocked.get(pids[i]); 5398 oomAdj = proc != null ? proc.setAdj : 0; 5399 } 5400 } 5401 infos[i] = new Debug.MemoryInfo(); 5402 Debug.getMemoryInfo(pids[i], infos[i]); 5403 if (proc != null) { 5404 synchronized (this) { 5405 if (proc.thread != null && proc.setAdj == oomAdj) { 5406 // Record this for posterity if the process has been stable. 5407 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5408 infos[i].getTotalUss(), false, proc.pkgList); 5409 } 5410 } 5411 } 5412 } 5413 return infos; 5414 } 5415 5416 @Override 5417 public long[] getProcessPss(int[] pids) { 5418 enforceNotIsolatedCaller("getProcessPss"); 5419 long[] pss = new long[pids.length]; 5420 for (int i=pids.length-1; i>=0; i--) { 5421 ProcessRecord proc; 5422 int oomAdj; 5423 synchronized (this) { 5424 synchronized (mPidsSelfLocked) { 5425 proc = mPidsSelfLocked.get(pids[i]); 5426 oomAdj = proc != null ? proc.setAdj : 0; 5427 } 5428 } 5429 long[] tmpUss = new long[1]; 5430 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5431 if (proc != null) { 5432 synchronized (this) { 5433 if (proc.thread != null && proc.setAdj == oomAdj) { 5434 // Record this for posterity if the process has been stable. 5435 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5436 } 5437 } 5438 } 5439 } 5440 return pss; 5441 } 5442 5443 @Override 5444 public void killApplicationProcess(String processName, int uid) { 5445 if (processName == null) { 5446 return; 5447 } 5448 5449 int callerUid = Binder.getCallingUid(); 5450 // Only the system server can kill an application 5451 if (callerUid == Process.SYSTEM_UID) { 5452 synchronized (this) { 5453 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5454 if (app != null && app.thread != null) { 5455 try { 5456 app.thread.scheduleSuicide(); 5457 } catch (RemoteException e) { 5458 // If the other end already died, then our work here is done. 5459 } 5460 } else { 5461 Slog.w(TAG, "Process/uid not found attempting kill of " 5462 + processName + " / " + uid); 5463 } 5464 } 5465 } else { 5466 throw new SecurityException(callerUid + " cannot kill app process: " + 5467 processName); 5468 } 5469 } 5470 5471 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5472 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5473 false, true, false, false, UserHandle.getUserId(uid), reason); 5474 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5475 Uri.fromParts("package", packageName, null)); 5476 if (!mProcessesReady) { 5477 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5478 | Intent.FLAG_RECEIVER_FOREGROUND); 5479 } 5480 intent.putExtra(Intent.EXTRA_UID, uid); 5481 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5482 broadcastIntentLocked(null, null, intent, 5483 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5484 false, false, 5485 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5486 } 5487 5488 private void forceStopUserLocked(int userId, String reason) { 5489 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5490 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5491 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5492 | Intent.FLAG_RECEIVER_FOREGROUND); 5493 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5494 broadcastIntentLocked(null, null, intent, 5495 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5496 false, false, 5497 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5498 } 5499 5500 private final boolean killPackageProcessesLocked(String packageName, int appId, 5501 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5502 boolean doit, boolean evenPersistent, String reason) { 5503 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5504 5505 // Remove all processes this package may have touched: all with the 5506 // same UID (except for the system or root user), and all whose name 5507 // matches the package name. 5508 final int NP = mProcessNames.getMap().size(); 5509 for (int ip=0; ip<NP; ip++) { 5510 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5511 final int NA = apps.size(); 5512 for (int ia=0; ia<NA; ia++) { 5513 ProcessRecord app = apps.valueAt(ia); 5514 if (app.persistent && !evenPersistent) { 5515 // we don't kill persistent processes 5516 continue; 5517 } 5518 if (app.removed) { 5519 if (doit) { 5520 procs.add(app); 5521 } 5522 continue; 5523 } 5524 5525 // Skip process if it doesn't meet our oom adj requirement. 5526 if (app.setAdj < minOomAdj) { 5527 continue; 5528 } 5529 5530 // If no package is specified, we call all processes under the 5531 // give user id. 5532 if (packageName == null) { 5533 if (app.userId != userId) { 5534 continue; 5535 } 5536 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5537 continue; 5538 } 5539 // Package has been specified, we want to hit all processes 5540 // that match it. We need to qualify this by the processes 5541 // that are running under the specified app and user ID. 5542 } else { 5543 final boolean isDep = app.pkgDeps != null 5544 && app.pkgDeps.contains(packageName); 5545 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5546 continue; 5547 } 5548 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5549 continue; 5550 } 5551 if (!app.pkgList.containsKey(packageName) && !isDep) { 5552 continue; 5553 } 5554 } 5555 5556 // Process has passed all conditions, kill it! 5557 if (!doit) { 5558 return true; 5559 } 5560 app.removed = true; 5561 procs.add(app); 5562 } 5563 } 5564 5565 int N = procs.size(); 5566 for (int i=0; i<N; i++) { 5567 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5568 } 5569 updateOomAdjLocked(); 5570 return N > 0; 5571 } 5572 5573 private final boolean forceStopPackageLocked(String name, int appId, 5574 boolean callerWillRestart, boolean purgeCache, boolean doit, 5575 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5576 int i; 5577 int N; 5578 5579 if (userId == UserHandle.USER_ALL && name == null) { 5580 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5581 } 5582 5583 if (appId < 0 && name != null) { 5584 try { 5585 appId = UserHandle.getAppId( 5586 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5587 } catch (RemoteException e) { 5588 } 5589 } 5590 5591 if (doit) { 5592 if (name != null) { 5593 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5594 + " user=" + userId + ": " + reason); 5595 } else { 5596 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5597 } 5598 5599 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5600 for (int ip=pmap.size()-1; ip>=0; ip--) { 5601 SparseArray<Long> ba = pmap.valueAt(ip); 5602 for (i=ba.size()-1; i>=0; i--) { 5603 boolean remove = false; 5604 final int entUid = ba.keyAt(i); 5605 if (name != null) { 5606 if (userId == UserHandle.USER_ALL) { 5607 if (UserHandle.getAppId(entUid) == appId) { 5608 remove = true; 5609 } 5610 } else { 5611 if (entUid == UserHandle.getUid(userId, appId)) { 5612 remove = true; 5613 } 5614 } 5615 } else if (UserHandle.getUserId(entUid) == userId) { 5616 remove = true; 5617 } 5618 if (remove) { 5619 ba.removeAt(i); 5620 } 5621 } 5622 if (ba.size() == 0) { 5623 pmap.removeAt(ip); 5624 } 5625 } 5626 } 5627 5628 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5629 -100, callerWillRestart, true, doit, evenPersistent, 5630 name == null ? ("stop user " + userId) : ("stop " + name)); 5631 5632 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5633 if (!doit) { 5634 return true; 5635 } 5636 didSomething = true; 5637 } 5638 5639 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5640 if (!doit) { 5641 return true; 5642 } 5643 didSomething = true; 5644 } 5645 5646 if (name == null) { 5647 // Remove all sticky broadcasts from this user. 5648 mStickyBroadcasts.remove(userId); 5649 } 5650 5651 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5652 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5653 userId, providers)) { 5654 if (!doit) { 5655 return true; 5656 } 5657 didSomething = true; 5658 } 5659 N = providers.size(); 5660 for (i=0; i<N; i++) { 5661 removeDyingProviderLocked(null, providers.get(i), true); 5662 } 5663 5664 // Remove transient permissions granted from/to this package/user 5665 removeUriPermissionsForPackageLocked(name, userId, false); 5666 5667 if (name == null || uninstalling) { 5668 // Remove pending intents. For now we only do this when force 5669 // stopping users, because we have some problems when doing this 5670 // for packages -- app widgets are not currently cleaned up for 5671 // such packages, so they can be left with bad pending intents. 5672 if (mIntentSenderRecords.size() > 0) { 5673 Iterator<WeakReference<PendingIntentRecord>> it 5674 = mIntentSenderRecords.values().iterator(); 5675 while (it.hasNext()) { 5676 WeakReference<PendingIntentRecord> wpir = it.next(); 5677 if (wpir == null) { 5678 it.remove(); 5679 continue; 5680 } 5681 PendingIntentRecord pir = wpir.get(); 5682 if (pir == null) { 5683 it.remove(); 5684 continue; 5685 } 5686 if (name == null) { 5687 // Stopping user, remove all objects for the user. 5688 if (pir.key.userId != userId) { 5689 // Not the same user, skip it. 5690 continue; 5691 } 5692 } else { 5693 if (UserHandle.getAppId(pir.uid) != appId) { 5694 // Different app id, skip it. 5695 continue; 5696 } 5697 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5698 // Different user, skip it. 5699 continue; 5700 } 5701 if (!pir.key.packageName.equals(name)) { 5702 // Different package, skip it. 5703 continue; 5704 } 5705 } 5706 if (!doit) { 5707 return true; 5708 } 5709 didSomething = true; 5710 it.remove(); 5711 pir.canceled = true; 5712 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5713 pir.key.activity.pendingResults.remove(pir.ref); 5714 } 5715 } 5716 } 5717 } 5718 5719 if (doit) { 5720 if (purgeCache && name != null) { 5721 AttributeCache ac = AttributeCache.instance(); 5722 if (ac != null) { 5723 ac.removePackage(name); 5724 } 5725 } 5726 if (mBooted) { 5727 mStackSupervisor.resumeTopActivitiesLocked(); 5728 mStackSupervisor.scheduleIdleLocked(); 5729 } 5730 } 5731 5732 return didSomething; 5733 } 5734 5735 private final boolean removeProcessLocked(ProcessRecord app, 5736 boolean callerWillRestart, boolean allowRestart, String reason) { 5737 final String name = app.processName; 5738 final int uid = app.uid; 5739 if (DEBUG_PROCESSES) Slog.d( 5740 TAG, "Force removing proc " + app.toShortString() + " (" + name 5741 + "/" + uid + ")"); 5742 5743 mProcessNames.remove(name, uid); 5744 mIsolatedProcesses.remove(app.uid); 5745 if (mHeavyWeightProcess == app) { 5746 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5747 mHeavyWeightProcess.userId, 0)); 5748 mHeavyWeightProcess = null; 5749 } 5750 boolean needRestart = false; 5751 if (app.pid > 0 && app.pid != MY_PID) { 5752 int pid = app.pid; 5753 synchronized (mPidsSelfLocked) { 5754 mPidsSelfLocked.remove(pid); 5755 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5756 } 5757 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5758 if (app.isolated) { 5759 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5760 } 5761 app.kill(reason, true); 5762 handleAppDiedLocked(app, true, allowRestart); 5763 removeLruProcessLocked(app); 5764 5765 if (app.persistent && !app.isolated) { 5766 if (!callerWillRestart) { 5767 addAppLocked(app.info, false, null /* ABI override */); 5768 } else { 5769 needRestart = true; 5770 } 5771 } 5772 } else { 5773 mRemovedProcesses.add(app); 5774 } 5775 5776 return needRestart; 5777 } 5778 5779 private final void processStartTimedOutLocked(ProcessRecord app) { 5780 final int pid = app.pid; 5781 boolean gone = false; 5782 synchronized (mPidsSelfLocked) { 5783 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5784 if (knownApp != null && knownApp.thread == null) { 5785 mPidsSelfLocked.remove(pid); 5786 gone = true; 5787 } 5788 } 5789 5790 if (gone) { 5791 Slog.w(TAG, "Process " + app + " failed to attach"); 5792 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5793 pid, app.uid, app.processName); 5794 mProcessNames.remove(app.processName, app.uid); 5795 mIsolatedProcesses.remove(app.uid); 5796 if (mHeavyWeightProcess == app) { 5797 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5798 mHeavyWeightProcess.userId, 0)); 5799 mHeavyWeightProcess = null; 5800 } 5801 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5802 if (app.isolated) { 5803 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5804 } 5805 // Take care of any launching providers waiting for this process. 5806 checkAppInLaunchingProvidersLocked(app, true); 5807 // Take care of any services that are waiting for the process. 5808 mServices.processStartTimedOutLocked(app); 5809 app.kill("start timeout", true); 5810 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5811 Slog.w(TAG, "Unattached app died before backup, skipping"); 5812 try { 5813 IBackupManager bm = IBackupManager.Stub.asInterface( 5814 ServiceManager.getService(Context.BACKUP_SERVICE)); 5815 bm.agentDisconnected(app.info.packageName); 5816 } catch (RemoteException e) { 5817 // Can't happen; the backup manager is local 5818 } 5819 } 5820 if (isPendingBroadcastProcessLocked(pid)) { 5821 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5822 skipPendingBroadcastLocked(pid); 5823 } 5824 } else { 5825 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5826 } 5827 } 5828 5829 private final boolean attachApplicationLocked(IApplicationThread thread, 5830 int pid) { 5831 5832 // Find the application record that is being attached... either via 5833 // the pid if we are running in multiple processes, or just pull the 5834 // next app record if we are emulating process with anonymous threads. 5835 ProcessRecord app; 5836 if (pid != MY_PID && pid >= 0) { 5837 synchronized (mPidsSelfLocked) { 5838 app = mPidsSelfLocked.get(pid); 5839 } 5840 } else { 5841 app = null; 5842 } 5843 5844 if (app == null) { 5845 Slog.w(TAG, "No pending application record for pid " + pid 5846 + " (IApplicationThread " + thread + "); dropping process"); 5847 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5848 if (pid > 0 && pid != MY_PID) { 5849 Process.killProcessQuiet(pid); 5850 //TODO: Process.killProcessGroup(app.info.uid, pid); 5851 } else { 5852 try { 5853 thread.scheduleExit(); 5854 } catch (Exception e) { 5855 // Ignore exceptions. 5856 } 5857 } 5858 return false; 5859 } 5860 5861 // If this application record is still attached to a previous 5862 // process, clean it up now. 5863 if (app.thread != null) { 5864 handleAppDiedLocked(app, true, true); 5865 } 5866 5867 // Tell the process all about itself. 5868 5869 if (localLOGV) Slog.v( 5870 TAG, "Binding process pid " + pid + " to record " + app); 5871 5872 final String processName = app.processName; 5873 try { 5874 AppDeathRecipient adr = new AppDeathRecipient( 5875 app, pid, thread); 5876 thread.asBinder().linkToDeath(adr, 0); 5877 app.deathRecipient = adr; 5878 } catch (RemoteException e) { 5879 app.resetPackageList(mProcessStats); 5880 startProcessLocked(app, "link fail", processName); 5881 return false; 5882 } 5883 5884 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5885 5886 app.makeActive(thread, mProcessStats); 5887 app.curAdj = app.setAdj = -100; 5888 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5889 app.forcingToForeground = null; 5890 updateProcessForegroundLocked(app, false, false); 5891 app.hasShownUi = false; 5892 app.debugging = false; 5893 app.cached = false; 5894 app.killedByAm = false; 5895 5896 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5897 5898 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5899 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5900 5901 if (!normalMode) { 5902 Slog.i(TAG, "Launching preboot mode app: " + app); 5903 } 5904 5905 if (localLOGV) Slog.v( 5906 TAG, "New app record " + app 5907 + " thread=" + thread.asBinder() + " pid=" + pid); 5908 try { 5909 int testMode = IApplicationThread.DEBUG_OFF; 5910 if (mDebugApp != null && mDebugApp.equals(processName)) { 5911 testMode = mWaitForDebugger 5912 ? IApplicationThread.DEBUG_WAIT 5913 : IApplicationThread.DEBUG_ON; 5914 app.debugging = true; 5915 if (mDebugTransient) { 5916 mDebugApp = mOrigDebugApp; 5917 mWaitForDebugger = mOrigWaitForDebugger; 5918 } 5919 } 5920 String profileFile = app.instrumentationProfileFile; 5921 ParcelFileDescriptor profileFd = null; 5922 int samplingInterval = 0; 5923 boolean profileAutoStop = false; 5924 if (mProfileApp != null && mProfileApp.equals(processName)) { 5925 mProfileProc = app; 5926 profileFile = mProfileFile; 5927 profileFd = mProfileFd; 5928 samplingInterval = mSamplingInterval; 5929 profileAutoStop = mAutoStopProfiler; 5930 } 5931 boolean enableOpenGlTrace = false; 5932 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5933 enableOpenGlTrace = true; 5934 mOpenGlTraceApp = null; 5935 } 5936 5937 // If the app is being launched for restore or full backup, set it up specially 5938 boolean isRestrictedBackupMode = false; 5939 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5940 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5941 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5942 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5943 } 5944 5945 ensurePackageDexOpt(app.instrumentationInfo != null 5946 ? app.instrumentationInfo.packageName 5947 : app.info.packageName); 5948 if (app.instrumentationClass != null) { 5949 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5950 } 5951 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5952 + processName + " with config " + mConfiguration); 5953 ApplicationInfo appInfo = app.instrumentationInfo != null 5954 ? app.instrumentationInfo : app.info; 5955 app.compat = compatibilityInfoForPackageLocked(appInfo); 5956 if (profileFd != null) { 5957 profileFd = profileFd.dup(); 5958 } 5959 ProfilerInfo profilerInfo = profileFile == null ? null 5960 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5961 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5962 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5963 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5964 isRestrictedBackupMode || !normalMode, app.persistent, 5965 new Configuration(mConfiguration), app.compat, 5966 getCommonServicesLocked(app.isolated), 5967 mCoreSettingsObserver.getCoreSettingsLocked()); 5968 updateLruProcessLocked(app, false, null); 5969 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5970 } catch (Exception e) { 5971 // todo: Yikes! What should we do? For now we will try to 5972 // start another process, but that could easily get us in 5973 // an infinite loop of restarting processes... 5974 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5975 5976 app.resetPackageList(mProcessStats); 5977 app.unlinkDeathRecipient(); 5978 startProcessLocked(app, "bind fail", processName); 5979 return false; 5980 } 5981 5982 // Remove this record from the list of starting applications. 5983 mPersistentStartingProcesses.remove(app); 5984 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5985 "Attach application locked removing on hold: " + app); 5986 mProcessesOnHold.remove(app); 5987 5988 boolean badApp = false; 5989 boolean didSomething = false; 5990 5991 // See if the top visible activity is waiting to run in this process... 5992 if (normalMode) { 5993 try { 5994 if (mStackSupervisor.attachApplicationLocked(app)) { 5995 didSomething = true; 5996 } 5997 } catch (Exception e) { 5998 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5999 badApp = true; 6000 } 6001 } 6002 6003 // Find any services that should be running in this process... 6004 if (!badApp) { 6005 try { 6006 didSomething |= mServices.attachApplicationLocked(app, processName); 6007 } catch (Exception e) { 6008 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6009 badApp = true; 6010 } 6011 } 6012 6013 // Check if a next-broadcast receiver is in this process... 6014 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6015 try { 6016 didSomething |= sendPendingBroadcastsLocked(app); 6017 } catch (Exception e) { 6018 // If the app died trying to launch the receiver we declare it 'bad' 6019 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6020 badApp = true; 6021 } 6022 } 6023 6024 // Check whether the next backup agent is in this process... 6025 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6026 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6027 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6028 try { 6029 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6030 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6031 mBackupTarget.backupMode); 6032 } catch (Exception e) { 6033 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6034 badApp = true; 6035 } 6036 } 6037 6038 if (badApp) { 6039 app.kill("error during init", true); 6040 handleAppDiedLocked(app, false, true); 6041 return false; 6042 } 6043 6044 if (!didSomething) { 6045 updateOomAdjLocked(); 6046 } 6047 6048 return true; 6049 } 6050 6051 @Override 6052 public final void attachApplication(IApplicationThread thread) { 6053 synchronized (this) { 6054 int callingPid = Binder.getCallingPid(); 6055 final long origId = Binder.clearCallingIdentity(); 6056 attachApplicationLocked(thread, callingPid); 6057 Binder.restoreCallingIdentity(origId); 6058 } 6059 } 6060 6061 @Override 6062 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6063 final long origId = Binder.clearCallingIdentity(); 6064 synchronized (this) { 6065 ActivityStack stack = ActivityRecord.getStackLocked(token); 6066 if (stack != null) { 6067 ActivityRecord r = 6068 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6069 if (stopProfiling) { 6070 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6071 try { 6072 mProfileFd.close(); 6073 } catch (IOException e) { 6074 } 6075 clearProfilerLocked(); 6076 } 6077 } 6078 } 6079 } 6080 Binder.restoreCallingIdentity(origId); 6081 } 6082 6083 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6084 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6085 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6086 } 6087 6088 void enableScreenAfterBoot() { 6089 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6090 SystemClock.uptimeMillis()); 6091 mWindowManager.enableScreenAfterBoot(); 6092 6093 synchronized (this) { 6094 updateEventDispatchingLocked(); 6095 } 6096 } 6097 6098 @Override 6099 public void showBootMessage(final CharSequence msg, final boolean always) { 6100 enforceNotIsolatedCaller("showBootMessage"); 6101 mWindowManager.showBootMessage(msg, always); 6102 } 6103 6104 @Override 6105 public void keyguardWaitingForActivityDrawn() { 6106 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6107 final long token = Binder.clearCallingIdentity(); 6108 try { 6109 synchronized (this) { 6110 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6111 mWindowManager.keyguardWaitingForActivityDrawn(); 6112 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6113 mLockScreenShown = LOCK_SCREEN_LEAVING; 6114 updateSleepIfNeededLocked(); 6115 } 6116 } 6117 } finally { 6118 Binder.restoreCallingIdentity(token); 6119 } 6120 } 6121 6122 final void finishBooting() { 6123 synchronized (this) { 6124 if (!mBootAnimationComplete) { 6125 mCallFinishBooting = true; 6126 return; 6127 } 6128 mCallFinishBooting = false; 6129 } 6130 6131 ArraySet<String> completedIsas = new ArraySet<String>(); 6132 for (String abi : Build.SUPPORTED_ABIS) { 6133 Process.establishZygoteConnectionForAbi(abi); 6134 final String instructionSet = VMRuntime.getInstructionSet(abi); 6135 if (!completedIsas.contains(instructionSet)) { 6136 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6137 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6138 } 6139 completedIsas.add(instructionSet); 6140 } 6141 } 6142 6143 IntentFilter pkgFilter = new IntentFilter(); 6144 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6145 pkgFilter.addDataScheme("package"); 6146 mContext.registerReceiver(new BroadcastReceiver() { 6147 @Override 6148 public void onReceive(Context context, Intent intent) { 6149 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6150 if (pkgs != null) { 6151 for (String pkg : pkgs) { 6152 synchronized (ActivityManagerService.this) { 6153 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6154 0, "finished booting")) { 6155 setResultCode(Activity.RESULT_OK); 6156 return; 6157 } 6158 } 6159 } 6160 } 6161 } 6162 }, pkgFilter); 6163 6164 // Let system services know. 6165 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6166 6167 synchronized (this) { 6168 // Ensure that any processes we had put on hold are now started 6169 // up. 6170 final int NP = mProcessesOnHold.size(); 6171 if (NP > 0) { 6172 ArrayList<ProcessRecord> procs = 6173 new ArrayList<ProcessRecord>(mProcessesOnHold); 6174 for (int ip=0; ip<NP; ip++) { 6175 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6176 + procs.get(ip)); 6177 startProcessLocked(procs.get(ip), "on-hold", null); 6178 } 6179 } 6180 6181 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6182 // Start looking for apps that are abusing wake locks. 6183 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6184 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6185 // Tell anyone interested that we are done booting! 6186 SystemProperties.set("sys.boot_completed", "1"); 6187 6188 // And trigger dev.bootcomplete if we are not showing encryption progress 6189 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6190 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6191 SystemProperties.set("dev.bootcomplete", "1"); 6192 } 6193 for (int i=0; i<mStartedUsers.size(); i++) { 6194 UserStartedState uss = mStartedUsers.valueAt(i); 6195 if (uss.mState == UserStartedState.STATE_BOOTING) { 6196 uss.mState = UserStartedState.STATE_RUNNING; 6197 final int userId = mStartedUsers.keyAt(i); 6198 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6199 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6200 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6201 broadcastIntentLocked(null, null, intent, null, 6202 new IIntentReceiver.Stub() { 6203 @Override 6204 public void performReceive(Intent intent, int resultCode, 6205 String data, Bundle extras, boolean ordered, 6206 boolean sticky, int sendingUser) { 6207 synchronized (ActivityManagerService.this) { 6208 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6209 true, false); 6210 } 6211 } 6212 }, 6213 0, null, null, 6214 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6215 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6216 userId); 6217 } 6218 } 6219 scheduleStartProfilesLocked(); 6220 } 6221 } 6222 } 6223 6224 @Override 6225 public void bootAnimationComplete() { 6226 final boolean callFinishBooting; 6227 synchronized (this) { 6228 callFinishBooting = mCallFinishBooting; 6229 mBootAnimationComplete = true; 6230 } 6231 if (callFinishBooting) { 6232 finishBooting(); 6233 } 6234 } 6235 6236 @Override 6237 public void systemBackupRestored() { 6238 synchronized (this) { 6239 if (mSystemReady) { 6240 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6241 } else { 6242 Slog.w(TAG, "System backup restored before system is ready"); 6243 } 6244 } 6245 } 6246 6247 final void ensureBootCompleted() { 6248 boolean booting; 6249 boolean enableScreen; 6250 synchronized (this) { 6251 booting = mBooting; 6252 mBooting = false; 6253 enableScreen = !mBooted; 6254 mBooted = true; 6255 } 6256 6257 if (booting) { 6258 finishBooting(); 6259 } 6260 6261 if (enableScreen) { 6262 enableScreenAfterBoot(); 6263 } 6264 } 6265 6266 @Override 6267 public final void activityResumed(IBinder token) { 6268 final long origId = Binder.clearCallingIdentity(); 6269 synchronized(this) { 6270 ActivityStack stack = ActivityRecord.getStackLocked(token); 6271 if (stack != null) { 6272 ActivityRecord.activityResumedLocked(token); 6273 } 6274 } 6275 Binder.restoreCallingIdentity(origId); 6276 } 6277 6278 @Override 6279 public final void activityPaused(IBinder token) { 6280 final long origId = Binder.clearCallingIdentity(); 6281 synchronized(this) { 6282 ActivityStack stack = ActivityRecord.getStackLocked(token); 6283 if (stack != null) { 6284 stack.activityPausedLocked(token, false); 6285 } 6286 } 6287 Binder.restoreCallingIdentity(origId); 6288 } 6289 6290 @Override 6291 public final void activityStopped(IBinder token, Bundle icicle, 6292 PersistableBundle persistentState, CharSequence description) { 6293 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6294 6295 // Refuse possible leaked file descriptors 6296 if (icicle != null && icicle.hasFileDescriptors()) { 6297 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6298 } 6299 6300 final long origId = Binder.clearCallingIdentity(); 6301 6302 synchronized (this) { 6303 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6304 if (r != null) { 6305 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6306 } 6307 } 6308 6309 trimApplications(); 6310 6311 Binder.restoreCallingIdentity(origId); 6312 } 6313 6314 @Override 6315 public final void activityDestroyed(IBinder token) { 6316 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6317 synchronized (this) { 6318 ActivityStack stack = ActivityRecord.getStackLocked(token); 6319 if (stack != null) { 6320 stack.activityDestroyedLocked(token); 6321 } 6322 } 6323 } 6324 6325 @Override 6326 public final void backgroundResourcesReleased(IBinder token) { 6327 final long origId = Binder.clearCallingIdentity(); 6328 try { 6329 synchronized (this) { 6330 ActivityStack stack = ActivityRecord.getStackLocked(token); 6331 if (stack != null) { 6332 stack.backgroundResourcesReleased(); 6333 } 6334 } 6335 } finally { 6336 Binder.restoreCallingIdentity(origId); 6337 } 6338 } 6339 6340 @Override 6341 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6342 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6343 } 6344 6345 @Override 6346 public final void notifyEnterAnimationComplete(IBinder token) { 6347 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6348 } 6349 6350 @Override 6351 public String getCallingPackage(IBinder token) { 6352 synchronized (this) { 6353 ActivityRecord r = getCallingRecordLocked(token); 6354 return r != null ? r.info.packageName : null; 6355 } 6356 } 6357 6358 @Override 6359 public ComponentName getCallingActivity(IBinder token) { 6360 synchronized (this) { 6361 ActivityRecord r = getCallingRecordLocked(token); 6362 return r != null ? r.intent.getComponent() : null; 6363 } 6364 } 6365 6366 private ActivityRecord getCallingRecordLocked(IBinder token) { 6367 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6368 if (r == null) { 6369 return null; 6370 } 6371 return r.resultTo; 6372 } 6373 6374 @Override 6375 public ComponentName getActivityClassForToken(IBinder token) { 6376 synchronized(this) { 6377 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6378 if (r == null) { 6379 return null; 6380 } 6381 return r.intent.getComponent(); 6382 } 6383 } 6384 6385 @Override 6386 public String getPackageForToken(IBinder token) { 6387 synchronized(this) { 6388 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6389 if (r == null) { 6390 return null; 6391 } 6392 return r.packageName; 6393 } 6394 } 6395 6396 @Override 6397 public IIntentSender getIntentSender(int type, 6398 String packageName, IBinder token, String resultWho, 6399 int requestCode, Intent[] intents, String[] resolvedTypes, 6400 int flags, Bundle options, int userId) { 6401 enforceNotIsolatedCaller("getIntentSender"); 6402 // Refuse possible leaked file descriptors 6403 if (intents != null) { 6404 if (intents.length < 1) { 6405 throw new IllegalArgumentException("Intents array length must be >= 1"); 6406 } 6407 for (int i=0; i<intents.length; i++) { 6408 Intent intent = intents[i]; 6409 if (intent != null) { 6410 if (intent.hasFileDescriptors()) { 6411 throw new IllegalArgumentException("File descriptors passed in Intent"); 6412 } 6413 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6414 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6415 throw new IllegalArgumentException( 6416 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6417 } 6418 intents[i] = new Intent(intent); 6419 } 6420 } 6421 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6422 throw new IllegalArgumentException( 6423 "Intent array length does not match resolvedTypes length"); 6424 } 6425 } 6426 if (options != null) { 6427 if (options.hasFileDescriptors()) { 6428 throw new IllegalArgumentException("File descriptors passed in options"); 6429 } 6430 } 6431 6432 synchronized(this) { 6433 int callingUid = Binder.getCallingUid(); 6434 int origUserId = userId; 6435 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6436 type == ActivityManager.INTENT_SENDER_BROADCAST, 6437 ALLOW_NON_FULL, "getIntentSender", null); 6438 if (origUserId == UserHandle.USER_CURRENT) { 6439 // We don't want to evaluate this until the pending intent is 6440 // actually executed. However, we do want to always do the 6441 // security checking for it above. 6442 userId = UserHandle.USER_CURRENT; 6443 } 6444 try { 6445 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6446 int uid = AppGlobals.getPackageManager() 6447 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6448 if (!UserHandle.isSameApp(callingUid, uid)) { 6449 String msg = "Permission Denial: getIntentSender() from pid=" 6450 + Binder.getCallingPid() 6451 + ", uid=" + Binder.getCallingUid() 6452 + ", (need uid=" + uid + ")" 6453 + " is not allowed to send as package " + packageName; 6454 Slog.w(TAG, msg); 6455 throw new SecurityException(msg); 6456 } 6457 } 6458 6459 return getIntentSenderLocked(type, packageName, callingUid, userId, 6460 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6461 6462 } catch (RemoteException e) { 6463 throw new SecurityException(e); 6464 } 6465 } 6466 } 6467 6468 IIntentSender getIntentSenderLocked(int type, String packageName, 6469 int callingUid, int userId, IBinder token, String resultWho, 6470 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6471 Bundle options) { 6472 if (DEBUG_MU) 6473 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6474 ActivityRecord activity = null; 6475 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6476 activity = ActivityRecord.isInStackLocked(token); 6477 if (activity == null) { 6478 return null; 6479 } 6480 if (activity.finishing) { 6481 return null; 6482 } 6483 } 6484 6485 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6486 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6487 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6488 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6489 |PendingIntent.FLAG_UPDATE_CURRENT); 6490 6491 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6492 type, packageName, activity, resultWho, 6493 requestCode, intents, resolvedTypes, flags, options, userId); 6494 WeakReference<PendingIntentRecord> ref; 6495 ref = mIntentSenderRecords.get(key); 6496 PendingIntentRecord rec = ref != null ? ref.get() : null; 6497 if (rec != null) { 6498 if (!cancelCurrent) { 6499 if (updateCurrent) { 6500 if (rec.key.requestIntent != null) { 6501 rec.key.requestIntent.replaceExtras(intents != null ? 6502 intents[intents.length - 1] : null); 6503 } 6504 if (intents != null) { 6505 intents[intents.length-1] = rec.key.requestIntent; 6506 rec.key.allIntents = intents; 6507 rec.key.allResolvedTypes = resolvedTypes; 6508 } else { 6509 rec.key.allIntents = null; 6510 rec.key.allResolvedTypes = null; 6511 } 6512 } 6513 return rec; 6514 } 6515 rec.canceled = true; 6516 mIntentSenderRecords.remove(key); 6517 } 6518 if (noCreate) { 6519 return rec; 6520 } 6521 rec = new PendingIntentRecord(this, key, callingUid); 6522 mIntentSenderRecords.put(key, rec.ref); 6523 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6524 if (activity.pendingResults == null) { 6525 activity.pendingResults 6526 = new HashSet<WeakReference<PendingIntentRecord>>(); 6527 } 6528 activity.pendingResults.add(rec.ref); 6529 } 6530 return rec; 6531 } 6532 6533 @Override 6534 public void cancelIntentSender(IIntentSender sender) { 6535 if (!(sender instanceof PendingIntentRecord)) { 6536 return; 6537 } 6538 synchronized(this) { 6539 PendingIntentRecord rec = (PendingIntentRecord)sender; 6540 try { 6541 int uid = AppGlobals.getPackageManager() 6542 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6543 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6544 String msg = "Permission Denial: cancelIntentSender() from pid=" 6545 + Binder.getCallingPid() 6546 + ", uid=" + Binder.getCallingUid() 6547 + " is not allowed to cancel packges " 6548 + rec.key.packageName; 6549 Slog.w(TAG, msg); 6550 throw new SecurityException(msg); 6551 } 6552 } catch (RemoteException e) { 6553 throw new SecurityException(e); 6554 } 6555 cancelIntentSenderLocked(rec, true); 6556 } 6557 } 6558 6559 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6560 rec.canceled = true; 6561 mIntentSenderRecords.remove(rec.key); 6562 if (cleanActivity && rec.key.activity != null) { 6563 rec.key.activity.pendingResults.remove(rec.ref); 6564 } 6565 } 6566 6567 @Override 6568 public String getPackageForIntentSender(IIntentSender pendingResult) { 6569 if (!(pendingResult instanceof PendingIntentRecord)) { 6570 return null; 6571 } 6572 try { 6573 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6574 return res.key.packageName; 6575 } catch (ClassCastException e) { 6576 } 6577 return null; 6578 } 6579 6580 @Override 6581 public int getUidForIntentSender(IIntentSender sender) { 6582 if (sender instanceof PendingIntentRecord) { 6583 try { 6584 PendingIntentRecord res = (PendingIntentRecord)sender; 6585 return res.uid; 6586 } catch (ClassCastException e) { 6587 } 6588 } 6589 return -1; 6590 } 6591 6592 @Override 6593 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6594 if (!(pendingResult instanceof PendingIntentRecord)) { 6595 return false; 6596 } 6597 try { 6598 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6599 if (res.key.allIntents == null) { 6600 return false; 6601 } 6602 for (int i=0; i<res.key.allIntents.length; i++) { 6603 Intent intent = res.key.allIntents[i]; 6604 if (intent.getPackage() != null && intent.getComponent() != null) { 6605 return false; 6606 } 6607 } 6608 return true; 6609 } catch (ClassCastException e) { 6610 } 6611 return false; 6612 } 6613 6614 @Override 6615 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6616 if (!(pendingResult instanceof PendingIntentRecord)) { 6617 return false; 6618 } 6619 try { 6620 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6621 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6622 return true; 6623 } 6624 return false; 6625 } catch (ClassCastException e) { 6626 } 6627 return false; 6628 } 6629 6630 @Override 6631 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6632 if (!(pendingResult instanceof PendingIntentRecord)) { 6633 return null; 6634 } 6635 try { 6636 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6637 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6638 } catch (ClassCastException e) { 6639 } 6640 return null; 6641 } 6642 6643 @Override 6644 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6645 if (!(pendingResult instanceof PendingIntentRecord)) { 6646 return null; 6647 } 6648 try { 6649 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6650 Intent intent = res.key.requestIntent; 6651 if (intent != null) { 6652 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6653 || res.lastTagPrefix.equals(prefix))) { 6654 return res.lastTag; 6655 } 6656 res.lastTagPrefix = prefix; 6657 StringBuilder sb = new StringBuilder(128); 6658 if (prefix != null) { 6659 sb.append(prefix); 6660 } 6661 if (intent.getAction() != null) { 6662 sb.append(intent.getAction()); 6663 } else if (intent.getComponent() != null) { 6664 intent.getComponent().appendShortString(sb); 6665 } else { 6666 sb.append("?"); 6667 } 6668 return res.lastTag = sb.toString(); 6669 } 6670 } catch (ClassCastException e) { 6671 } 6672 return null; 6673 } 6674 6675 @Override 6676 public void setProcessLimit(int max) { 6677 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6678 "setProcessLimit()"); 6679 synchronized (this) { 6680 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6681 mProcessLimitOverride = max; 6682 } 6683 trimApplications(); 6684 } 6685 6686 @Override 6687 public int getProcessLimit() { 6688 synchronized (this) { 6689 return mProcessLimitOverride; 6690 } 6691 } 6692 6693 void foregroundTokenDied(ForegroundToken token) { 6694 synchronized (ActivityManagerService.this) { 6695 synchronized (mPidsSelfLocked) { 6696 ForegroundToken cur 6697 = mForegroundProcesses.get(token.pid); 6698 if (cur != token) { 6699 return; 6700 } 6701 mForegroundProcesses.remove(token.pid); 6702 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6703 if (pr == null) { 6704 return; 6705 } 6706 pr.forcingToForeground = null; 6707 updateProcessForegroundLocked(pr, false, false); 6708 } 6709 updateOomAdjLocked(); 6710 } 6711 } 6712 6713 @Override 6714 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6715 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6716 "setProcessForeground()"); 6717 synchronized(this) { 6718 boolean changed = false; 6719 6720 synchronized (mPidsSelfLocked) { 6721 ProcessRecord pr = mPidsSelfLocked.get(pid); 6722 if (pr == null && isForeground) { 6723 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6724 return; 6725 } 6726 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6727 if (oldToken != null) { 6728 oldToken.token.unlinkToDeath(oldToken, 0); 6729 mForegroundProcesses.remove(pid); 6730 if (pr != null) { 6731 pr.forcingToForeground = null; 6732 } 6733 changed = true; 6734 } 6735 if (isForeground && token != null) { 6736 ForegroundToken newToken = new ForegroundToken() { 6737 @Override 6738 public void binderDied() { 6739 foregroundTokenDied(this); 6740 } 6741 }; 6742 newToken.pid = pid; 6743 newToken.token = token; 6744 try { 6745 token.linkToDeath(newToken, 0); 6746 mForegroundProcesses.put(pid, newToken); 6747 pr.forcingToForeground = token; 6748 changed = true; 6749 } catch (RemoteException e) { 6750 // If the process died while doing this, we will later 6751 // do the cleanup with the process death link. 6752 } 6753 } 6754 } 6755 6756 if (changed) { 6757 updateOomAdjLocked(); 6758 } 6759 } 6760 } 6761 6762 // ========================================================= 6763 // PERMISSIONS 6764 // ========================================================= 6765 6766 static class PermissionController extends IPermissionController.Stub { 6767 ActivityManagerService mActivityManagerService; 6768 PermissionController(ActivityManagerService activityManagerService) { 6769 mActivityManagerService = activityManagerService; 6770 } 6771 6772 @Override 6773 public boolean checkPermission(String permission, int pid, int uid) { 6774 return mActivityManagerService.checkPermission(permission, pid, 6775 uid) == PackageManager.PERMISSION_GRANTED; 6776 } 6777 } 6778 6779 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6780 @Override 6781 public int checkComponentPermission(String permission, int pid, int uid, 6782 int owningUid, boolean exported) { 6783 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6784 owningUid, exported); 6785 } 6786 6787 @Override 6788 public Object getAMSLock() { 6789 return ActivityManagerService.this; 6790 } 6791 } 6792 6793 /** 6794 * This can be called with or without the global lock held. 6795 */ 6796 int checkComponentPermission(String permission, int pid, int uid, 6797 int owningUid, boolean exported) { 6798 if (pid == MY_PID) { 6799 return PackageManager.PERMISSION_GRANTED; 6800 } 6801 return ActivityManager.checkComponentPermission(permission, uid, 6802 owningUid, exported); 6803 } 6804 6805 /** 6806 * As the only public entry point for permissions checking, this method 6807 * can enforce the semantic that requesting a check on a null global 6808 * permission is automatically denied. (Internally a null permission 6809 * string is used when calling {@link #checkComponentPermission} in cases 6810 * when only uid-based security is needed.) 6811 * 6812 * This can be called with or without the global lock held. 6813 */ 6814 @Override 6815 public int checkPermission(String permission, int pid, int uid) { 6816 if (permission == null) { 6817 return PackageManager.PERMISSION_DENIED; 6818 } 6819 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6820 } 6821 6822 @Override 6823 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6824 if (permission == null) { 6825 return PackageManager.PERMISSION_DENIED; 6826 } 6827 6828 // We might be performing an operation on behalf of an indirect binder 6829 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6830 // client identity accordingly before proceeding. 6831 Identity tlsIdentity = sCallerIdentity.get(); 6832 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6833 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6834 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6835 uid = tlsIdentity.uid; 6836 pid = tlsIdentity.pid; 6837 } 6838 6839 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6840 } 6841 6842 /** 6843 * Binder IPC calls go through the public entry point. 6844 * This can be called with or without the global lock held. 6845 */ 6846 int checkCallingPermission(String permission) { 6847 return checkPermission(permission, 6848 Binder.getCallingPid(), 6849 UserHandle.getAppId(Binder.getCallingUid())); 6850 } 6851 6852 /** 6853 * This can be called with or without the global lock held. 6854 */ 6855 void enforceCallingPermission(String permission, String func) { 6856 if (checkCallingPermission(permission) 6857 == PackageManager.PERMISSION_GRANTED) { 6858 return; 6859 } 6860 6861 String msg = "Permission Denial: " + func + " from pid=" 6862 + Binder.getCallingPid() 6863 + ", uid=" + Binder.getCallingUid() 6864 + " requires " + permission; 6865 Slog.w(TAG, msg); 6866 throw new SecurityException(msg); 6867 } 6868 6869 /** 6870 * Determine if UID is holding permissions required to access {@link Uri} in 6871 * the given {@link ProviderInfo}. Final permission checking is always done 6872 * in {@link ContentProvider}. 6873 */ 6874 private final boolean checkHoldingPermissionsLocked( 6875 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6876 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6877 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6878 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6879 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6880 != PERMISSION_GRANTED) { 6881 return false; 6882 } 6883 } 6884 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6885 } 6886 6887 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6888 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6889 if (pi.applicationInfo.uid == uid) { 6890 return true; 6891 } else if (!pi.exported) { 6892 return false; 6893 } 6894 6895 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6896 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6897 try { 6898 // check if target holds top-level <provider> permissions 6899 if (!readMet && pi.readPermission != null && considerUidPermissions 6900 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6901 readMet = true; 6902 } 6903 if (!writeMet && pi.writePermission != null && considerUidPermissions 6904 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6905 writeMet = true; 6906 } 6907 6908 // track if unprotected read/write is allowed; any denied 6909 // <path-permission> below removes this ability 6910 boolean allowDefaultRead = pi.readPermission == null; 6911 boolean allowDefaultWrite = pi.writePermission == null; 6912 6913 // check if target holds any <path-permission> that match uri 6914 final PathPermission[] pps = pi.pathPermissions; 6915 if (pps != null) { 6916 final String path = grantUri.uri.getPath(); 6917 int i = pps.length; 6918 while (i > 0 && (!readMet || !writeMet)) { 6919 i--; 6920 PathPermission pp = pps[i]; 6921 if (pp.match(path)) { 6922 if (!readMet) { 6923 final String pprperm = pp.getReadPermission(); 6924 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6925 + pprperm + " for " + pp.getPath() 6926 + ": match=" + pp.match(path) 6927 + " check=" + pm.checkUidPermission(pprperm, uid)); 6928 if (pprperm != null) { 6929 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6930 == PERMISSION_GRANTED) { 6931 readMet = true; 6932 } else { 6933 allowDefaultRead = false; 6934 } 6935 } 6936 } 6937 if (!writeMet) { 6938 final String ppwperm = pp.getWritePermission(); 6939 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6940 + ppwperm + " for " + pp.getPath() 6941 + ": match=" + pp.match(path) 6942 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6943 if (ppwperm != null) { 6944 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6945 == PERMISSION_GRANTED) { 6946 writeMet = true; 6947 } else { 6948 allowDefaultWrite = false; 6949 } 6950 } 6951 } 6952 } 6953 } 6954 } 6955 6956 // grant unprotected <provider> read/write, if not blocked by 6957 // <path-permission> above 6958 if (allowDefaultRead) readMet = true; 6959 if (allowDefaultWrite) writeMet = true; 6960 6961 } catch (RemoteException e) { 6962 return false; 6963 } 6964 6965 return readMet && writeMet; 6966 } 6967 6968 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6969 ProviderInfo pi = null; 6970 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6971 if (cpr != null) { 6972 pi = cpr.info; 6973 } else { 6974 try { 6975 pi = AppGlobals.getPackageManager().resolveContentProvider( 6976 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6977 } catch (RemoteException ex) { 6978 } 6979 } 6980 return pi; 6981 } 6982 6983 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6984 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6985 if (targetUris != null) { 6986 return targetUris.get(grantUri); 6987 } 6988 return null; 6989 } 6990 6991 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6992 String targetPkg, int targetUid, GrantUri grantUri) { 6993 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6994 if (targetUris == null) { 6995 targetUris = Maps.newArrayMap(); 6996 mGrantedUriPermissions.put(targetUid, targetUris); 6997 } 6998 6999 UriPermission perm = targetUris.get(grantUri); 7000 if (perm == null) { 7001 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7002 targetUris.put(grantUri, perm); 7003 } 7004 7005 return perm; 7006 } 7007 7008 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7009 final int modeFlags) { 7010 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7011 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7012 : UriPermission.STRENGTH_OWNED; 7013 7014 // Root gets to do everything. 7015 if (uid == 0) { 7016 return true; 7017 } 7018 7019 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7020 if (perms == null) return false; 7021 7022 // First look for exact match 7023 final UriPermission exactPerm = perms.get(grantUri); 7024 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7025 return true; 7026 } 7027 7028 // No exact match, look for prefixes 7029 final int N = perms.size(); 7030 for (int i = 0; i < N; i++) { 7031 final UriPermission perm = perms.valueAt(i); 7032 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7033 && perm.getStrength(modeFlags) >= minStrength) { 7034 return true; 7035 } 7036 } 7037 7038 return false; 7039 } 7040 7041 /** 7042 * @param uri This uri must NOT contain an embedded userId. 7043 * @param userId The userId in which the uri is to be resolved. 7044 */ 7045 @Override 7046 public int checkUriPermission(Uri uri, int pid, int uid, 7047 final int modeFlags, int userId, IBinder callerToken) { 7048 enforceNotIsolatedCaller("checkUriPermission"); 7049 7050 // Another redirected-binder-call permissions check as in 7051 // {@link checkPermissionWithToken}. 7052 Identity tlsIdentity = sCallerIdentity.get(); 7053 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7054 uid = tlsIdentity.uid; 7055 pid = tlsIdentity.pid; 7056 } 7057 7058 // Our own process gets to do everything. 7059 if (pid == MY_PID) { 7060 return PackageManager.PERMISSION_GRANTED; 7061 } 7062 synchronized (this) { 7063 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7064 ? PackageManager.PERMISSION_GRANTED 7065 : PackageManager.PERMISSION_DENIED; 7066 } 7067 } 7068 7069 /** 7070 * Check if the targetPkg can be granted permission to access uri by 7071 * the callingUid using the given modeFlags. Throws a security exception 7072 * if callingUid is not allowed to do this. Returns the uid of the target 7073 * if the URI permission grant should be performed; returns -1 if it is not 7074 * needed (for example targetPkg already has permission to access the URI). 7075 * If you already know the uid of the target, you can supply it in 7076 * lastTargetUid else set that to -1. 7077 */ 7078 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7079 final int modeFlags, int lastTargetUid) { 7080 if (!Intent.isAccessUriMode(modeFlags)) { 7081 return -1; 7082 } 7083 7084 if (targetPkg != null) { 7085 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7086 "Checking grant " + targetPkg + " permission to " + grantUri); 7087 } 7088 7089 final IPackageManager pm = AppGlobals.getPackageManager(); 7090 7091 // If this is not a content: uri, we can't do anything with it. 7092 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7093 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7094 "Can't grant URI permission for non-content URI: " + grantUri); 7095 return -1; 7096 } 7097 7098 final String authority = grantUri.uri.getAuthority(); 7099 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7100 if (pi == null) { 7101 Slog.w(TAG, "No content provider found for permission check: " + 7102 grantUri.uri.toSafeString()); 7103 return -1; 7104 } 7105 7106 int targetUid = lastTargetUid; 7107 if (targetUid < 0 && targetPkg != null) { 7108 try { 7109 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7110 if (targetUid < 0) { 7111 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7112 "Can't grant URI permission no uid for: " + targetPkg); 7113 return -1; 7114 } 7115 } catch (RemoteException ex) { 7116 return -1; 7117 } 7118 } 7119 7120 if (targetUid >= 0) { 7121 // First... does the target actually need this permission? 7122 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7123 // No need to grant the target this permission. 7124 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7125 "Target " + targetPkg + " already has full permission to " + grantUri); 7126 return -1; 7127 } 7128 } else { 7129 // First... there is no target package, so can anyone access it? 7130 boolean allowed = pi.exported; 7131 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7132 if (pi.readPermission != null) { 7133 allowed = false; 7134 } 7135 } 7136 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7137 if (pi.writePermission != null) { 7138 allowed = false; 7139 } 7140 } 7141 if (allowed) { 7142 return -1; 7143 } 7144 } 7145 7146 /* There is a special cross user grant if: 7147 * - The target is on another user. 7148 * - Apps on the current user can access the uri without any uid permissions. 7149 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7150 * grant uri permissions. 7151 */ 7152 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7153 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7154 modeFlags, false /*without considering the uid permissions*/); 7155 7156 // Second... is the provider allowing granting of URI permissions? 7157 if (!specialCrossUserGrant) { 7158 if (!pi.grantUriPermissions) { 7159 throw new SecurityException("Provider " + pi.packageName 7160 + "/" + pi.name 7161 + " does not allow granting of Uri permissions (uri " 7162 + grantUri + ")"); 7163 } 7164 if (pi.uriPermissionPatterns != null) { 7165 final int N = pi.uriPermissionPatterns.length; 7166 boolean allowed = false; 7167 for (int i=0; i<N; i++) { 7168 if (pi.uriPermissionPatterns[i] != null 7169 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7170 allowed = true; 7171 break; 7172 } 7173 } 7174 if (!allowed) { 7175 throw new SecurityException("Provider " + pi.packageName 7176 + "/" + pi.name 7177 + " does not allow granting of permission to path of Uri " 7178 + grantUri); 7179 } 7180 } 7181 } 7182 7183 // Third... does the caller itself have permission to access 7184 // this uri? 7185 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7186 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7187 // Require they hold a strong enough Uri permission 7188 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7189 throw new SecurityException("Uid " + callingUid 7190 + " does not have permission to uri " + grantUri); 7191 } 7192 } 7193 } 7194 return targetUid; 7195 } 7196 7197 /** 7198 * @param uri This uri must NOT contain an embedded userId. 7199 * @param userId The userId in which the uri is to be resolved. 7200 */ 7201 @Override 7202 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7203 final int modeFlags, int userId) { 7204 enforceNotIsolatedCaller("checkGrantUriPermission"); 7205 synchronized(this) { 7206 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7207 new GrantUri(userId, uri, false), modeFlags, -1); 7208 } 7209 } 7210 7211 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7212 final int modeFlags, UriPermissionOwner owner) { 7213 if (!Intent.isAccessUriMode(modeFlags)) { 7214 return; 7215 } 7216 7217 // So here we are: the caller has the assumed permission 7218 // to the uri, and the target doesn't. Let's now give this to 7219 // the target. 7220 7221 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7222 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7223 7224 final String authority = grantUri.uri.getAuthority(); 7225 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7226 if (pi == null) { 7227 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7228 return; 7229 } 7230 7231 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7232 grantUri.prefix = true; 7233 } 7234 final UriPermission perm = findOrCreateUriPermissionLocked( 7235 pi.packageName, targetPkg, targetUid, grantUri); 7236 perm.grantModes(modeFlags, owner); 7237 } 7238 7239 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7240 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7241 if (targetPkg == null) { 7242 throw new NullPointerException("targetPkg"); 7243 } 7244 int targetUid; 7245 final IPackageManager pm = AppGlobals.getPackageManager(); 7246 try { 7247 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7248 } catch (RemoteException ex) { 7249 return; 7250 } 7251 7252 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7253 targetUid); 7254 if (targetUid < 0) { 7255 return; 7256 } 7257 7258 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7259 owner); 7260 } 7261 7262 static class NeededUriGrants extends ArrayList<GrantUri> { 7263 final String targetPkg; 7264 final int targetUid; 7265 final int flags; 7266 7267 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7268 this.targetPkg = targetPkg; 7269 this.targetUid = targetUid; 7270 this.flags = flags; 7271 } 7272 } 7273 7274 /** 7275 * Like checkGrantUriPermissionLocked, but takes an Intent. 7276 */ 7277 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7278 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7279 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7280 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7281 + " clip=" + (intent != null ? intent.getClipData() : null) 7282 + " from " + intent + "; flags=0x" 7283 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7284 7285 if (targetPkg == null) { 7286 throw new NullPointerException("targetPkg"); 7287 } 7288 7289 if (intent == null) { 7290 return null; 7291 } 7292 Uri data = intent.getData(); 7293 ClipData clip = intent.getClipData(); 7294 if (data == null && clip == null) { 7295 return null; 7296 } 7297 // Default userId for uris in the intent (if they don't specify it themselves) 7298 int contentUserHint = intent.getContentUserHint(); 7299 if (contentUserHint == UserHandle.USER_CURRENT) { 7300 contentUserHint = UserHandle.getUserId(callingUid); 7301 } 7302 final IPackageManager pm = AppGlobals.getPackageManager(); 7303 int targetUid; 7304 if (needed != null) { 7305 targetUid = needed.targetUid; 7306 } else { 7307 try { 7308 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7309 } catch (RemoteException ex) { 7310 return null; 7311 } 7312 if (targetUid < 0) { 7313 if (DEBUG_URI_PERMISSION) { 7314 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7315 + " on user " + targetUserId); 7316 } 7317 return null; 7318 } 7319 } 7320 if (data != null) { 7321 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7322 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7323 targetUid); 7324 if (targetUid > 0) { 7325 if (needed == null) { 7326 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7327 } 7328 needed.add(grantUri); 7329 } 7330 } 7331 if (clip != null) { 7332 for (int i=0; i<clip.getItemCount(); i++) { 7333 Uri uri = clip.getItemAt(i).getUri(); 7334 if (uri != null) { 7335 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7336 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7337 targetUid); 7338 if (targetUid > 0) { 7339 if (needed == null) { 7340 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7341 } 7342 needed.add(grantUri); 7343 } 7344 } else { 7345 Intent clipIntent = clip.getItemAt(i).getIntent(); 7346 if (clipIntent != null) { 7347 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7348 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7349 if (newNeeded != null) { 7350 needed = newNeeded; 7351 } 7352 } 7353 } 7354 } 7355 } 7356 7357 return needed; 7358 } 7359 7360 /** 7361 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7362 */ 7363 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7364 UriPermissionOwner owner) { 7365 if (needed != null) { 7366 for (int i=0; i<needed.size(); i++) { 7367 GrantUri grantUri = needed.get(i); 7368 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7369 grantUri, needed.flags, owner); 7370 } 7371 } 7372 } 7373 7374 void grantUriPermissionFromIntentLocked(int callingUid, 7375 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7376 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7377 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7378 if (needed == null) { 7379 return; 7380 } 7381 7382 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7383 } 7384 7385 /** 7386 * @param uri This uri must NOT contain an embedded userId. 7387 * @param userId The userId in which the uri is to be resolved. 7388 */ 7389 @Override 7390 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7391 final int modeFlags, int userId) { 7392 enforceNotIsolatedCaller("grantUriPermission"); 7393 GrantUri grantUri = new GrantUri(userId, uri, false); 7394 synchronized(this) { 7395 final ProcessRecord r = getRecordForAppLocked(caller); 7396 if (r == null) { 7397 throw new SecurityException("Unable to find app for caller " 7398 + caller 7399 + " when granting permission to uri " + grantUri); 7400 } 7401 if (targetPkg == null) { 7402 throw new IllegalArgumentException("null target"); 7403 } 7404 if (grantUri == null) { 7405 throw new IllegalArgumentException("null uri"); 7406 } 7407 7408 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7409 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7410 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7411 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7412 7413 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7414 UserHandle.getUserId(r.uid)); 7415 } 7416 } 7417 7418 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7419 if (perm.modeFlags == 0) { 7420 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7421 perm.targetUid); 7422 if (perms != null) { 7423 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7424 "Removing " + perm.targetUid + " permission to " + perm.uri); 7425 7426 perms.remove(perm.uri); 7427 if (perms.isEmpty()) { 7428 mGrantedUriPermissions.remove(perm.targetUid); 7429 } 7430 } 7431 } 7432 } 7433 7434 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7435 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7436 7437 final IPackageManager pm = AppGlobals.getPackageManager(); 7438 final String authority = grantUri.uri.getAuthority(); 7439 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7440 if (pi == null) { 7441 Slog.w(TAG, "No content provider found for permission revoke: " 7442 + grantUri.toSafeString()); 7443 return; 7444 } 7445 7446 // Does the caller have this permission on the URI? 7447 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7448 // If they don't have direct access to the URI, then revoke any 7449 // ownerless URI permissions that have been granted to them. 7450 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7451 if (perms != null) { 7452 boolean persistChanged = false; 7453 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7454 final UriPermission perm = it.next(); 7455 if (perm.uri.sourceUserId == grantUri.sourceUserId 7456 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7457 if (DEBUG_URI_PERMISSION) 7458 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7459 " permission to " + perm.uri); 7460 persistChanged |= perm.revokeModes( 7461 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7462 if (perm.modeFlags == 0) { 7463 it.remove(); 7464 } 7465 } 7466 } 7467 if (perms.isEmpty()) { 7468 mGrantedUriPermissions.remove(callingUid); 7469 } 7470 if (persistChanged) { 7471 schedulePersistUriGrants(); 7472 } 7473 } 7474 return; 7475 } 7476 7477 boolean persistChanged = false; 7478 7479 // Go through all of the permissions and remove any that match. 7480 int N = mGrantedUriPermissions.size(); 7481 for (int i = 0; i < N; i++) { 7482 final int targetUid = mGrantedUriPermissions.keyAt(i); 7483 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7484 7485 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7486 final UriPermission perm = it.next(); 7487 if (perm.uri.sourceUserId == grantUri.sourceUserId 7488 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7489 if (DEBUG_URI_PERMISSION) 7490 Slog.v(TAG, 7491 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7492 persistChanged |= perm.revokeModes( 7493 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7494 if (perm.modeFlags == 0) { 7495 it.remove(); 7496 } 7497 } 7498 } 7499 7500 if (perms.isEmpty()) { 7501 mGrantedUriPermissions.remove(targetUid); 7502 N--; 7503 i--; 7504 } 7505 } 7506 7507 if (persistChanged) { 7508 schedulePersistUriGrants(); 7509 } 7510 } 7511 7512 /** 7513 * @param uri This uri must NOT contain an embedded userId. 7514 * @param userId The userId in which the uri is to be resolved. 7515 */ 7516 @Override 7517 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7518 int userId) { 7519 enforceNotIsolatedCaller("revokeUriPermission"); 7520 synchronized(this) { 7521 final ProcessRecord r = getRecordForAppLocked(caller); 7522 if (r == null) { 7523 throw new SecurityException("Unable to find app for caller " 7524 + caller 7525 + " when revoking permission to uri " + uri); 7526 } 7527 if (uri == null) { 7528 Slog.w(TAG, "revokeUriPermission: null uri"); 7529 return; 7530 } 7531 7532 if (!Intent.isAccessUriMode(modeFlags)) { 7533 return; 7534 } 7535 7536 final IPackageManager pm = AppGlobals.getPackageManager(); 7537 final String authority = uri.getAuthority(); 7538 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7539 if (pi == null) { 7540 Slog.w(TAG, "No content provider found for permission revoke: " 7541 + uri.toSafeString()); 7542 return; 7543 } 7544 7545 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7546 } 7547 } 7548 7549 /** 7550 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7551 * given package. 7552 * 7553 * @param packageName Package name to match, or {@code null} to apply to all 7554 * packages. 7555 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7556 * to all users. 7557 * @param persistable If persistable grants should be removed. 7558 */ 7559 private void removeUriPermissionsForPackageLocked( 7560 String packageName, int userHandle, boolean persistable) { 7561 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7562 throw new IllegalArgumentException("Must narrow by either package or user"); 7563 } 7564 7565 boolean persistChanged = false; 7566 7567 int N = mGrantedUriPermissions.size(); 7568 for (int i = 0; i < N; i++) { 7569 final int targetUid = mGrantedUriPermissions.keyAt(i); 7570 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7571 7572 // Only inspect grants matching user 7573 if (userHandle == UserHandle.USER_ALL 7574 || userHandle == UserHandle.getUserId(targetUid)) { 7575 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7576 final UriPermission perm = it.next(); 7577 7578 // Only inspect grants matching package 7579 if (packageName == null || perm.sourcePkg.equals(packageName) 7580 || perm.targetPkg.equals(packageName)) { 7581 persistChanged |= perm.revokeModes(persistable 7582 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7583 7584 // Only remove when no modes remain; any persisted grants 7585 // will keep this alive. 7586 if (perm.modeFlags == 0) { 7587 it.remove(); 7588 } 7589 } 7590 } 7591 7592 if (perms.isEmpty()) { 7593 mGrantedUriPermissions.remove(targetUid); 7594 N--; 7595 i--; 7596 } 7597 } 7598 } 7599 7600 if (persistChanged) { 7601 schedulePersistUriGrants(); 7602 } 7603 } 7604 7605 @Override 7606 public IBinder newUriPermissionOwner(String name) { 7607 enforceNotIsolatedCaller("newUriPermissionOwner"); 7608 synchronized(this) { 7609 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7610 return owner.getExternalTokenLocked(); 7611 } 7612 } 7613 7614 /** 7615 * @param uri This uri must NOT contain an embedded userId. 7616 * @param sourceUserId The userId in which the uri is to be resolved. 7617 * @param targetUserId The userId of the app that receives the grant. 7618 */ 7619 @Override 7620 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7621 final int modeFlags, int sourceUserId, int targetUserId) { 7622 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7623 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7624 synchronized(this) { 7625 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7626 if (owner == null) { 7627 throw new IllegalArgumentException("Unknown owner: " + token); 7628 } 7629 if (fromUid != Binder.getCallingUid()) { 7630 if (Binder.getCallingUid() != Process.myUid()) { 7631 // Only system code can grant URI permissions on behalf 7632 // of other users. 7633 throw new SecurityException("nice try"); 7634 } 7635 } 7636 if (targetPkg == null) { 7637 throw new IllegalArgumentException("null target"); 7638 } 7639 if (uri == null) { 7640 throw new IllegalArgumentException("null uri"); 7641 } 7642 7643 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7644 modeFlags, owner, targetUserId); 7645 } 7646 } 7647 7648 /** 7649 * @param uri This uri must NOT contain an embedded userId. 7650 * @param userId The userId in which the uri is to be resolved. 7651 */ 7652 @Override 7653 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7654 synchronized(this) { 7655 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7656 if (owner == null) { 7657 throw new IllegalArgumentException("Unknown owner: " + token); 7658 } 7659 7660 if (uri == null) { 7661 owner.removeUriPermissionsLocked(mode); 7662 } else { 7663 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7664 } 7665 } 7666 } 7667 7668 private void schedulePersistUriGrants() { 7669 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7670 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7671 10 * DateUtils.SECOND_IN_MILLIS); 7672 } 7673 } 7674 7675 private void writeGrantedUriPermissions() { 7676 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7677 7678 // Snapshot permissions so we can persist without lock 7679 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7680 synchronized (this) { 7681 final int size = mGrantedUriPermissions.size(); 7682 for (int i = 0; i < size; i++) { 7683 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7684 for (UriPermission perm : perms.values()) { 7685 if (perm.persistedModeFlags != 0) { 7686 persist.add(perm.snapshot()); 7687 } 7688 } 7689 } 7690 } 7691 7692 FileOutputStream fos = null; 7693 try { 7694 fos = mGrantFile.startWrite(); 7695 7696 XmlSerializer out = new FastXmlSerializer(); 7697 out.setOutput(fos, "utf-8"); 7698 out.startDocument(null, true); 7699 out.startTag(null, TAG_URI_GRANTS); 7700 for (UriPermission.Snapshot perm : persist) { 7701 out.startTag(null, TAG_URI_GRANT); 7702 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7703 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7704 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7705 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7706 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7707 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7708 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7709 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7710 out.endTag(null, TAG_URI_GRANT); 7711 } 7712 out.endTag(null, TAG_URI_GRANTS); 7713 out.endDocument(); 7714 7715 mGrantFile.finishWrite(fos); 7716 } catch (IOException e) { 7717 if (fos != null) { 7718 mGrantFile.failWrite(fos); 7719 } 7720 } 7721 } 7722 7723 private void readGrantedUriPermissionsLocked() { 7724 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7725 7726 final long now = System.currentTimeMillis(); 7727 7728 FileInputStream fis = null; 7729 try { 7730 fis = mGrantFile.openRead(); 7731 final XmlPullParser in = Xml.newPullParser(); 7732 in.setInput(fis, null); 7733 7734 int type; 7735 while ((type = in.next()) != END_DOCUMENT) { 7736 final String tag = in.getName(); 7737 if (type == START_TAG) { 7738 if (TAG_URI_GRANT.equals(tag)) { 7739 final int sourceUserId; 7740 final int targetUserId; 7741 final int userHandle = readIntAttribute(in, 7742 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7743 if (userHandle != UserHandle.USER_NULL) { 7744 // For backwards compatibility. 7745 sourceUserId = userHandle; 7746 targetUserId = userHandle; 7747 } else { 7748 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7749 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7750 } 7751 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7752 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7753 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7754 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7755 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7756 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7757 7758 // Sanity check that provider still belongs to source package 7759 final ProviderInfo pi = getProviderInfoLocked( 7760 uri.getAuthority(), sourceUserId); 7761 if (pi != null && sourcePkg.equals(pi.packageName)) { 7762 int targetUid = -1; 7763 try { 7764 targetUid = AppGlobals.getPackageManager() 7765 .getPackageUid(targetPkg, targetUserId); 7766 } catch (RemoteException e) { 7767 } 7768 if (targetUid != -1) { 7769 final UriPermission perm = findOrCreateUriPermissionLocked( 7770 sourcePkg, targetPkg, targetUid, 7771 new GrantUri(sourceUserId, uri, prefix)); 7772 perm.initPersistedModes(modeFlags, createdTime); 7773 } 7774 } else { 7775 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7776 + " but instead found " + pi); 7777 } 7778 } 7779 } 7780 } 7781 } catch (FileNotFoundException e) { 7782 // Missing grants is okay 7783 } catch (IOException e) { 7784 Slog.wtf(TAG, "Failed reading Uri grants", e); 7785 } catch (XmlPullParserException e) { 7786 Slog.wtf(TAG, "Failed reading Uri grants", e); 7787 } finally { 7788 IoUtils.closeQuietly(fis); 7789 } 7790 } 7791 7792 /** 7793 * @param uri This uri must NOT contain an embedded userId. 7794 * @param userId The userId in which the uri is to be resolved. 7795 */ 7796 @Override 7797 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7798 enforceNotIsolatedCaller("takePersistableUriPermission"); 7799 7800 Preconditions.checkFlagsArgument(modeFlags, 7801 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7802 7803 synchronized (this) { 7804 final int callingUid = Binder.getCallingUid(); 7805 boolean persistChanged = false; 7806 GrantUri grantUri = new GrantUri(userId, uri, false); 7807 7808 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7809 new GrantUri(userId, uri, false)); 7810 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7811 new GrantUri(userId, uri, true)); 7812 7813 final boolean exactValid = (exactPerm != null) 7814 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7815 final boolean prefixValid = (prefixPerm != null) 7816 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7817 7818 if (!(exactValid || prefixValid)) { 7819 throw new SecurityException("No persistable permission grants found for UID " 7820 + callingUid + " and Uri " + grantUri.toSafeString()); 7821 } 7822 7823 if (exactValid) { 7824 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7825 } 7826 if (prefixValid) { 7827 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7828 } 7829 7830 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7831 7832 if (persistChanged) { 7833 schedulePersistUriGrants(); 7834 } 7835 } 7836 } 7837 7838 /** 7839 * @param uri This uri must NOT contain an embedded userId. 7840 * @param userId The userId in which the uri is to be resolved. 7841 */ 7842 @Override 7843 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7844 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7845 7846 Preconditions.checkFlagsArgument(modeFlags, 7847 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7848 7849 synchronized (this) { 7850 final int callingUid = Binder.getCallingUid(); 7851 boolean persistChanged = false; 7852 7853 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7854 new GrantUri(userId, uri, false)); 7855 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7856 new GrantUri(userId, uri, true)); 7857 if (exactPerm == null && prefixPerm == null) { 7858 throw new SecurityException("No permission grants found for UID " + callingUid 7859 + " and Uri " + uri.toSafeString()); 7860 } 7861 7862 if (exactPerm != null) { 7863 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7864 removeUriPermissionIfNeededLocked(exactPerm); 7865 } 7866 if (prefixPerm != null) { 7867 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7868 removeUriPermissionIfNeededLocked(prefixPerm); 7869 } 7870 7871 if (persistChanged) { 7872 schedulePersistUriGrants(); 7873 } 7874 } 7875 } 7876 7877 /** 7878 * Prune any older {@link UriPermission} for the given UID until outstanding 7879 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7880 * 7881 * @return if any mutations occured that require persisting. 7882 */ 7883 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7884 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7885 if (perms == null) return false; 7886 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7887 7888 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7889 for (UriPermission perm : perms.values()) { 7890 if (perm.persistedModeFlags != 0) { 7891 persisted.add(perm); 7892 } 7893 } 7894 7895 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7896 if (trimCount <= 0) return false; 7897 7898 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7899 for (int i = 0; i < trimCount; i++) { 7900 final UriPermission perm = persisted.get(i); 7901 7902 if (DEBUG_URI_PERMISSION) { 7903 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7904 } 7905 7906 perm.releasePersistableModes(~0); 7907 removeUriPermissionIfNeededLocked(perm); 7908 } 7909 7910 return true; 7911 } 7912 7913 @Override 7914 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7915 String packageName, boolean incoming) { 7916 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7917 Preconditions.checkNotNull(packageName, "packageName"); 7918 7919 final int callingUid = Binder.getCallingUid(); 7920 final IPackageManager pm = AppGlobals.getPackageManager(); 7921 try { 7922 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7923 if (packageUid != callingUid) { 7924 throw new SecurityException( 7925 "Package " + packageName + " does not belong to calling UID " + callingUid); 7926 } 7927 } catch (RemoteException e) { 7928 throw new SecurityException("Failed to verify package name ownership"); 7929 } 7930 7931 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7932 synchronized (this) { 7933 if (incoming) { 7934 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7935 callingUid); 7936 if (perms == null) { 7937 Slog.w(TAG, "No permission grants found for " + packageName); 7938 } else { 7939 for (UriPermission perm : perms.values()) { 7940 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7941 result.add(perm.buildPersistedPublicApiObject()); 7942 } 7943 } 7944 } 7945 } else { 7946 final int size = mGrantedUriPermissions.size(); 7947 for (int i = 0; i < size; i++) { 7948 final ArrayMap<GrantUri, UriPermission> perms = 7949 mGrantedUriPermissions.valueAt(i); 7950 for (UriPermission perm : perms.values()) { 7951 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7952 result.add(perm.buildPersistedPublicApiObject()); 7953 } 7954 } 7955 } 7956 } 7957 } 7958 return new ParceledListSlice<android.content.UriPermission>(result); 7959 } 7960 7961 @Override 7962 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7963 synchronized (this) { 7964 ProcessRecord app = 7965 who != null ? getRecordForAppLocked(who) : null; 7966 if (app == null) return; 7967 7968 Message msg = Message.obtain(); 7969 msg.what = WAIT_FOR_DEBUGGER_MSG; 7970 msg.obj = app; 7971 msg.arg1 = waiting ? 1 : 0; 7972 mHandler.sendMessage(msg); 7973 } 7974 } 7975 7976 @Override 7977 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7978 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7979 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7980 outInfo.availMem = Process.getFreeMemory(); 7981 outInfo.totalMem = Process.getTotalMemory(); 7982 outInfo.threshold = homeAppMem; 7983 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7984 outInfo.hiddenAppThreshold = cachedAppMem; 7985 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7986 ProcessList.SERVICE_ADJ); 7987 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7988 ProcessList.VISIBLE_APP_ADJ); 7989 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7990 ProcessList.FOREGROUND_APP_ADJ); 7991 } 7992 7993 // ========================================================= 7994 // TASK MANAGEMENT 7995 // ========================================================= 7996 7997 @Override 7998 public List<IAppTask> getAppTasks(String callingPackage) { 7999 int callingUid = Binder.getCallingUid(); 8000 long ident = Binder.clearCallingIdentity(); 8001 8002 synchronized(this) { 8003 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8004 try { 8005 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8006 8007 final int N = mRecentTasks.size(); 8008 for (int i = 0; i < N; i++) { 8009 TaskRecord tr = mRecentTasks.get(i); 8010 // Skip tasks that do not match the caller. We don't need to verify 8011 // callingPackage, because we are also limiting to callingUid and know 8012 // that will limit to the correct security sandbox. 8013 if (tr.effectiveUid != callingUid) { 8014 continue; 8015 } 8016 Intent intent = tr.getBaseIntent(); 8017 if (intent == null || 8018 !callingPackage.equals(intent.getComponent().getPackageName())) { 8019 continue; 8020 } 8021 ActivityManager.RecentTaskInfo taskInfo = 8022 createRecentTaskInfoFromTaskRecord(tr); 8023 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8024 list.add(taskImpl); 8025 } 8026 } finally { 8027 Binder.restoreCallingIdentity(ident); 8028 } 8029 return list; 8030 } 8031 } 8032 8033 @Override 8034 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8035 final int callingUid = Binder.getCallingUid(); 8036 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8037 8038 synchronized(this) { 8039 if (localLOGV) Slog.v( 8040 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8041 8042 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8043 callingUid); 8044 8045 // TODO: Improve with MRU list from all ActivityStacks. 8046 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8047 } 8048 8049 return list; 8050 } 8051 8052 /** 8053 * Creates a new RecentTaskInfo from a TaskRecord. 8054 */ 8055 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8056 // Update the task description to reflect any changes in the task stack 8057 tr.updateTaskDescription(); 8058 8059 // Compose the recent task info 8060 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8061 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8062 rti.persistentId = tr.taskId; 8063 rti.baseIntent = new Intent(tr.getBaseIntent()); 8064 rti.origActivity = tr.origActivity; 8065 rti.description = tr.lastDescription; 8066 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8067 rti.userId = tr.userId; 8068 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8069 rti.firstActiveTime = tr.firstActiveTime; 8070 rti.lastActiveTime = tr.lastActiveTime; 8071 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8072 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8073 return rti; 8074 } 8075 8076 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8077 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8078 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8079 if (!allowed) { 8080 if (checkPermission(android.Manifest.permission.GET_TASKS, 8081 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8082 // Temporary compatibility: some existing apps on the system image may 8083 // still be requesting the old permission and not switched to the new 8084 // one; if so, we'll still allow them full access. This means we need 8085 // to see if they are holding the old permission and are a system app. 8086 try { 8087 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8088 allowed = true; 8089 Slog.w(TAG, caller + ": caller " + callingUid 8090 + " is using old GET_TASKS but privileged; allowing"); 8091 } 8092 } catch (RemoteException e) { 8093 } 8094 } 8095 } 8096 if (!allowed) { 8097 Slog.w(TAG, caller + ": caller " + callingUid 8098 + " does not hold GET_TASKS; limiting output"); 8099 } 8100 return allowed; 8101 } 8102 8103 @Override 8104 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8105 final int callingUid = Binder.getCallingUid(); 8106 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8107 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8108 8109 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8110 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8111 synchronized (this) { 8112 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8113 callingUid); 8114 final boolean detailed = checkCallingPermission( 8115 android.Manifest.permission.GET_DETAILED_TASKS) 8116 == PackageManager.PERMISSION_GRANTED; 8117 8118 final int N = mRecentTasks.size(); 8119 ArrayList<ActivityManager.RecentTaskInfo> res 8120 = new ArrayList<ActivityManager.RecentTaskInfo>( 8121 maxNum < N ? maxNum : N); 8122 8123 final Set<Integer> includedUsers; 8124 if (includeProfiles) { 8125 includedUsers = getProfileIdsLocked(userId); 8126 } else { 8127 includedUsers = new HashSet<Integer>(); 8128 } 8129 includedUsers.add(Integer.valueOf(userId)); 8130 8131 for (int i=0; i<N && maxNum > 0; i++) { 8132 TaskRecord tr = mRecentTasks.get(i); 8133 // Only add calling user or related users recent tasks 8134 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8135 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8136 continue; 8137 } 8138 8139 // Return the entry if desired by the caller. We always return 8140 // the first entry, because callers always expect this to be the 8141 // foreground app. We may filter others if the caller has 8142 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8143 // we should exclude the entry. 8144 8145 if (i == 0 8146 || withExcluded 8147 || (tr.intent == null) 8148 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8149 == 0)) { 8150 if (!allowed) { 8151 // If the caller doesn't have the GET_TASKS permission, then only 8152 // allow them to see a small subset of tasks -- their own and home. 8153 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8154 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8155 continue; 8156 } 8157 } 8158 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8159 if (tr.stack != null && tr.stack.isHomeStack()) { 8160 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8161 continue; 8162 } 8163 } 8164 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8165 // Don't include auto remove tasks that are finished or finishing. 8166 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8167 + tr); 8168 continue; 8169 } 8170 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8171 && !tr.isAvailable) { 8172 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8173 continue; 8174 } 8175 8176 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8177 if (!detailed) { 8178 rti.baseIntent.replaceExtras((Bundle)null); 8179 } 8180 8181 res.add(rti); 8182 maxNum--; 8183 } 8184 } 8185 return res; 8186 } 8187 } 8188 8189 TaskRecord recentTaskForIdLocked(int id) { 8190 final int N = mRecentTasks.size(); 8191 for (int i=0; i<N; i++) { 8192 TaskRecord tr = mRecentTasks.get(i); 8193 if (tr.taskId == id) { 8194 return tr; 8195 } 8196 } 8197 return null; 8198 } 8199 8200 @Override 8201 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8202 synchronized (this) { 8203 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8204 "getTaskThumbnail()"); 8205 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8206 if (tr != null) { 8207 return tr.getTaskThumbnailLocked(); 8208 } 8209 } 8210 return null; 8211 } 8212 8213 @Override 8214 public int addAppTask(IBinder activityToken, Intent intent, 8215 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8216 final int callingUid = Binder.getCallingUid(); 8217 final long callingIdent = Binder.clearCallingIdentity(); 8218 8219 try { 8220 synchronized (this) { 8221 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8222 if (r == null) { 8223 throw new IllegalArgumentException("Activity does not exist; token=" 8224 + activityToken); 8225 } 8226 ComponentName comp = intent.getComponent(); 8227 if (comp == null) { 8228 throw new IllegalArgumentException("Intent " + intent 8229 + " must specify explicit component"); 8230 } 8231 if (thumbnail.getWidth() != mThumbnailWidth 8232 || thumbnail.getHeight() != mThumbnailHeight) { 8233 throw new IllegalArgumentException("Bad thumbnail size: got " 8234 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8235 + mThumbnailWidth + "x" + mThumbnailHeight); 8236 } 8237 if (intent.getSelector() != null) { 8238 intent.setSelector(null); 8239 } 8240 if (intent.getSourceBounds() != null) { 8241 intent.setSourceBounds(null); 8242 } 8243 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8244 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8245 // The caller has added this as an auto-remove task... that makes no 8246 // sense, so turn off auto-remove. 8247 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8248 } 8249 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8250 // Must be a new task. 8251 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8252 } 8253 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8254 mLastAddedTaskActivity = null; 8255 } 8256 ActivityInfo ainfo = mLastAddedTaskActivity; 8257 if (ainfo == null) { 8258 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8259 comp, 0, UserHandle.getUserId(callingUid)); 8260 if (ainfo.applicationInfo.uid != callingUid) { 8261 throw new SecurityException( 8262 "Can't add task for another application: target uid=" 8263 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8264 } 8265 } 8266 8267 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8268 intent, description); 8269 8270 int trimIdx = trimRecentsForTaskLocked(task, false); 8271 if (trimIdx >= 0) { 8272 // If this would have caused a trim, then we'll abort because that 8273 // means it would be added at the end of the list but then just removed. 8274 return INVALID_TASK_ID; 8275 } 8276 8277 final int N = mRecentTasks.size(); 8278 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8279 final TaskRecord tr = mRecentTasks.remove(N - 1); 8280 tr.removedFromRecents(); 8281 } 8282 8283 task.inRecents = true; 8284 mRecentTasks.add(task); 8285 r.task.stack.addTask(task, false, false); 8286 8287 task.setLastThumbnail(thumbnail); 8288 task.freeLastThumbnail(); 8289 8290 return task.taskId; 8291 } 8292 } finally { 8293 Binder.restoreCallingIdentity(callingIdent); 8294 } 8295 } 8296 8297 @Override 8298 public Point getAppTaskThumbnailSize() { 8299 synchronized (this) { 8300 return new Point(mThumbnailWidth, mThumbnailHeight); 8301 } 8302 } 8303 8304 @Override 8305 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8306 synchronized (this) { 8307 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8308 if (r != null) { 8309 r.setTaskDescription(td); 8310 r.task.updateTaskDescription(); 8311 } 8312 } 8313 } 8314 8315 @Override 8316 public Bitmap getTaskDescriptionIcon(String filename) { 8317 if (!FileUtils.isValidExtFilename(filename) 8318 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8319 throw new IllegalArgumentException("Bad filename: " + filename); 8320 } 8321 return mTaskPersister.getTaskDescriptionIcon(filename); 8322 } 8323 8324 @Override 8325 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8326 throws RemoteException { 8327 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8328 opts.getCustomInPlaceResId() == 0) { 8329 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8330 "with valid animation"); 8331 } 8332 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8333 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8334 opts.getCustomInPlaceResId()); 8335 mWindowManager.executeAppTransition(); 8336 } 8337 8338 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8339 mRecentTasks.remove(tr); 8340 tr.removedFromRecents(); 8341 ComponentName component = tr.getBaseIntent().getComponent(); 8342 if (component == null) { 8343 Slog.w(TAG, "No component for base intent of task: " + tr); 8344 return; 8345 } 8346 8347 if (!killProcess) { 8348 return; 8349 } 8350 8351 // Determine if the process(es) for this task should be killed. 8352 final String pkg = component.getPackageName(); 8353 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8354 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8355 for (int i = 0; i < pmap.size(); i++) { 8356 8357 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8358 for (int j = 0; j < uids.size(); j++) { 8359 ProcessRecord proc = uids.valueAt(j); 8360 if (proc.userId != tr.userId) { 8361 // Don't kill process for a different user. 8362 continue; 8363 } 8364 if (proc == mHomeProcess) { 8365 // Don't kill the home process along with tasks from the same package. 8366 continue; 8367 } 8368 if (!proc.pkgList.containsKey(pkg)) { 8369 // Don't kill process that is not associated with this task. 8370 continue; 8371 } 8372 8373 for (int k = 0; k < proc.activities.size(); k++) { 8374 TaskRecord otherTask = proc.activities.get(k).task; 8375 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8376 // Don't kill process(es) that has an activity in a different task that is 8377 // also in recents. 8378 return; 8379 } 8380 } 8381 8382 // Add process to kill list. 8383 procsToKill.add(proc); 8384 } 8385 } 8386 8387 // Find any running services associated with this app and stop if needed. 8388 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8389 8390 // Kill the running processes. 8391 for (int i = 0; i < procsToKill.size(); i++) { 8392 ProcessRecord pr = procsToKill.get(i); 8393 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8394 pr.kill("remove task", true); 8395 } else { 8396 pr.waitingToKill = "remove task"; 8397 } 8398 } 8399 } 8400 8401 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8402 // Remove all tasks with activities in the specified package from the list of recent tasks 8403 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8404 TaskRecord tr = mRecentTasks.get(i); 8405 if (tr.userId != userId) continue; 8406 8407 ComponentName cn = tr.intent.getComponent(); 8408 if (cn != null && cn.getPackageName().equals(packageName)) { 8409 // If the package name matches, remove the task. 8410 removeTaskByIdLocked(tr.taskId, true); 8411 } 8412 } 8413 } 8414 8415 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8416 final IPackageManager pm = AppGlobals.getPackageManager(); 8417 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8418 8419 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8420 TaskRecord tr = mRecentTasks.get(i); 8421 if (tr.userId != userId) continue; 8422 8423 ComponentName cn = tr.intent.getComponent(); 8424 if (cn != null && cn.getPackageName().equals(packageName)) { 8425 // Skip if component still exists in the package. 8426 if (componentsKnownToExist.contains(cn)) continue; 8427 8428 try { 8429 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8430 if (info != null) { 8431 componentsKnownToExist.add(cn); 8432 } else { 8433 removeTaskByIdLocked(tr.taskId, false); 8434 } 8435 } catch (RemoteException e) { 8436 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8437 } 8438 } 8439 } 8440 } 8441 8442 /** 8443 * Removes the task with the specified task id. 8444 * 8445 * @param taskId Identifier of the task to be removed. 8446 * @param killProcess Kill any process associated with the task if possible. 8447 * @return Returns true if the given task was found and removed. 8448 */ 8449 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8450 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8451 if (tr != null) { 8452 tr.removeTaskActivitiesLocked(); 8453 cleanUpRemovedTaskLocked(tr, killProcess); 8454 if (tr.isPersistable) { 8455 notifyTaskPersisterLocked(null, true); 8456 } 8457 return true; 8458 } 8459 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8460 return false; 8461 } 8462 8463 @Override 8464 public boolean removeTask(int taskId) { 8465 synchronized (this) { 8466 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8467 "removeTask()"); 8468 long ident = Binder.clearCallingIdentity(); 8469 try { 8470 return removeTaskByIdLocked(taskId, true); 8471 } finally { 8472 Binder.restoreCallingIdentity(ident); 8473 } 8474 } 8475 } 8476 8477 /** 8478 * TODO: Add mController hook 8479 */ 8480 @Override 8481 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8482 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8483 "moveTaskToFront()"); 8484 8485 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8486 synchronized(this) { 8487 moveTaskToFrontLocked(taskId, flags, options); 8488 } 8489 } 8490 8491 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8492 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8493 Binder.getCallingUid(), -1, -1, "Task to front")) { 8494 ActivityOptions.abort(options); 8495 return; 8496 } 8497 final long origId = Binder.clearCallingIdentity(); 8498 try { 8499 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8500 if (task == null) { 8501 Slog.d(TAG, "Could not find task for id: "+ taskId); 8502 return; 8503 } 8504 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8505 mStackSupervisor.showLockTaskToast(); 8506 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8507 return; 8508 } 8509 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8510 if (prev != null && prev.isRecentsActivity()) { 8511 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8512 } 8513 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8514 } finally { 8515 Binder.restoreCallingIdentity(origId); 8516 } 8517 ActivityOptions.abort(options); 8518 } 8519 8520 @Override 8521 public void moveTaskToBack(int taskId) { 8522 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8523 "moveTaskToBack()"); 8524 8525 synchronized(this) { 8526 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8527 if (tr != null) { 8528 if (tr == mStackSupervisor.mLockTaskModeTask) { 8529 mStackSupervisor.showLockTaskToast(); 8530 return; 8531 } 8532 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8533 ActivityStack stack = tr.stack; 8534 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8535 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8536 Binder.getCallingUid(), -1, -1, "Task to back")) { 8537 return; 8538 } 8539 } 8540 final long origId = Binder.clearCallingIdentity(); 8541 try { 8542 stack.moveTaskToBackLocked(taskId, null); 8543 } finally { 8544 Binder.restoreCallingIdentity(origId); 8545 } 8546 } 8547 } 8548 } 8549 8550 /** 8551 * Moves an activity, and all of the other activities within the same task, to the bottom 8552 * of the history stack. The activity's order within the task is unchanged. 8553 * 8554 * @param token A reference to the activity we wish to move 8555 * @param nonRoot If false then this only works if the activity is the root 8556 * of a task; if true it will work for any activity in a task. 8557 * @return Returns true if the move completed, false if not. 8558 */ 8559 @Override 8560 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8561 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8562 synchronized(this) { 8563 final long origId = Binder.clearCallingIdentity(); 8564 try { 8565 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8566 if (taskId >= 0) { 8567 if ((mStackSupervisor.mLockTaskModeTask != null) 8568 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8569 mStackSupervisor.showLockTaskToast(); 8570 return false; 8571 } 8572 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8573 } 8574 } finally { 8575 Binder.restoreCallingIdentity(origId); 8576 } 8577 } 8578 return false; 8579 } 8580 8581 @Override 8582 public void moveTaskBackwards(int task) { 8583 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8584 "moveTaskBackwards()"); 8585 8586 synchronized(this) { 8587 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8588 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8589 return; 8590 } 8591 final long origId = Binder.clearCallingIdentity(); 8592 moveTaskBackwardsLocked(task); 8593 Binder.restoreCallingIdentity(origId); 8594 } 8595 } 8596 8597 private final void moveTaskBackwardsLocked(int task) { 8598 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8599 } 8600 8601 @Override 8602 public IBinder getHomeActivityToken() throws RemoteException { 8603 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8604 "getHomeActivityToken()"); 8605 synchronized (this) { 8606 return mStackSupervisor.getHomeActivityToken(); 8607 } 8608 } 8609 8610 @Override 8611 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8612 IActivityContainerCallback callback) throws RemoteException { 8613 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8614 "createActivityContainer()"); 8615 synchronized (this) { 8616 if (parentActivityToken == null) { 8617 throw new IllegalArgumentException("parent token must not be null"); 8618 } 8619 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8620 if (r == null) { 8621 return null; 8622 } 8623 if (callback == null) { 8624 throw new IllegalArgumentException("callback must not be null"); 8625 } 8626 return mStackSupervisor.createActivityContainer(r, callback); 8627 } 8628 } 8629 8630 @Override 8631 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8632 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8633 "deleteActivityContainer()"); 8634 synchronized (this) { 8635 mStackSupervisor.deleteActivityContainer(container); 8636 } 8637 } 8638 8639 @Override 8640 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8641 throws RemoteException { 8642 synchronized (this) { 8643 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8644 if (stack != null) { 8645 return stack.mActivityContainer; 8646 } 8647 return null; 8648 } 8649 } 8650 8651 @Override 8652 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8653 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8654 "moveTaskToStack()"); 8655 if (stackId == HOME_STACK_ID) { 8656 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8657 new RuntimeException("here").fillInStackTrace()); 8658 } 8659 synchronized (this) { 8660 long ident = Binder.clearCallingIdentity(); 8661 try { 8662 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8663 + stackId + " toTop=" + toTop); 8664 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8665 } finally { 8666 Binder.restoreCallingIdentity(ident); 8667 } 8668 } 8669 } 8670 8671 @Override 8672 public void resizeStack(int stackBoxId, Rect bounds) { 8673 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8674 "resizeStackBox()"); 8675 long ident = Binder.clearCallingIdentity(); 8676 try { 8677 mWindowManager.resizeStack(stackBoxId, bounds); 8678 } finally { 8679 Binder.restoreCallingIdentity(ident); 8680 } 8681 } 8682 8683 @Override 8684 public List<StackInfo> getAllStackInfos() { 8685 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8686 "getAllStackInfos()"); 8687 long ident = Binder.clearCallingIdentity(); 8688 try { 8689 synchronized (this) { 8690 return mStackSupervisor.getAllStackInfosLocked(); 8691 } 8692 } finally { 8693 Binder.restoreCallingIdentity(ident); 8694 } 8695 } 8696 8697 @Override 8698 public StackInfo getStackInfo(int stackId) { 8699 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8700 "getStackInfo()"); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 synchronized (this) { 8704 return mStackSupervisor.getStackInfoLocked(stackId); 8705 } 8706 } finally { 8707 Binder.restoreCallingIdentity(ident); 8708 } 8709 } 8710 8711 @Override 8712 public boolean isInHomeStack(int taskId) { 8713 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8714 "getStackInfo()"); 8715 long ident = Binder.clearCallingIdentity(); 8716 try { 8717 synchronized (this) { 8718 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8719 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8720 } 8721 } finally { 8722 Binder.restoreCallingIdentity(ident); 8723 } 8724 } 8725 8726 @Override 8727 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8728 synchronized(this) { 8729 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8730 } 8731 } 8732 8733 private boolean isLockTaskAuthorized(String pkg) { 8734 final DevicePolicyManager dpm = (DevicePolicyManager) 8735 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8736 try { 8737 int uid = mContext.getPackageManager().getPackageUid(pkg, 8738 Binder.getCallingUserHandle().getIdentifier()); 8739 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8740 } catch (NameNotFoundException e) { 8741 return false; 8742 } 8743 } 8744 8745 void startLockTaskMode(TaskRecord task) { 8746 final String pkg; 8747 synchronized (this) { 8748 pkg = task.intent.getComponent().getPackageName(); 8749 } 8750 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8751 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8752 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8753 StatusBarManagerInternal.class); 8754 if (statusBarManager != null) { 8755 statusBarManager.showScreenPinningRequest(); 8756 } 8757 return; 8758 } 8759 long ident = Binder.clearCallingIdentity(); 8760 try { 8761 synchronized (this) { 8762 // Since we lost lock on task, make sure it is still there. 8763 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8764 if (task != null) { 8765 if (!isSystemInitiated 8766 && ((mStackSupervisor.getFocusedStack() == null) 8767 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8768 throw new IllegalArgumentException("Invalid task, not in foreground"); 8769 } 8770 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8771 } 8772 } 8773 } finally { 8774 Binder.restoreCallingIdentity(ident); 8775 } 8776 } 8777 8778 @Override 8779 public void startLockTaskMode(int taskId) { 8780 final TaskRecord task; 8781 long ident = Binder.clearCallingIdentity(); 8782 try { 8783 synchronized (this) { 8784 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8785 } 8786 } finally { 8787 Binder.restoreCallingIdentity(ident); 8788 } 8789 if (task != null) { 8790 startLockTaskMode(task); 8791 } 8792 } 8793 8794 @Override 8795 public void startLockTaskMode(IBinder token) { 8796 final TaskRecord task; 8797 long ident = Binder.clearCallingIdentity(); 8798 try { 8799 synchronized (this) { 8800 final ActivityRecord r = ActivityRecord.forToken(token); 8801 if (r == null) { 8802 return; 8803 } 8804 task = r.task; 8805 } 8806 } finally { 8807 Binder.restoreCallingIdentity(ident); 8808 } 8809 if (task != null) { 8810 startLockTaskMode(task); 8811 } 8812 } 8813 8814 @Override 8815 public void startLockTaskModeOnCurrent() throws RemoteException { 8816 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8817 "startLockTaskModeOnCurrent"); 8818 long ident = Binder.clearCallingIdentity(); 8819 try { 8820 ActivityRecord r = null; 8821 synchronized (this) { 8822 r = mStackSupervisor.topRunningActivityLocked(); 8823 } 8824 startLockTaskMode(r.task); 8825 } finally { 8826 Binder.restoreCallingIdentity(ident); 8827 } 8828 } 8829 8830 @Override 8831 public void stopLockTaskMode() { 8832 // Verify that the user matches the package of the intent for the TaskRecord 8833 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8834 // and stopLockTaskMode. 8835 final int callingUid = Binder.getCallingUid(); 8836 if (callingUid != Process.SYSTEM_UID) { 8837 try { 8838 String pkg = 8839 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8840 int uid = mContext.getPackageManager().getPackageUid(pkg, 8841 Binder.getCallingUserHandle().getIdentifier()); 8842 if (uid != callingUid) { 8843 throw new SecurityException("Invalid uid, expected " + uid); 8844 } 8845 } catch (NameNotFoundException e) { 8846 Log.d(TAG, "stopLockTaskMode " + e); 8847 return; 8848 } 8849 } 8850 long ident = Binder.clearCallingIdentity(); 8851 try { 8852 Log.d(TAG, "stopLockTaskMode"); 8853 // Stop lock task 8854 synchronized (this) { 8855 mStackSupervisor.setLockTaskModeLocked(null, false); 8856 } 8857 } finally { 8858 Binder.restoreCallingIdentity(ident); 8859 } 8860 } 8861 8862 @Override 8863 public void stopLockTaskModeOnCurrent() throws RemoteException { 8864 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8865 "stopLockTaskModeOnCurrent"); 8866 long ident = Binder.clearCallingIdentity(); 8867 try { 8868 stopLockTaskMode(); 8869 } finally { 8870 Binder.restoreCallingIdentity(ident); 8871 } 8872 } 8873 8874 @Override 8875 public boolean isInLockTaskMode() { 8876 synchronized (this) { 8877 return mStackSupervisor.isInLockTaskMode(); 8878 } 8879 } 8880 8881 // ========================================================= 8882 // CONTENT PROVIDERS 8883 // ========================================================= 8884 8885 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8886 List<ProviderInfo> providers = null; 8887 try { 8888 providers = AppGlobals.getPackageManager(). 8889 queryContentProviders(app.processName, app.uid, 8890 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8891 } catch (RemoteException ex) { 8892 } 8893 if (DEBUG_MU) 8894 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8895 int userId = app.userId; 8896 if (providers != null) { 8897 int N = providers.size(); 8898 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8899 for (int i=0; i<N; i++) { 8900 ProviderInfo cpi = 8901 (ProviderInfo)providers.get(i); 8902 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8903 cpi.name, cpi.flags); 8904 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8905 // This is a singleton provider, but a user besides the 8906 // default user is asking to initialize a process it runs 8907 // in... well, no, it doesn't actually run in this process, 8908 // it runs in the process of the default user. Get rid of it. 8909 providers.remove(i); 8910 N--; 8911 i--; 8912 continue; 8913 } 8914 8915 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8916 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8917 if (cpr == null) { 8918 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8919 mProviderMap.putProviderByClass(comp, cpr); 8920 } 8921 if (DEBUG_MU) 8922 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8923 app.pubProviders.put(cpi.name, cpr); 8924 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8925 // Don't add this if it is a platform component that is marked 8926 // to run in multiple processes, because this is actually 8927 // part of the framework so doesn't make sense to track as a 8928 // separate apk in the process. 8929 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8930 mProcessStats); 8931 } 8932 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8933 } 8934 } 8935 return providers; 8936 } 8937 8938 /** 8939 * Check if {@link ProcessRecord} has a possible chance at accessing the 8940 * given {@link ProviderInfo}. Final permission checking is always done 8941 * in {@link ContentProvider}. 8942 */ 8943 private final String checkContentProviderPermissionLocked( 8944 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8945 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8946 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8947 boolean checkedGrants = false; 8948 if (checkUser) { 8949 // Looking for cross-user grants before enforcing the typical cross-users permissions 8950 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8951 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8952 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8953 return null; 8954 } 8955 checkedGrants = true; 8956 } 8957 userId = handleIncomingUser(callingPid, callingUid, userId, 8958 false, ALLOW_NON_FULL, 8959 "checkContentProviderPermissionLocked " + cpi.authority, null); 8960 if (userId != tmpTargetUserId) { 8961 // When we actually went to determine the final targer user ID, this ended 8962 // up different than our initial check for the authority. This is because 8963 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8964 // SELF. So we need to re-check the grants again. 8965 checkedGrants = false; 8966 } 8967 } 8968 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8969 cpi.applicationInfo.uid, cpi.exported) 8970 == PackageManager.PERMISSION_GRANTED) { 8971 return null; 8972 } 8973 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8974 cpi.applicationInfo.uid, cpi.exported) 8975 == PackageManager.PERMISSION_GRANTED) { 8976 return null; 8977 } 8978 8979 PathPermission[] pps = cpi.pathPermissions; 8980 if (pps != null) { 8981 int i = pps.length; 8982 while (i > 0) { 8983 i--; 8984 PathPermission pp = pps[i]; 8985 String pprperm = pp.getReadPermission(); 8986 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8987 cpi.applicationInfo.uid, cpi.exported) 8988 == PackageManager.PERMISSION_GRANTED) { 8989 return null; 8990 } 8991 String ppwperm = pp.getWritePermission(); 8992 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8993 cpi.applicationInfo.uid, cpi.exported) 8994 == PackageManager.PERMISSION_GRANTED) { 8995 return null; 8996 } 8997 } 8998 } 8999 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9000 return null; 9001 } 9002 9003 String msg; 9004 if (!cpi.exported) { 9005 msg = "Permission Denial: opening provider " + cpi.name 9006 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9007 + ", uid=" + callingUid + ") that is not exported from uid " 9008 + cpi.applicationInfo.uid; 9009 } else { 9010 msg = "Permission Denial: opening provider " + cpi.name 9011 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9012 + ", uid=" + callingUid + ") requires " 9013 + cpi.readPermission + " or " + cpi.writePermission; 9014 } 9015 Slog.w(TAG, msg); 9016 return msg; 9017 } 9018 9019 /** 9020 * Returns if the ContentProvider has granted a uri to callingUid 9021 */ 9022 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9023 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9024 if (perms != null) { 9025 for (int i=perms.size()-1; i>=0; i--) { 9026 GrantUri grantUri = perms.keyAt(i); 9027 if (grantUri.sourceUserId == userId || !checkUser) { 9028 if (matchesProvider(grantUri.uri, cpi)) { 9029 return true; 9030 } 9031 } 9032 } 9033 } 9034 return false; 9035 } 9036 9037 /** 9038 * Returns true if the uri authority is one of the authorities specified in the provider. 9039 */ 9040 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9041 String uriAuth = uri.getAuthority(); 9042 String cpiAuth = cpi.authority; 9043 if (cpiAuth.indexOf(';') == -1) { 9044 return cpiAuth.equals(uriAuth); 9045 } 9046 String[] cpiAuths = cpiAuth.split(";"); 9047 int length = cpiAuths.length; 9048 for (int i = 0; i < length; i++) { 9049 if (cpiAuths[i].equals(uriAuth)) return true; 9050 } 9051 return false; 9052 } 9053 9054 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9055 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9056 if (r != null) { 9057 for (int i=0; i<r.conProviders.size(); i++) { 9058 ContentProviderConnection conn = r.conProviders.get(i); 9059 if (conn.provider == cpr) { 9060 if (DEBUG_PROVIDER) Slog.v(TAG, 9061 "Adding provider requested by " 9062 + r.processName + " from process " 9063 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9064 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9065 if (stable) { 9066 conn.stableCount++; 9067 conn.numStableIncs++; 9068 } else { 9069 conn.unstableCount++; 9070 conn.numUnstableIncs++; 9071 } 9072 return conn; 9073 } 9074 } 9075 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9076 if (stable) { 9077 conn.stableCount = 1; 9078 conn.numStableIncs = 1; 9079 } else { 9080 conn.unstableCount = 1; 9081 conn.numUnstableIncs = 1; 9082 } 9083 cpr.connections.add(conn); 9084 r.conProviders.add(conn); 9085 return conn; 9086 } 9087 cpr.addExternalProcessHandleLocked(externalProcessToken); 9088 return null; 9089 } 9090 9091 boolean decProviderCountLocked(ContentProviderConnection conn, 9092 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9093 if (conn != null) { 9094 cpr = conn.provider; 9095 if (DEBUG_PROVIDER) Slog.v(TAG, 9096 "Removing provider requested by " 9097 + conn.client.processName + " from process " 9098 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9099 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9100 if (stable) { 9101 conn.stableCount--; 9102 } else { 9103 conn.unstableCount--; 9104 } 9105 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9106 cpr.connections.remove(conn); 9107 conn.client.conProviders.remove(conn); 9108 return true; 9109 } 9110 return false; 9111 } 9112 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9113 return false; 9114 } 9115 9116 private void checkTime(long startTime, String where) { 9117 long now = SystemClock.elapsedRealtime(); 9118 if ((now-startTime) > 1000) { 9119 // If we are taking more than a second, log about it. 9120 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9121 } 9122 } 9123 9124 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9125 String name, IBinder token, boolean stable, int userId) { 9126 ContentProviderRecord cpr; 9127 ContentProviderConnection conn = null; 9128 ProviderInfo cpi = null; 9129 9130 synchronized(this) { 9131 long startTime = SystemClock.elapsedRealtime(); 9132 9133 ProcessRecord r = null; 9134 if (caller != null) { 9135 r = getRecordForAppLocked(caller); 9136 if (r == null) { 9137 throw new SecurityException( 9138 "Unable to find app for caller " + caller 9139 + " (pid=" + Binder.getCallingPid() 9140 + ") when getting content provider " + name); 9141 } 9142 } 9143 9144 boolean checkCrossUser = true; 9145 9146 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9147 9148 // First check if this content provider has been published... 9149 cpr = mProviderMap.getProviderByName(name, userId); 9150 // If that didn't work, check if it exists for user 0 and then 9151 // verify that it's a singleton provider before using it. 9152 if (cpr == null && userId != UserHandle.USER_OWNER) { 9153 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9154 if (cpr != null) { 9155 cpi = cpr.info; 9156 if (isSingleton(cpi.processName, cpi.applicationInfo, 9157 cpi.name, cpi.flags) 9158 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9159 userId = UserHandle.USER_OWNER; 9160 checkCrossUser = false; 9161 } else { 9162 cpr = null; 9163 cpi = null; 9164 } 9165 } 9166 } 9167 9168 boolean providerRunning = cpr != null; 9169 if (providerRunning) { 9170 cpi = cpr.info; 9171 String msg; 9172 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9173 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9174 != null) { 9175 throw new SecurityException(msg); 9176 } 9177 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9178 9179 if (r != null && cpr.canRunHere(r)) { 9180 // This provider has been published or is in the process 9181 // of being published... but it is also allowed to run 9182 // in the caller's process, so don't make a connection 9183 // and just let the caller instantiate its own instance. 9184 ContentProviderHolder holder = cpr.newHolder(null); 9185 // don't give caller the provider object, it needs 9186 // to make its own. 9187 holder.provider = null; 9188 return holder; 9189 } 9190 9191 final long origId = Binder.clearCallingIdentity(); 9192 9193 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9194 9195 // In this case the provider instance already exists, so we can 9196 // return it right away. 9197 conn = incProviderCountLocked(r, cpr, token, stable); 9198 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9199 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9200 // If this is a perceptible app accessing the provider, 9201 // make sure to count it as being accessed and thus 9202 // back up on the LRU list. This is good because 9203 // content providers are often expensive to start. 9204 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9205 updateLruProcessLocked(cpr.proc, false, null); 9206 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9207 } 9208 } 9209 9210 if (cpr.proc != null) { 9211 if (false) { 9212 if (cpr.name.flattenToShortString().equals( 9213 "com.android.providers.calendar/.CalendarProvider2")) { 9214 Slog.v(TAG, "****************** KILLING " 9215 + cpr.name.flattenToShortString()); 9216 Process.killProcess(cpr.proc.pid); 9217 } 9218 } 9219 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9220 boolean success = updateOomAdjLocked(cpr.proc); 9221 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9222 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9223 // NOTE: there is still a race here where a signal could be 9224 // pending on the process even though we managed to update its 9225 // adj level. Not sure what to do about this, but at least 9226 // the race is now smaller. 9227 if (!success) { 9228 // Uh oh... it looks like the provider's process 9229 // has been killed on us. We need to wait for a new 9230 // process to be started, and make sure its death 9231 // doesn't kill our process. 9232 Slog.i(TAG, 9233 "Existing provider " + cpr.name.flattenToShortString() 9234 + " is crashing; detaching " + r); 9235 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9236 checkTime(startTime, "getContentProviderImpl: before appDied"); 9237 appDiedLocked(cpr.proc); 9238 checkTime(startTime, "getContentProviderImpl: after appDied"); 9239 if (!lastRef) { 9240 // This wasn't the last ref our process had on 9241 // the provider... we have now been killed, bail. 9242 return null; 9243 } 9244 providerRunning = false; 9245 conn = null; 9246 } 9247 } 9248 9249 Binder.restoreCallingIdentity(origId); 9250 } 9251 9252 boolean singleton; 9253 if (!providerRunning) { 9254 try { 9255 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9256 cpi = AppGlobals.getPackageManager(). 9257 resolveContentProvider(name, 9258 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9259 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9260 } catch (RemoteException ex) { 9261 } 9262 if (cpi == null) { 9263 return null; 9264 } 9265 // If the provider is a singleton AND 9266 // (it's a call within the same user || the provider is a 9267 // privileged app) 9268 // Then allow connecting to the singleton provider 9269 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9270 cpi.name, cpi.flags) 9271 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9272 if (singleton) { 9273 userId = UserHandle.USER_OWNER; 9274 } 9275 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9276 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9277 9278 String msg; 9279 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9280 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9281 != null) { 9282 throw new SecurityException(msg); 9283 } 9284 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9285 9286 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9287 && !cpi.processName.equals("system")) { 9288 // If this content provider does not run in the system 9289 // process, and the system is not yet ready to run other 9290 // processes, then fail fast instead of hanging. 9291 throw new IllegalArgumentException( 9292 "Attempt to launch content provider before system ready"); 9293 } 9294 9295 // Make sure that the user who owns this provider is running. If not, 9296 // we don't want to allow it to run. 9297 if (!isUserRunningLocked(userId, false)) { 9298 Slog.w(TAG, "Unable to launch app " 9299 + cpi.applicationInfo.packageName + "/" 9300 + cpi.applicationInfo.uid + " for provider " 9301 + name + ": user " + userId + " is stopped"); 9302 return null; 9303 } 9304 9305 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9306 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9307 cpr = mProviderMap.getProviderByClass(comp, userId); 9308 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9309 final boolean firstClass = cpr == null; 9310 if (firstClass) { 9311 final long ident = Binder.clearCallingIdentity(); 9312 try { 9313 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9314 ApplicationInfo ai = 9315 AppGlobals.getPackageManager(). 9316 getApplicationInfo( 9317 cpi.applicationInfo.packageName, 9318 STOCK_PM_FLAGS, userId); 9319 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9320 if (ai == null) { 9321 Slog.w(TAG, "No package info for content provider " 9322 + cpi.name); 9323 return null; 9324 } 9325 ai = getAppInfoForUser(ai, userId); 9326 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9327 } catch (RemoteException ex) { 9328 // pm is in same process, this will never happen. 9329 } finally { 9330 Binder.restoreCallingIdentity(ident); 9331 } 9332 } 9333 9334 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9335 9336 if (r != null && cpr.canRunHere(r)) { 9337 // If this is a multiprocess provider, then just return its 9338 // info and allow the caller to instantiate it. Only do 9339 // this if the provider is the same user as the caller's 9340 // process, or can run as root (so can be in any process). 9341 return cpr.newHolder(null); 9342 } 9343 9344 if (DEBUG_PROVIDER) { 9345 RuntimeException e = new RuntimeException("here"); 9346 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9347 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9348 } 9349 9350 // This is single process, and our app is now connecting to it. 9351 // See if we are already in the process of launching this 9352 // provider. 9353 final int N = mLaunchingProviders.size(); 9354 int i; 9355 for (i=0; i<N; i++) { 9356 if (mLaunchingProviders.get(i) == cpr) { 9357 break; 9358 } 9359 } 9360 9361 // If the provider is not already being launched, then get it 9362 // started. 9363 if (i >= N) { 9364 final long origId = Binder.clearCallingIdentity(); 9365 9366 try { 9367 // Content provider is now in use, its package can't be stopped. 9368 try { 9369 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9370 AppGlobals.getPackageManager().setPackageStoppedState( 9371 cpr.appInfo.packageName, false, userId); 9372 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9373 } catch (RemoteException e) { 9374 } catch (IllegalArgumentException e) { 9375 Slog.w(TAG, "Failed trying to unstop package " 9376 + cpr.appInfo.packageName + ": " + e); 9377 } 9378 9379 // Use existing process if already started 9380 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9381 ProcessRecord proc = getProcessRecordLocked( 9382 cpi.processName, cpr.appInfo.uid, false); 9383 if (proc != null && proc.thread != null) { 9384 if (DEBUG_PROVIDER) { 9385 Slog.d(TAG, "Installing in existing process " + proc); 9386 } 9387 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9388 proc.pubProviders.put(cpi.name, cpr); 9389 try { 9390 proc.thread.scheduleInstallProvider(cpi); 9391 } catch (RemoteException e) { 9392 } 9393 } else { 9394 checkTime(startTime, "getContentProviderImpl: before start process"); 9395 proc = startProcessLocked(cpi.processName, 9396 cpr.appInfo, false, 0, "content provider", 9397 new ComponentName(cpi.applicationInfo.packageName, 9398 cpi.name), false, false, false); 9399 checkTime(startTime, "getContentProviderImpl: after start process"); 9400 if (proc == null) { 9401 Slog.w(TAG, "Unable to launch app " 9402 + cpi.applicationInfo.packageName + "/" 9403 + cpi.applicationInfo.uid + " for provider " 9404 + name + ": process is bad"); 9405 return null; 9406 } 9407 } 9408 cpr.launchingApp = proc; 9409 mLaunchingProviders.add(cpr); 9410 } finally { 9411 Binder.restoreCallingIdentity(origId); 9412 } 9413 } 9414 9415 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9416 9417 // Make sure the provider is published (the same provider class 9418 // may be published under multiple names). 9419 if (firstClass) { 9420 mProviderMap.putProviderByClass(comp, cpr); 9421 } 9422 9423 mProviderMap.putProviderByName(name, cpr); 9424 conn = incProviderCountLocked(r, cpr, token, stable); 9425 if (conn != null) { 9426 conn.waiting = true; 9427 } 9428 } 9429 checkTime(startTime, "getContentProviderImpl: done!"); 9430 } 9431 9432 // Wait for the provider to be published... 9433 synchronized (cpr) { 9434 while (cpr.provider == null) { 9435 if (cpr.launchingApp == null) { 9436 Slog.w(TAG, "Unable to launch app " 9437 + cpi.applicationInfo.packageName + "/" 9438 + cpi.applicationInfo.uid + " for provider " 9439 + name + ": launching app became null"); 9440 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9441 UserHandle.getUserId(cpi.applicationInfo.uid), 9442 cpi.applicationInfo.packageName, 9443 cpi.applicationInfo.uid, name); 9444 return null; 9445 } 9446 try { 9447 if (DEBUG_MU) { 9448 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9449 + cpr.launchingApp); 9450 } 9451 if (conn != null) { 9452 conn.waiting = true; 9453 } 9454 cpr.wait(); 9455 } catch (InterruptedException ex) { 9456 } finally { 9457 if (conn != null) { 9458 conn.waiting = false; 9459 } 9460 } 9461 } 9462 } 9463 return cpr != null ? cpr.newHolder(conn) : null; 9464 } 9465 9466 @Override 9467 public final ContentProviderHolder getContentProvider( 9468 IApplicationThread caller, String name, int userId, boolean stable) { 9469 enforceNotIsolatedCaller("getContentProvider"); 9470 if (caller == null) { 9471 String msg = "null IApplicationThread when getting content provider " 9472 + name; 9473 Slog.w(TAG, msg); 9474 throw new SecurityException(msg); 9475 } 9476 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9477 // with cross-user grant. 9478 return getContentProviderImpl(caller, name, null, stable, userId); 9479 } 9480 9481 public ContentProviderHolder getContentProviderExternal( 9482 String name, int userId, IBinder token) { 9483 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9484 "Do not have permission in call getContentProviderExternal()"); 9485 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9486 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9487 return getContentProviderExternalUnchecked(name, token, userId); 9488 } 9489 9490 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9491 IBinder token, int userId) { 9492 return getContentProviderImpl(null, name, token, true, userId); 9493 } 9494 9495 /** 9496 * Drop a content provider from a ProcessRecord's bookkeeping 9497 */ 9498 public void removeContentProvider(IBinder connection, boolean stable) { 9499 enforceNotIsolatedCaller("removeContentProvider"); 9500 long ident = Binder.clearCallingIdentity(); 9501 try { 9502 synchronized (this) { 9503 ContentProviderConnection conn; 9504 try { 9505 conn = (ContentProviderConnection)connection; 9506 } catch (ClassCastException e) { 9507 String msg ="removeContentProvider: " + connection 9508 + " not a ContentProviderConnection"; 9509 Slog.w(TAG, msg); 9510 throw new IllegalArgumentException(msg); 9511 } 9512 if (conn == null) { 9513 throw new NullPointerException("connection is null"); 9514 } 9515 if (decProviderCountLocked(conn, null, null, stable)) { 9516 updateOomAdjLocked(); 9517 } 9518 } 9519 } finally { 9520 Binder.restoreCallingIdentity(ident); 9521 } 9522 } 9523 9524 public void removeContentProviderExternal(String name, IBinder token) { 9525 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9526 "Do not have permission in call removeContentProviderExternal()"); 9527 int userId = UserHandle.getCallingUserId(); 9528 long ident = Binder.clearCallingIdentity(); 9529 try { 9530 removeContentProviderExternalUnchecked(name, token, userId); 9531 } finally { 9532 Binder.restoreCallingIdentity(ident); 9533 } 9534 } 9535 9536 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9537 synchronized (this) { 9538 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9539 if(cpr == null) { 9540 //remove from mProvidersByClass 9541 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9542 return; 9543 } 9544 9545 //update content provider record entry info 9546 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9547 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9548 if (localCpr.hasExternalProcessHandles()) { 9549 if (localCpr.removeExternalProcessHandleLocked(token)) { 9550 updateOomAdjLocked(); 9551 } else { 9552 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9553 + " with no external reference for token: " 9554 + token + "."); 9555 } 9556 } else { 9557 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9558 + " with no external references."); 9559 } 9560 } 9561 } 9562 9563 public final void publishContentProviders(IApplicationThread caller, 9564 List<ContentProviderHolder> providers) { 9565 if (providers == null) { 9566 return; 9567 } 9568 9569 enforceNotIsolatedCaller("publishContentProviders"); 9570 synchronized (this) { 9571 final ProcessRecord r = getRecordForAppLocked(caller); 9572 if (DEBUG_MU) 9573 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9574 if (r == null) { 9575 throw new SecurityException( 9576 "Unable to find app for caller " + caller 9577 + " (pid=" + Binder.getCallingPid() 9578 + ") when publishing content providers"); 9579 } 9580 9581 final long origId = Binder.clearCallingIdentity(); 9582 9583 final int N = providers.size(); 9584 for (int i=0; i<N; i++) { 9585 ContentProviderHolder src = providers.get(i); 9586 if (src == null || src.info == null || src.provider == null) { 9587 continue; 9588 } 9589 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9590 if (DEBUG_MU) 9591 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9592 if (dst != null) { 9593 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9594 mProviderMap.putProviderByClass(comp, dst); 9595 String names[] = dst.info.authority.split(";"); 9596 for (int j = 0; j < names.length; j++) { 9597 mProviderMap.putProviderByName(names[j], dst); 9598 } 9599 9600 int NL = mLaunchingProviders.size(); 9601 int j; 9602 for (j=0; j<NL; j++) { 9603 if (mLaunchingProviders.get(j) == dst) { 9604 mLaunchingProviders.remove(j); 9605 j--; 9606 NL--; 9607 } 9608 } 9609 synchronized (dst) { 9610 dst.provider = src.provider; 9611 dst.proc = r; 9612 dst.notifyAll(); 9613 } 9614 updateOomAdjLocked(r); 9615 } 9616 } 9617 9618 Binder.restoreCallingIdentity(origId); 9619 } 9620 } 9621 9622 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9623 ContentProviderConnection conn; 9624 try { 9625 conn = (ContentProviderConnection)connection; 9626 } catch (ClassCastException e) { 9627 String msg ="refContentProvider: " + connection 9628 + " not a ContentProviderConnection"; 9629 Slog.w(TAG, msg); 9630 throw new IllegalArgumentException(msg); 9631 } 9632 if (conn == null) { 9633 throw new NullPointerException("connection is null"); 9634 } 9635 9636 synchronized (this) { 9637 if (stable > 0) { 9638 conn.numStableIncs += stable; 9639 } 9640 stable = conn.stableCount + stable; 9641 if (stable < 0) { 9642 throw new IllegalStateException("stableCount < 0: " + stable); 9643 } 9644 9645 if (unstable > 0) { 9646 conn.numUnstableIncs += unstable; 9647 } 9648 unstable = conn.unstableCount + unstable; 9649 if (unstable < 0) { 9650 throw new IllegalStateException("unstableCount < 0: " + unstable); 9651 } 9652 9653 if ((stable+unstable) <= 0) { 9654 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9655 + stable + " unstable=" + unstable); 9656 } 9657 conn.stableCount = stable; 9658 conn.unstableCount = unstable; 9659 return !conn.dead; 9660 } 9661 } 9662 9663 public void unstableProviderDied(IBinder connection) { 9664 ContentProviderConnection conn; 9665 try { 9666 conn = (ContentProviderConnection)connection; 9667 } catch (ClassCastException e) { 9668 String msg ="refContentProvider: " + connection 9669 + " not a ContentProviderConnection"; 9670 Slog.w(TAG, msg); 9671 throw new IllegalArgumentException(msg); 9672 } 9673 if (conn == null) { 9674 throw new NullPointerException("connection is null"); 9675 } 9676 9677 // Safely retrieve the content provider associated with the connection. 9678 IContentProvider provider; 9679 synchronized (this) { 9680 provider = conn.provider.provider; 9681 } 9682 9683 if (provider == null) { 9684 // Um, yeah, we're way ahead of you. 9685 return; 9686 } 9687 9688 // Make sure the caller is being honest with us. 9689 if (provider.asBinder().pingBinder()) { 9690 // Er, no, still looks good to us. 9691 synchronized (this) { 9692 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9693 + " says " + conn + " died, but we don't agree"); 9694 return; 9695 } 9696 } 9697 9698 // Well look at that! It's dead! 9699 synchronized (this) { 9700 if (conn.provider.provider != provider) { 9701 // But something changed... good enough. 9702 return; 9703 } 9704 9705 ProcessRecord proc = conn.provider.proc; 9706 if (proc == null || proc.thread == null) { 9707 // Seems like the process is already cleaned up. 9708 return; 9709 } 9710 9711 // As far as we're concerned, this is just like receiving a 9712 // death notification... just a bit prematurely. 9713 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9714 + ") early provider death"); 9715 final long ident = Binder.clearCallingIdentity(); 9716 try { 9717 appDiedLocked(proc); 9718 } finally { 9719 Binder.restoreCallingIdentity(ident); 9720 } 9721 } 9722 } 9723 9724 @Override 9725 public void appNotRespondingViaProvider(IBinder connection) { 9726 enforceCallingPermission( 9727 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9728 9729 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9730 if (conn == null) { 9731 Slog.w(TAG, "ContentProviderConnection is null"); 9732 return; 9733 } 9734 9735 final ProcessRecord host = conn.provider.proc; 9736 if (host == null) { 9737 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9738 return; 9739 } 9740 9741 final long token = Binder.clearCallingIdentity(); 9742 try { 9743 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9744 } finally { 9745 Binder.restoreCallingIdentity(token); 9746 } 9747 } 9748 9749 public final void installSystemProviders() { 9750 List<ProviderInfo> providers; 9751 synchronized (this) { 9752 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9753 providers = generateApplicationProvidersLocked(app); 9754 if (providers != null) { 9755 for (int i=providers.size()-1; i>=0; i--) { 9756 ProviderInfo pi = (ProviderInfo)providers.get(i); 9757 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9758 Slog.w(TAG, "Not installing system proc provider " + pi.name 9759 + ": not system .apk"); 9760 providers.remove(i); 9761 } 9762 } 9763 } 9764 } 9765 if (providers != null) { 9766 mSystemThread.installSystemProviders(providers); 9767 } 9768 9769 mCoreSettingsObserver = new CoreSettingsObserver(this); 9770 9771 //mUsageStatsService.monitorPackages(); 9772 } 9773 9774 /** 9775 * Allows apps to retrieve the MIME type of a URI. 9776 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9777 * users, then it does not need permission to access the ContentProvider. 9778 * Either, it needs cross-user uri grants. 9779 * 9780 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9781 * 9782 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9783 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9784 */ 9785 public String getProviderMimeType(Uri uri, int userId) { 9786 enforceNotIsolatedCaller("getProviderMimeType"); 9787 final String name = uri.getAuthority(); 9788 int callingUid = Binder.getCallingUid(); 9789 int callingPid = Binder.getCallingPid(); 9790 long ident = 0; 9791 boolean clearedIdentity = false; 9792 userId = unsafeConvertIncomingUser(userId); 9793 if (canClearIdentity(callingPid, callingUid, userId)) { 9794 clearedIdentity = true; 9795 ident = Binder.clearCallingIdentity(); 9796 } 9797 ContentProviderHolder holder = null; 9798 try { 9799 holder = getContentProviderExternalUnchecked(name, null, userId); 9800 if (holder != null) { 9801 return holder.provider.getType(uri); 9802 } 9803 } catch (RemoteException e) { 9804 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9805 return null; 9806 } finally { 9807 // We need to clear the identity to call removeContentProviderExternalUnchecked 9808 if (!clearedIdentity) { 9809 ident = Binder.clearCallingIdentity(); 9810 } 9811 try { 9812 if (holder != null) { 9813 removeContentProviderExternalUnchecked(name, null, userId); 9814 } 9815 } finally { 9816 Binder.restoreCallingIdentity(ident); 9817 } 9818 } 9819 9820 return null; 9821 } 9822 9823 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9824 if (UserHandle.getUserId(callingUid) == userId) { 9825 return true; 9826 } 9827 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9828 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9829 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9830 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9831 return true; 9832 } 9833 return false; 9834 } 9835 9836 // ========================================================= 9837 // GLOBAL MANAGEMENT 9838 // ========================================================= 9839 9840 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9841 boolean isolated, int isolatedUid) { 9842 String proc = customProcess != null ? customProcess : info.processName; 9843 BatteryStatsImpl.Uid.Proc ps = null; 9844 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9845 int uid = info.uid; 9846 if (isolated) { 9847 if (isolatedUid == 0) { 9848 int userId = UserHandle.getUserId(uid); 9849 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9850 while (true) { 9851 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9852 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9853 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9854 } 9855 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9856 mNextIsolatedProcessUid++; 9857 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9858 // No process for this uid, use it. 9859 break; 9860 } 9861 stepsLeft--; 9862 if (stepsLeft <= 0) { 9863 return null; 9864 } 9865 } 9866 } else { 9867 // Special case for startIsolatedProcess (internal only), where 9868 // the uid of the isolated process is specified by the caller. 9869 uid = isolatedUid; 9870 } 9871 } 9872 return new ProcessRecord(stats, info, proc, uid); 9873 } 9874 9875 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9876 String abiOverride) { 9877 ProcessRecord app; 9878 if (!isolated) { 9879 app = getProcessRecordLocked(info.processName, info.uid, true); 9880 } else { 9881 app = null; 9882 } 9883 9884 if (app == null) { 9885 app = newProcessRecordLocked(info, null, isolated, 0); 9886 mProcessNames.put(info.processName, app.uid, app); 9887 if (isolated) { 9888 mIsolatedProcesses.put(app.uid, app); 9889 } 9890 updateLruProcessLocked(app, false, null); 9891 updateOomAdjLocked(); 9892 } 9893 9894 // This package really, really can not be stopped. 9895 try { 9896 AppGlobals.getPackageManager().setPackageStoppedState( 9897 info.packageName, false, UserHandle.getUserId(app.uid)); 9898 } catch (RemoteException e) { 9899 } catch (IllegalArgumentException e) { 9900 Slog.w(TAG, "Failed trying to unstop package " 9901 + info.packageName + ": " + e); 9902 } 9903 9904 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9905 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9906 app.persistent = true; 9907 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9908 } 9909 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9910 mPersistentStartingProcesses.add(app); 9911 startProcessLocked(app, "added application", app.processName, abiOverride, 9912 null /* entryPoint */, null /* entryPointArgs */); 9913 } 9914 9915 return app; 9916 } 9917 9918 public void unhandledBack() { 9919 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9920 "unhandledBack()"); 9921 9922 synchronized(this) { 9923 final long origId = Binder.clearCallingIdentity(); 9924 try { 9925 getFocusedStack().unhandledBackLocked(); 9926 } finally { 9927 Binder.restoreCallingIdentity(origId); 9928 } 9929 } 9930 } 9931 9932 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9933 enforceNotIsolatedCaller("openContentUri"); 9934 final int userId = UserHandle.getCallingUserId(); 9935 String name = uri.getAuthority(); 9936 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9937 ParcelFileDescriptor pfd = null; 9938 if (cph != null) { 9939 // We record the binder invoker's uid in thread-local storage before 9940 // going to the content provider to open the file. Later, in the code 9941 // that handles all permissions checks, we look for this uid and use 9942 // that rather than the Activity Manager's own uid. The effect is that 9943 // we do the check against the caller's permissions even though it looks 9944 // to the content provider like the Activity Manager itself is making 9945 // the request. 9946 Binder token = new Binder(); 9947 sCallerIdentity.set(new Identity( 9948 token, Binder.getCallingPid(), Binder.getCallingUid())); 9949 try { 9950 pfd = cph.provider.openFile(null, uri, "r", null, token); 9951 } catch (FileNotFoundException e) { 9952 // do nothing; pfd will be returned null 9953 } finally { 9954 // Ensure that whatever happens, we clean up the identity state 9955 sCallerIdentity.remove(); 9956 } 9957 9958 // We've got the fd now, so we're done with the provider. 9959 removeContentProviderExternalUnchecked(name, null, userId); 9960 } else { 9961 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9962 } 9963 return pfd; 9964 } 9965 9966 // Actually is sleeping or shutting down or whatever else in the future 9967 // is an inactive state. 9968 public boolean isSleepingOrShuttingDown() { 9969 return isSleeping() || mShuttingDown; 9970 } 9971 9972 public boolean isSleeping() { 9973 return mSleeping; 9974 } 9975 9976 void onWakefulnessChanged(int wakefulness) { 9977 synchronized(this) { 9978 mWakefulness = wakefulness; 9979 updateSleepIfNeededLocked(); 9980 } 9981 } 9982 9983 void finishRunningVoiceLocked() { 9984 if (mRunningVoice) { 9985 mRunningVoice = false; 9986 updateSleepIfNeededLocked(); 9987 } 9988 } 9989 9990 void updateSleepIfNeededLocked() { 9991 if (mSleeping && !shouldSleepLocked()) { 9992 mSleeping = false; 9993 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9994 } else if (!mSleeping && shouldSleepLocked()) { 9995 mSleeping = true; 9996 mStackSupervisor.goingToSleepLocked(); 9997 9998 // Initialize the wake times of all processes. 9999 checkExcessivePowerUsageLocked(false); 10000 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10001 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10002 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10003 } 10004 } 10005 10006 private boolean shouldSleepLocked() { 10007 // Resume applications while running a voice interactor. 10008 if (mRunningVoice) { 10009 return false; 10010 } 10011 10012 switch (mWakefulness) { 10013 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10014 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10015 // If we're interactive but applications are already paused then defer 10016 // resuming them until the lock screen is hidden. 10017 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10018 case PowerManagerInternal.WAKEFULNESS_DOZING: 10019 // If we're dozing then pause applications whenever the lock screen is shown. 10020 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10021 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10022 default: 10023 // If we're asleep then pause applications unconditionally. 10024 return true; 10025 } 10026 } 10027 10028 /** Pokes the task persister. */ 10029 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10030 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10031 // Never persist the home stack. 10032 return; 10033 } 10034 mTaskPersister.wakeup(task, flush); 10035 } 10036 10037 /** Notifies all listeners when the task stack has changed. */ 10038 void notifyTaskStackChangedLocked() { 10039 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10040 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10041 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10042 } 10043 10044 @Override 10045 public boolean shutdown(int timeout) { 10046 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10047 != PackageManager.PERMISSION_GRANTED) { 10048 throw new SecurityException("Requires permission " 10049 + android.Manifest.permission.SHUTDOWN); 10050 } 10051 10052 boolean timedout = false; 10053 10054 synchronized(this) { 10055 mShuttingDown = true; 10056 updateEventDispatchingLocked(); 10057 timedout = mStackSupervisor.shutdownLocked(timeout); 10058 } 10059 10060 mAppOpsService.shutdown(); 10061 if (mUsageStatsService != null) { 10062 mUsageStatsService.prepareShutdown(); 10063 } 10064 mBatteryStatsService.shutdown(); 10065 synchronized (this) { 10066 mProcessStats.shutdownLocked(); 10067 notifyTaskPersisterLocked(null, true); 10068 } 10069 10070 return timedout; 10071 } 10072 10073 public final void activitySlept(IBinder token) { 10074 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10075 10076 final long origId = Binder.clearCallingIdentity(); 10077 10078 synchronized (this) { 10079 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10080 if (r != null) { 10081 mStackSupervisor.activitySleptLocked(r); 10082 } 10083 } 10084 10085 Binder.restoreCallingIdentity(origId); 10086 } 10087 10088 private String lockScreenShownToString() { 10089 switch (mLockScreenShown) { 10090 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10091 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10092 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10093 default: return "Unknown=" + mLockScreenShown; 10094 } 10095 } 10096 10097 void logLockScreen(String msg) { 10098 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10099 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10100 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10101 + " mSleeping=" + mSleeping); 10102 } 10103 10104 void startRunningVoiceLocked() { 10105 if (!mRunningVoice) { 10106 mRunningVoice = true; 10107 updateSleepIfNeededLocked(); 10108 } 10109 } 10110 10111 private void updateEventDispatchingLocked() { 10112 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10113 } 10114 10115 public void setLockScreenShown(boolean shown) { 10116 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10117 != PackageManager.PERMISSION_GRANTED) { 10118 throw new SecurityException("Requires permission " 10119 + android.Manifest.permission.DEVICE_POWER); 10120 } 10121 10122 synchronized(this) { 10123 long ident = Binder.clearCallingIdentity(); 10124 try { 10125 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10126 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10127 updateSleepIfNeededLocked(); 10128 } finally { 10129 Binder.restoreCallingIdentity(ident); 10130 } 10131 } 10132 } 10133 10134 @Override 10135 public void stopAppSwitches() { 10136 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10137 != PackageManager.PERMISSION_GRANTED) { 10138 throw new SecurityException("Requires permission " 10139 + android.Manifest.permission.STOP_APP_SWITCHES); 10140 } 10141 10142 synchronized(this) { 10143 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10144 + APP_SWITCH_DELAY_TIME; 10145 mDidAppSwitch = false; 10146 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10147 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10148 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10149 } 10150 } 10151 10152 public void resumeAppSwitches() { 10153 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10154 != PackageManager.PERMISSION_GRANTED) { 10155 throw new SecurityException("Requires permission " 10156 + android.Manifest.permission.STOP_APP_SWITCHES); 10157 } 10158 10159 synchronized(this) { 10160 // Note that we don't execute any pending app switches... we will 10161 // let those wait until either the timeout, or the next start 10162 // activity request. 10163 mAppSwitchesAllowedTime = 0; 10164 } 10165 } 10166 10167 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10168 int callingPid, int callingUid, String name) { 10169 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10170 return true; 10171 } 10172 10173 int perm = checkComponentPermission( 10174 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10175 sourceUid, -1, true); 10176 if (perm == PackageManager.PERMISSION_GRANTED) { 10177 return true; 10178 } 10179 10180 // If the actual IPC caller is different from the logical source, then 10181 // also see if they are allowed to control app switches. 10182 if (callingUid != -1 && callingUid != sourceUid) { 10183 perm = checkComponentPermission( 10184 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10185 callingUid, -1, true); 10186 if (perm == PackageManager.PERMISSION_GRANTED) { 10187 return true; 10188 } 10189 } 10190 10191 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10192 return false; 10193 } 10194 10195 public void setDebugApp(String packageName, boolean waitForDebugger, 10196 boolean persistent) { 10197 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10198 "setDebugApp()"); 10199 10200 long ident = Binder.clearCallingIdentity(); 10201 try { 10202 // Note that this is not really thread safe if there are multiple 10203 // callers into it at the same time, but that's not a situation we 10204 // care about. 10205 if (persistent) { 10206 final ContentResolver resolver = mContext.getContentResolver(); 10207 Settings.Global.putString( 10208 resolver, Settings.Global.DEBUG_APP, 10209 packageName); 10210 Settings.Global.putInt( 10211 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10212 waitForDebugger ? 1 : 0); 10213 } 10214 10215 synchronized (this) { 10216 if (!persistent) { 10217 mOrigDebugApp = mDebugApp; 10218 mOrigWaitForDebugger = mWaitForDebugger; 10219 } 10220 mDebugApp = packageName; 10221 mWaitForDebugger = waitForDebugger; 10222 mDebugTransient = !persistent; 10223 if (packageName != null) { 10224 forceStopPackageLocked(packageName, -1, false, false, true, true, 10225 false, UserHandle.USER_ALL, "set debug app"); 10226 } 10227 } 10228 } finally { 10229 Binder.restoreCallingIdentity(ident); 10230 } 10231 } 10232 10233 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10234 synchronized (this) { 10235 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10236 if (!isDebuggable) { 10237 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10238 throw new SecurityException("Process not debuggable: " + app.packageName); 10239 } 10240 } 10241 10242 mOpenGlTraceApp = processName; 10243 } 10244 } 10245 10246 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10247 synchronized (this) { 10248 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10249 if (!isDebuggable) { 10250 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10251 throw new SecurityException("Process not debuggable: " + app.packageName); 10252 } 10253 } 10254 mProfileApp = processName; 10255 mProfileFile = profilerInfo.profileFile; 10256 if (mProfileFd != null) { 10257 try { 10258 mProfileFd.close(); 10259 } catch (IOException e) { 10260 } 10261 mProfileFd = null; 10262 } 10263 mProfileFd = profilerInfo.profileFd; 10264 mSamplingInterval = profilerInfo.samplingInterval; 10265 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10266 mProfileType = 0; 10267 } 10268 } 10269 10270 @Override 10271 public void setAlwaysFinish(boolean enabled) { 10272 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10273 "setAlwaysFinish()"); 10274 10275 Settings.Global.putInt( 10276 mContext.getContentResolver(), 10277 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10278 10279 synchronized (this) { 10280 mAlwaysFinishActivities = enabled; 10281 } 10282 } 10283 10284 @Override 10285 public void setActivityController(IActivityController controller) { 10286 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10287 "setActivityController()"); 10288 synchronized (this) { 10289 mController = controller; 10290 Watchdog.getInstance().setActivityController(controller); 10291 } 10292 } 10293 10294 @Override 10295 public void setUserIsMonkey(boolean userIsMonkey) { 10296 synchronized (this) { 10297 synchronized (mPidsSelfLocked) { 10298 final int callingPid = Binder.getCallingPid(); 10299 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10300 if (precessRecord == null) { 10301 throw new SecurityException("Unknown process: " + callingPid); 10302 } 10303 if (precessRecord.instrumentationUiAutomationConnection == null) { 10304 throw new SecurityException("Only an instrumentation process " 10305 + "with a UiAutomation can call setUserIsMonkey"); 10306 } 10307 } 10308 mUserIsMonkey = userIsMonkey; 10309 } 10310 } 10311 10312 @Override 10313 public boolean isUserAMonkey() { 10314 synchronized (this) { 10315 // If there is a controller also implies the user is a monkey. 10316 return (mUserIsMonkey || mController != null); 10317 } 10318 } 10319 10320 public void requestBugReport() { 10321 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10322 SystemProperties.set("ctl.start", "bugreport"); 10323 } 10324 10325 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10326 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10327 } 10328 10329 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10330 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10331 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10332 } 10333 return KEY_DISPATCHING_TIMEOUT; 10334 } 10335 10336 @Override 10337 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10338 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10339 != PackageManager.PERMISSION_GRANTED) { 10340 throw new SecurityException("Requires permission " 10341 + android.Manifest.permission.FILTER_EVENTS); 10342 } 10343 ProcessRecord proc; 10344 long timeout; 10345 synchronized (this) { 10346 synchronized (mPidsSelfLocked) { 10347 proc = mPidsSelfLocked.get(pid); 10348 } 10349 timeout = getInputDispatchingTimeoutLocked(proc); 10350 } 10351 10352 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10353 return -1; 10354 } 10355 10356 return timeout; 10357 } 10358 10359 /** 10360 * Handle input dispatching timeouts. 10361 * Returns whether input dispatching should be aborted or not. 10362 */ 10363 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10364 final ActivityRecord activity, final ActivityRecord parent, 10365 final boolean aboveSystem, String reason) { 10366 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10367 != PackageManager.PERMISSION_GRANTED) { 10368 throw new SecurityException("Requires permission " 10369 + android.Manifest.permission.FILTER_EVENTS); 10370 } 10371 10372 final String annotation; 10373 if (reason == null) { 10374 annotation = "Input dispatching timed out"; 10375 } else { 10376 annotation = "Input dispatching timed out (" + reason + ")"; 10377 } 10378 10379 if (proc != null) { 10380 synchronized (this) { 10381 if (proc.debugging) { 10382 return false; 10383 } 10384 10385 if (mDidDexOpt) { 10386 // Give more time since we were dexopting. 10387 mDidDexOpt = false; 10388 return false; 10389 } 10390 10391 if (proc.instrumentationClass != null) { 10392 Bundle info = new Bundle(); 10393 info.putString("shortMsg", "keyDispatchingTimedOut"); 10394 info.putString("longMsg", annotation); 10395 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10396 return true; 10397 } 10398 } 10399 mHandler.post(new Runnable() { 10400 @Override 10401 public void run() { 10402 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10403 } 10404 }); 10405 } 10406 10407 return true; 10408 } 10409 10410 public Bundle getAssistContextExtras(int requestType) { 10411 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10412 UserHandle.getCallingUserId()); 10413 if (pae == null) { 10414 return null; 10415 } 10416 synchronized (pae) { 10417 while (!pae.haveResult) { 10418 try { 10419 pae.wait(); 10420 } catch (InterruptedException e) { 10421 } 10422 } 10423 if (pae.result != null) { 10424 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10425 } 10426 } 10427 synchronized (this) { 10428 mPendingAssistExtras.remove(pae); 10429 mHandler.removeCallbacks(pae); 10430 } 10431 return pae.extras; 10432 } 10433 10434 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10435 int userHandle) { 10436 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10437 "getAssistContextExtras()"); 10438 PendingAssistExtras pae; 10439 Bundle extras = new Bundle(); 10440 synchronized (this) { 10441 ActivityRecord activity = getFocusedStack().mResumedActivity; 10442 if (activity == null) { 10443 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10444 return null; 10445 } 10446 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10447 if (activity.app == null || activity.app.thread == null) { 10448 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10449 return null; 10450 } 10451 if (activity.app.pid == Binder.getCallingPid()) { 10452 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10453 return null; 10454 } 10455 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10456 try { 10457 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10458 requestType); 10459 mPendingAssistExtras.add(pae); 10460 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10461 } catch (RemoteException e) { 10462 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10463 return null; 10464 } 10465 return pae; 10466 } 10467 } 10468 10469 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10470 PendingAssistExtras pae = (PendingAssistExtras)token; 10471 synchronized (pae) { 10472 pae.result = extras; 10473 pae.haveResult = true; 10474 pae.notifyAll(); 10475 if (pae.intent == null) { 10476 // Caller is just waiting for the result. 10477 return; 10478 } 10479 } 10480 10481 // We are now ready to launch the assist activity. 10482 synchronized (this) { 10483 boolean exists = mPendingAssistExtras.remove(pae); 10484 mHandler.removeCallbacks(pae); 10485 if (!exists) { 10486 // Timed out. 10487 return; 10488 } 10489 } 10490 pae.intent.replaceExtras(extras); 10491 if (pae.hint != null) { 10492 pae.intent.putExtra(pae.hint, true); 10493 } 10494 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10495 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10496 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10497 closeSystemDialogs("assist"); 10498 try { 10499 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10500 } catch (ActivityNotFoundException e) { 10501 Slog.w(TAG, "No activity to handle assist action.", e); 10502 } 10503 } 10504 10505 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10506 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10507 } 10508 10509 public void registerProcessObserver(IProcessObserver observer) { 10510 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10511 "registerProcessObserver()"); 10512 synchronized (this) { 10513 mProcessObservers.register(observer); 10514 } 10515 } 10516 10517 @Override 10518 public void unregisterProcessObserver(IProcessObserver observer) { 10519 synchronized (this) { 10520 mProcessObservers.unregister(observer); 10521 } 10522 } 10523 10524 @Override 10525 public boolean convertFromTranslucent(IBinder token) { 10526 final long origId = Binder.clearCallingIdentity(); 10527 try { 10528 synchronized (this) { 10529 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10530 if (r == null) { 10531 return false; 10532 } 10533 final boolean translucentChanged = r.changeWindowTranslucency(true); 10534 if (translucentChanged) { 10535 r.task.stack.releaseBackgroundResources(); 10536 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10537 } 10538 mWindowManager.setAppFullscreen(token, true); 10539 return translucentChanged; 10540 } 10541 } finally { 10542 Binder.restoreCallingIdentity(origId); 10543 } 10544 } 10545 10546 @Override 10547 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10548 final long origId = Binder.clearCallingIdentity(); 10549 try { 10550 synchronized (this) { 10551 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10552 if (r == null) { 10553 return false; 10554 } 10555 int index = r.task.mActivities.lastIndexOf(r); 10556 if (index > 0) { 10557 ActivityRecord under = r.task.mActivities.get(index - 1); 10558 under.returningOptions = options; 10559 } 10560 final boolean translucentChanged = r.changeWindowTranslucency(false); 10561 if (translucentChanged) { 10562 r.task.stack.convertToTranslucent(r); 10563 } 10564 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10565 mWindowManager.setAppFullscreen(token, false); 10566 return translucentChanged; 10567 } 10568 } finally { 10569 Binder.restoreCallingIdentity(origId); 10570 } 10571 } 10572 10573 @Override 10574 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10575 final long origId = Binder.clearCallingIdentity(); 10576 try { 10577 synchronized (this) { 10578 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10579 if (r != null) { 10580 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10581 } 10582 } 10583 return false; 10584 } finally { 10585 Binder.restoreCallingIdentity(origId); 10586 } 10587 } 10588 10589 @Override 10590 public boolean isBackgroundVisibleBehind(IBinder token) { 10591 final long origId = Binder.clearCallingIdentity(); 10592 try { 10593 synchronized (this) { 10594 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10595 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10596 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10597 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10598 return visible; 10599 } 10600 } finally { 10601 Binder.restoreCallingIdentity(origId); 10602 } 10603 } 10604 10605 @Override 10606 public ActivityOptions getActivityOptions(IBinder token) { 10607 final long origId = Binder.clearCallingIdentity(); 10608 try { 10609 synchronized (this) { 10610 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10611 if (r != null) { 10612 final ActivityOptions activityOptions = r.pendingOptions; 10613 r.pendingOptions = null; 10614 return activityOptions; 10615 } 10616 return null; 10617 } 10618 } finally { 10619 Binder.restoreCallingIdentity(origId); 10620 } 10621 } 10622 10623 @Override 10624 public void setImmersive(IBinder token, boolean immersive) { 10625 synchronized(this) { 10626 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10627 if (r == null) { 10628 throw new IllegalArgumentException(); 10629 } 10630 r.immersive = immersive; 10631 10632 // update associated state if we're frontmost 10633 if (r == mFocusedActivity) { 10634 if (DEBUG_IMMERSIVE) { 10635 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10636 } 10637 applyUpdateLockStateLocked(r); 10638 } 10639 } 10640 } 10641 10642 @Override 10643 public boolean isImmersive(IBinder token) { 10644 synchronized (this) { 10645 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10646 if (r == null) { 10647 throw new IllegalArgumentException(); 10648 } 10649 return r.immersive; 10650 } 10651 } 10652 10653 public boolean isTopActivityImmersive() { 10654 enforceNotIsolatedCaller("startActivity"); 10655 synchronized (this) { 10656 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10657 return (r != null) ? r.immersive : false; 10658 } 10659 } 10660 10661 @Override 10662 public boolean isTopOfTask(IBinder token) { 10663 synchronized (this) { 10664 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10665 if (r == null) { 10666 throw new IllegalArgumentException(); 10667 } 10668 return r.task.getTopActivity() == r; 10669 } 10670 } 10671 10672 public final void enterSafeMode() { 10673 synchronized(this) { 10674 // It only makes sense to do this before the system is ready 10675 // and started launching other packages. 10676 if (!mSystemReady) { 10677 try { 10678 AppGlobals.getPackageManager().enterSafeMode(); 10679 } catch (RemoteException e) { 10680 } 10681 } 10682 10683 mSafeMode = true; 10684 } 10685 } 10686 10687 public final void showSafeModeOverlay() { 10688 View v = LayoutInflater.from(mContext).inflate( 10689 com.android.internal.R.layout.safe_mode, null); 10690 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10691 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10692 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10693 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10694 lp.gravity = Gravity.BOTTOM | Gravity.START; 10695 lp.format = v.getBackground().getOpacity(); 10696 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10697 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10698 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10699 ((WindowManager)mContext.getSystemService( 10700 Context.WINDOW_SERVICE)).addView(v, lp); 10701 } 10702 10703 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10704 if (!(sender instanceof PendingIntentRecord)) { 10705 return; 10706 } 10707 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10708 synchronized (stats) { 10709 if (mBatteryStatsService.isOnBattery()) { 10710 mBatteryStatsService.enforceCallingPermission(); 10711 PendingIntentRecord rec = (PendingIntentRecord)sender; 10712 int MY_UID = Binder.getCallingUid(); 10713 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10714 BatteryStatsImpl.Uid.Pkg pkg = 10715 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10716 sourcePkg != null ? sourcePkg : rec.key.packageName); 10717 pkg.incWakeupsLocked(); 10718 } 10719 } 10720 } 10721 10722 public boolean killPids(int[] pids, String pReason, boolean secure) { 10723 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10724 throw new SecurityException("killPids only available to the system"); 10725 } 10726 String reason = (pReason == null) ? "Unknown" : pReason; 10727 // XXX Note: don't acquire main activity lock here, because the window 10728 // manager calls in with its locks held. 10729 10730 boolean killed = false; 10731 synchronized (mPidsSelfLocked) { 10732 int[] types = new int[pids.length]; 10733 int worstType = 0; 10734 for (int i=0; i<pids.length; i++) { 10735 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10736 if (proc != null) { 10737 int type = proc.setAdj; 10738 types[i] = type; 10739 if (type > worstType) { 10740 worstType = type; 10741 } 10742 } 10743 } 10744 10745 // If the worst oom_adj is somewhere in the cached proc LRU range, 10746 // then constrain it so we will kill all cached procs. 10747 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10748 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10749 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10750 } 10751 10752 // If this is not a secure call, don't let it kill processes that 10753 // are important. 10754 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10755 worstType = ProcessList.SERVICE_ADJ; 10756 } 10757 10758 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10759 for (int i=0; i<pids.length; i++) { 10760 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10761 if (proc == null) { 10762 continue; 10763 } 10764 int adj = proc.setAdj; 10765 if (adj >= worstType && !proc.killedByAm) { 10766 proc.kill(reason, true); 10767 killed = true; 10768 } 10769 } 10770 } 10771 return killed; 10772 } 10773 10774 @Override 10775 public void killUid(int uid, String reason) { 10776 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10777 throw new SecurityException("killUid only available to the system"); 10778 } 10779 synchronized (this) { 10780 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10781 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10782 reason != null ? reason : "kill uid"); 10783 } 10784 } 10785 10786 @Override 10787 public boolean killProcessesBelowForeground(String reason) { 10788 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10789 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10790 } 10791 10792 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10793 } 10794 10795 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10796 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10797 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10798 } 10799 10800 boolean killed = false; 10801 synchronized (mPidsSelfLocked) { 10802 final int size = mPidsSelfLocked.size(); 10803 for (int i = 0; i < size; i++) { 10804 final int pid = mPidsSelfLocked.keyAt(i); 10805 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10806 if (proc == null) continue; 10807 10808 final int adj = proc.setAdj; 10809 if (adj > belowAdj && !proc.killedByAm) { 10810 proc.kill(reason, true); 10811 killed = true; 10812 } 10813 } 10814 } 10815 return killed; 10816 } 10817 10818 @Override 10819 public void hang(final IBinder who, boolean allowRestart) { 10820 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10821 != PackageManager.PERMISSION_GRANTED) { 10822 throw new SecurityException("Requires permission " 10823 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10824 } 10825 10826 final IBinder.DeathRecipient death = new DeathRecipient() { 10827 @Override 10828 public void binderDied() { 10829 synchronized (this) { 10830 notifyAll(); 10831 } 10832 } 10833 }; 10834 10835 try { 10836 who.linkToDeath(death, 0); 10837 } catch (RemoteException e) { 10838 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10839 return; 10840 } 10841 10842 synchronized (this) { 10843 Watchdog.getInstance().setAllowRestart(allowRestart); 10844 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10845 synchronized (death) { 10846 while (who.isBinderAlive()) { 10847 try { 10848 death.wait(); 10849 } catch (InterruptedException e) { 10850 } 10851 } 10852 } 10853 Watchdog.getInstance().setAllowRestart(true); 10854 } 10855 } 10856 10857 @Override 10858 public void restart() { 10859 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10860 != PackageManager.PERMISSION_GRANTED) { 10861 throw new SecurityException("Requires permission " 10862 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10863 } 10864 10865 Log.i(TAG, "Sending shutdown broadcast..."); 10866 10867 BroadcastReceiver br = new BroadcastReceiver() { 10868 @Override public void onReceive(Context context, Intent intent) { 10869 // Now the broadcast is done, finish up the low-level shutdown. 10870 Log.i(TAG, "Shutting down activity manager..."); 10871 shutdown(10000); 10872 Log.i(TAG, "Shutdown complete, restarting!"); 10873 Process.killProcess(Process.myPid()); 10874 System.exit(10); 10875 } 10876 }; 10877 10878 // First send the high-level shut down broadcast. 10879 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10880 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10881 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10882 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10883 mContext.sendOrderedBroadcastAsUser(intent, 10884 UserHandle.ALL, null, br, mHandler, 0, null, null); 10885 */ 10886 br.onReceive(mContext, intent); 10887 } 10888 10889 private long getLowRamTimeSinceIdle(long now) { 10890 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10891 } 10892 10893 @Override 10894 public void performIdleMaintenance() { 10895 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10896 != PackageManager.PERMISSION_GRANTED) { 10897 throw new SecurityException("Requires permission " 10898 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10899 } 10900 10901 synchronized (this) { 10902 final long now = SystemClock.uptimeMillis(); 10903 final long timeSinceLastIdle = now - mLastIdleTime; 10904 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10905 mLastIdleTime = now; 10906 mLowRamTimeSinceLastIdle = 0; 10907 if (mLowRamStartTime != 0) { 10908 mLowRamStartTime = now; 10909 } 10910 10911 StringBuilder sb = new StringBuilder(128); 10912 sb.append("Idle maintenance over "); 10913 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10914 sb.append(" low RAM for "); 10915 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10916 Slog.i(TAG, sb.toString()); 10917 10918 // If at least 1/3 of our time since the last idle period has been spent 10919 // with RAM low, then we want to kill processes. 10920 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10921 10922 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10923 ProcessRecord proc = mLruProcesses.get(i); 10924 if (proc.notCachedSinceIdle) { 10925 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10926 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10927 if (doKilling && proc.initialIdlePss != 0 10928 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10929 sb = new StringBuilder(128); 10930 sb.append("Kill"); 10931 sb.append(proc.processName); 10932 sb.append(" in idle maint: pss="); 10933 sb.append(proc.lastPss); 10934 sb.append(", initialPss="); 10935 sb.append(proc.initialIdlePss); 10936 sb.append(", period="); 10937 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10938 sb.append(", lowRamPeriod="); 10939 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10940 Slog.wtfQuiet(TAG, sb.toString()); 10941 proc.kill("idle maint (pss " + proc.lastPss 10942 + " from " + proc.initialIdlePss + ")", true); 10943 } 10944 } 10945 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10946 proc.notCachedSinceIdle = true; 10947 proc.initialIdlePss = 0; 10948 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10949 mTestPssMode, isSleeping(), now); 10950 } 10951 } 10952 10953 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10954 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10955 } 10956 } 10957 10958 private void retrieveSettings() { 10959 final ContentResolver resolver = mContext.getContentResolver(); 10960 String debugApp = Settings.Global.getString( 10961 resolver, Settings.Global.DEBUG_APP); 10962 boolean waitForDebugger = Settings.Global.getInt( 10963 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10964 boolean alwaysFinishActivities = Settings.Global.getInt( 10965 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10966 boolean forceRtl = Settings.Global.getInt( 10967 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10968 // Transfer any global setting for forcing RTL layout, into a System Property 10969 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10970 10971 Configuration configuration = new Configuration(); 10972 Settings.System.getConfiguration(resolver, configuration); 10973 if (forceRtl) { 10974 // This will take care of setting the correct layout direction flags 10975 configuration.setLayoutDirection(configuration.locale); 10976 } 10977 10978 synchronized (this) { 10979 mDebugApp = mOrigDebugApp = debugApp; 10980 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10981 mAlwaysFinishActivities = alwaysFinishActivities; 10982 // This happens before any activities are started, so we can 10983 // change mConfiguration in-place. 10984 updateConfigurationLocked(configuration, null, false, true); 10985 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10986 } 10987 } 10988 10989 /** Loads resources after the current configuration has been set. */ 10990 private void loadResourcesOnSystemReady() { 10991 final Resources res = mContext.getResources(); 10992 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10993 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10994 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10995 } 10996 10997 public boolean testIsSystemReady() { 10998 // no need to synchronize(this) just to read & return the value 10999 return mSystemReady; 11000 } 11001 11002 private static File getCalledPreBootReceiversFile() { 11003 File dataDir = Environment.getDataDirectory(); 11004 File systemDir = new File(dataDir, "system"); 11005 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11006 return fname; 11007 } 11008 11009 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11010 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11011 File file = getCalledPreBootReceiversFile(); 11012 FileInputStream fis = null; 11013 try { 11014 fis = new FileInputStream(file); 11015 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11016 int fvers = dis.readInt(); 11017 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11018 String vers = dis.readUTF(); 11019 String codename = dis.readUTF(); 11020 String build = dis.readUTF(); 11021 if (android.os.Build.VERSION.RELEASE.equals(vers) 11022 && android.os.Build.VERSION.CODENAME.equals(codename) 11023 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11024 int num = dis.readInt(); 11025 while (num > 0) { 11026 num--; 11027 String pkg = dis.readUTF(); 11028 String cls = dis.readUTF(); 11029 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11030 } 11031 } 11032 } 11033 } catch (FileNotFoundException e) { 11034 } catch (IOException e) { 11035 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11036 } finally { 11037 if (fis != null) { 11038 try { 11039 fis.close(); 11040 } catch (IOException e) { 11041 } 11042 } 11043 } 11044 return lastDoneReceivers; 11045 } 11046 11047 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11048 File file = getCalledPreBootReceiversFile(); 11049 FileOutputStream fos = null; 11050 DataOutputStream dos = null; 11051 try { 11052 fos = new FileOutputStream(file); 11053 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11054 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11055 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11056 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11057 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11058 dos.writeInt(list.size()); 11059 for (int i=0; i<list.size(); i++) { 11060 dos.writeUTF(list.get(i).getPackageName()); 11061 dos.writeUTF(list.get(i).getClassName()); 11062 } 11063 } catch (IOException e) { 11064 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11065 file.delete(); 11066 } finally { 11067 FileUtils.sync(fos); 11068 if (dos != null) { 11069 try { 11070 dos.close(); 11071 } catch (IOException e) { 11072 // TODO Auto-generated catch block 11073 e.printStackTrace(); 11074 } 11075 } 11076 } 11077 } 11078 11079 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11080 ArrayList<ComponentName> doneReceivers, int userId) { 11081 boolean waitingUpdate = false; 11082 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11083 List<ResolveInfo> ris = null; 11084 try { 11085 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11086 intent, null, 0, userId); 11087 } catch (RemoteException e) { 11088 } 11089 if (ris != null) { 11090 for (int i=ris.size()-1; i>=0; i--) { 11091 if ((ris.get(i).activityInfo.applicationInfo.flags 11092 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11093 ris.remove(i); 11094 } 11095 } 11096 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11097 11098 // For User 0, load the version number. When delivering to a new user, deliver 11099 // to all receivers. 11100 if (userId == UserHandle.USER_OWNER) { 11101 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11102 for (int i=0; i<ris.size(); i++) { 11103 ActivityInfo ai = ris.get(i).activityInfo; 11104 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11105 if (lastDoneReceivers.contains(comp)) { 11106 // We already did the pre boot receiver for this app with the current 11107 // platform version, so don't do it again... 11108 ris.remove(i); 11109 i--; 11110 // ...however, do keep it as one that has been done, so we don't 11111 // forget about it when rewriting the file of last done receivers. 11112 doneReceivers.add(comp); 11113 } 11114 } 11115 } 11116 11117 // If primary user, send broadcast to all available users, else just to userId 11118 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11119 : new int[] { userId }; 11120 for (int i = 0; i < ris.size(); i++) { 11121 ActivityInfo ai = ris.get(i).activityInfo; 11122 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11123 doneReceivers.add(comp); 11124 intent.setComponent(comp); 11125 for (int j=0; j<users.length; j++) { 11126 IIntentReceiver finisher = null; 11127 // On last receiver and user, set up a completion callback 11128 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11129 finisher = new IIntentReceiver.Stub() { 11130 public void performReceive(Intent intent, int resultCode, 11131 String data, Bundle extras, boolean ordered, 11132 boolean sticky, int sendingUser) { 11133 // The raw IIntentReceiver interface is called 11134 // with the AM lock held, so redispatch to 11135 // execute our code without the lock. 11136 mHandler.post(onFinishCallback); 11137 } 11138 }; 11139 } 11140 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11141 + " for user " + users[j]); 11142 broadcastIntentLocked(null, null, intent, null, finisher, 11143 0, null, null, null, AppOpsManager.OP_NONE, 11144 true, false, MY_PID, Process.SYSTEM_UID, 11145 users[j]); 11146 if (finisher != null) { 11147 waitingUpdate = true; 11148 } 11149 } 11150 } 11151 } 11152 11153 return waitingUpdate; 11154 } 11155 11156 public void systemReady(final Runnable goingCallback) { 11157 synchronized(this) { 11158 if (mSystemReady) { 11159 // If we're done calling all the receivers, run the next "boot phase" passed in 11160 // by the SystemServer 11161 if (goingCallback != null) { 11162 goingCallback.run(); 11163 } 11164 return; 11165 } 11166 11167 // Make sure we have the current profile info, since it is needed for 11168 // security checks. 11169 updateCurrentProfileIdsLocked(); 11170 11171 if (mRecentTasks == null) { 11172 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11173 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11174 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11175 mTaskPersister.startPersisting(); 11176 } 11177 11178 // Check to see if there are any update receivers to run. 11179 if (!mDidUpdate) { 11180 if (mWaitingUpdate) { 11181 return; 11182 } 11183 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11184 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11185 public void run() { 11186 synchronized (ActivityManagerService.this) { 11187 mDidUpdate = true; 11188 } 11189 writeLastDonePreBootReceivers(doneReceivers); 11190 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11191 false); 11192 systemReady(goingCallback); 11193 } 11194 }, doneReceivers, UserHandle.USER_OWNER); 11195 11196 if (mWaitingUpdate) { 11197 return; 11198 } 11199 mDidUpdate = true; 11200 } 11201 11202 mAppOpsService.systemReady(); 11203 mSystemReady = true; 11204 } 11205 11206 ArrayList<ProcessRecord> procsToKill = null; 11207 synchronized(mPidsSelfLocked) { 11208 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11209 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11210 if (!isAllowedWhileBooting(proc.info)){ 11211 if (procsToKill == null) { 11212 procsToKill = new ArrayList<ProcessRecord>(); 11213 } 11214 procsToKill.add(proc); 11215 } 11216 } 11217 } 11218 11219 synchronized(this) { 11220 if (procsToKill != null) { 11221 for (int i=procsToKill.size()-1; i>=0; i--) { 11222 ProcessRecord proc = procsToKill.get(i); 11223 Slog.i(TAG, "Removing system update proc: " + proc); 11224 removeProcessLocked(proc, true, false, "system update done"); 11225 } 11226 } 11227 11228 // Now that we have cleaned up any update processes, we 11229 // are ready to start launching real processes and know that 11230 // we won't trample on them any more. 11231 mProcessesReady = true; 11232 } 11233 11234 Slog.i(TAG, "System now ready"); 11235 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11236 SystemClock.uptimeMillis()); 11237 11238 synchronized(this) { 11239 // Make sure we have no pre-ready processes sitting around. 11240 11241 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11242 ResolveInfo ri = mContext.getPackageManager() 11243 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11244 STOCK_PM_FLAGS); 11245 CharSequence errorMsg = null; 11246 if (ri != null) { 11247 ActivityInfo ai = ri.activityInfo; 11248 ApplicationInfo app = ai.applicationInfo; 11249 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11250 mTopAction = Intent.ACTION_FACTORY_TEST; 11251 mTopData = null; 11252 mTopComponent = new ComponentName(app.packageName, 11253 ai.name); 11254 } else { 11255 errorMsg = mContext.getResources().getText( 11256 com.android.internal.R.string.factorytest_not_system); 11257 } 11258 } else { 11259 errorMsg = mContext.getResources().getText( 11260 com.android.internal.R.string.factorytest_no_action); 11261 } 11262 if (errorMsg != null) { 11263 mTopAction = null; 11264 mTopData = null; 11265 mTopComponent = null; 11266 Message msg = Message.obtain(); 11267 msg.what = SHOW_FACTORY_ERROR_MSG; 11268 msg.getData().putCharSequence("msg", errorMsg); 11269 mHandler.sendMessage(msg); 11270 } 11271 } 11272 } 11273 11274 retrieveSettings(); 11275 loadResourcesOnSystemReady(); 11276 11277 synchronized (this) { 11278 readGrantedUriPermissionsLocked(); 11279 } 11280 11281 if (goingCallback != null) goingCallback.run(); 11282 11283 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11284 Integer.toString(mCurrentUserId), mCurrentUserId); 11285 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11286 Integer.toString(mCurrentUserId), mCurrentUserId); 11287 mSystemServiceManager.startUser(mCurrentUserId); 11288 11289 synchronized (this) { 11290 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11291 try { 11292 List apps = AppGlobals.getPackageManager(). 11293 getPersistentApplications(STOCK_PM_FLAGS); 11294 if (apps != null) { 11295 int N = apps.size(); 11296 int i; 11297 for (i=0; i<N; i++) { 11298 ApplicationInfo info 11299 = (ApplicationInfo)apps.get(i); 11300 if (info != null && 11301 !info.packageName.equals("android")) { 11302 addAppLocked(info, false, null /* ABI override */); 11303 } 11304 } 11305 } 11306 } catch (RemoteException ex) { 11307 // pm is in same process, this will never happen. 11308 } 11309 } 11310 11311 // Start up initial activity. 11312 mBooting = true; 11313 startHomeActivityLocked(mCurrentUserId); 11314 11315 try { 11316 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11317 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11318 + " data partition or your device will be unstable."); 11319 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11320 } 11321 } catch (RemoteException e) { 11322 } 11323 11324 if (!Build.isFingerprintConsistent()) { 11325 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11326 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11327 } 11328 11329 long ident = Binder.clearCallingIdentity(); 11330 try { 11331 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11332 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11333 | Intent.FLAG_RECEIVER_FOREGROUND); 11334 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11335 broadcastIntentLocked(null, null, intent, 11336 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11337 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11338 intent = new Intent(Intent.ACTION_USER_STARTING); 11339 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11340 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11341 broadcastIntentLocked(null, null, intent, 11342 null, new IIntentReceiver.Stub() { 11343 @Override 11344 public void performReceive(Intent intent, int resultCode, String data, 11345 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11346 throws RemoteException { 11347 } 11348 }, 0, null, null, 11349 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11350 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11351 } catch (Throwable t) { 11352 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11353 } finally { 11354 Binder.restoreCallingIdentity(ident); 11355 } 11356 mStackSupervisor.resumeTopActivitiesLocked(); 11357 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11358 } 11359 } 11360 11361 private boolean makeAppCrashingLocked(ProcessRecord app, 11362 String shortMsg, String longMsg, String stackTrace) { 11363 app.crashing = true; 11364 app.crashingReport = generateProcessError(app, 11365 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11366 startAppProblemLocked(app); 11367 app.stopFreezingAllLocked(); 11368 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11369 } 11370 11371 private void makeAppNotRespondingLocked(ProcessRecord app, 11372 String activity, String shortMsg, String longMsg) { 11373 app.notResponding = true; 11374 app.notRespondingReport = generateProcessError(app, 11375 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11376 activity, shortMsg, longMsg, null); 11377 startAppProblemLocked(app); 11378 app.stopFreezingAllLocked(); 11379 } 11380 11381 /** 11382 * Generate a process error record, suitable for attachment to a ProcessRecord. 11383 * 11384 * @param app The ProcessRecord in which the error occurred. 11385 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11386 * ActivityManager.AppErrorStateInfo 11387 * @param activity The activity associated with the crash, if known. 11388 * @param shortMsg Short message describing the crash. 11389 * @param longMsg Long message describing the crash. 11390 * @param stackTrace Full crash stack trace, may be null. 11391 * 11392 * @return Returns a fully-formed AppErrorStateInfo record. 11393 */ 11394 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11395 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11396 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11397 11398 report.condition = condition; 11399 report.processName = app.processName; 11400 report.pid = app.pid; 11401 report.uid = app.info.uid; 11402 report.tag = activity; 11403 report.shortMsg = shortMsg; 11404 report.longMsg = longMsg; 11405 report.stackTrace = stackTrace; 11406 11407 return report; 11408 } 11409 11410 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11411 synchronized (this) { 11412 app.crashing = false; 11413 app.crashingReport = null; 11414 app.notResponding = false; 11415 app.notRespondingReport = null; 11416 if (app.anrDialog == fromDialog) { 11417 app.anrDialog = null; 11418 } 11419 if (app.waitDialog == fromDialog) { 11420 app.waitDialog = null; 11421 } 11422 if (app.pid > 0 && app.pid != MY_PID) { 11423 handleAppCrashLocked(app, null, null, null); 11424 app.kill("user request after error", true); 11425 } 11426 } 11427 } 11428 11429 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11430 String stackTrace) { 11431 long now = SystemClock.uptimeMillis(); 11432 11433 Long crashTime; 11434 if (!app.isolated) { 11435 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11436 } else { 11437 crashTime = null; 11438 } 11439 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11440 // This process loses! 11441 Slog.w(TAG, "Process " + app.info.processName 11442 + " has crashed too many times: killing!"); 11443 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11444 app.userId, app.info.processName, app.uid); 11445 mStackSupervisor.handleAppCrashLocked(app); 11446 if (!app.persistent) { 11447 // We don't want to start this process again until the user 11448 // explicitly does so... but for persistent process, we really 11449 // need to keep it running. If a persistent process is actually 11450 // repeatedly crashing, then badness for everyone. 11451 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11452 app.info.processName); 11453 if (!app.isolated) { 11454 // XXX We don't have a way to mark isolated processes 11455 // as bad, since they don't have a peristent identity. 11456 mBadProcesses.put(app.info.processName, app.uid, 11457 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11458 mProcessCrashTimes.remove(app.info.processName, app.uid); 11459 } 11460 app.bad = true; 11461 app.removed = true; 11462 // Don't let services in this process be restarted and potentially 11463 // annoy the user repeatedly. Unless it is persistent, since those 11464 // processes run critical code. 11465 removeProcessLocked(app, false, false, "crash"); 11466 mStackSupervisor.resumeTopActivitiesLocked(); 11467 return false; 11468 } 11469 mStackSupervisor.resumeTopActivitiesLocked(); 11470 } else { 11471 mStackSupervisor.finishTopRunningActivityLocked(app); 11472 } 11473 11474 // Bump up the crash count of any services currently running in the proc. 11475 for (int i=app.services.size()-1; i>=0; i--) { 11476 // Any services running in the application need to be placed 11477 // back in the pending list. 11478 ServiceRecord sr = app.services.valueAt(i); 11479 sr.crashCount++; 11480 } 11481 11482 // If the crashing process is what we consider to be the "home process" and it has been 11483 // replaced by a third-party app, clear the package preferred activities from packages 11484 // with a home activity running in the process to prevent a repeatedly crashing app 11485 // from blocking the user to manually clear the list. 11486 final ArrayList<ActivityRecord> activities = app.activities; 11487 if (app == mHomeProcess && activities.size() > 0 11488 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11489 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11490 final ActivityRecord r = activities.get(activityNdx); 11491 if (r.isHomeActivity()) { 11492 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11493 try { 11494 ActivityThread.getPackageManager() 11495 .clearPackagePreferredActivities(r.packageName); 11496 } catch (RemoteException c) { 11497 // pm is in same process, this will never happen. 11498 } 11499 } 11500 } 11501 } 11502 11503 if (!app.isolated) { 11504 // XXX Can't keep track of crash times for isolated processes, 11505 // because they don't have a perisistent identity. 11506 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11507 } 11508 11509 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11510 return true; 11511 } 11512 11513 void startAppProblemLocked(ProcessRecord app) { 11514 // If this app is not running under the current user, then we 11515 // can't give it a report button because that would require 11516 // launching the report UI under a different user. 11517 app.errorReportReceiver = null; 11518 11519 for (int userId : mCurrentProfileIds) { 11520 if (app.userId == userId) { 11521 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11522 mContext, app.info.packageName, app.info.flags); 11523 } 11524 } 11525 skipCurrentReceiverLocked(app); 11526 } 11527 11528 void skipCurrentReceiverLocked(ProcessRecord app) { 11529 for (BroadcastQueue queue : mBroadcastQueues) { 11530 queue.skipCurrentReceiverLocked(app); 11531 } 11532 } 11533 11534 /** 11535 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11536 * The application process will exit immediately after this call returns. 11537 * @param app object of the crashing app, null for the system server 11538 * @param crashInfo describing the exception 11539 */ 11540 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11541 ProcessRecord r = findAppProcess(app, "Crash"); 11542 final String processName = app == null ? "system_server" 11543 : (r == null ? "unknown" : r.processName); 11544 11545 handleApplicationCrashInner("crash", r, processName, crashInfo); 11546 } 11547 11548 /* Native crash reporting uses this inner version because it needs to be somewhat 11549 * decoupled from the AM-managed cleanup lifecycle 11550 */ 11551 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11552 ApplicationErrorReport.CrashInfo crashInfo) { 11553 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11554 UserHandle.getUserId(Binder.getCallingUid()), processName, 11555 r == null ? -1 : r.info.flags, 11556 crashInfo.exceptionClassName, 11557 crashInfo.exceptionMessage, 11558 crashInfo.throwFileName, 11559 crashInfo.throwLineNumber); 11560 11561 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11562 11563 crashApplication(r, crashInfo); 11564 } 11565 11566 public void handleApplicationStrictModeViolation( 11567 IBinder app, 11568 int violationMask, 11569 StrictMode.ViolationInfo info) { 11570 ProcessRecord r = findAppProcess(app, "StrictMode"); 11571 if (r == null) { 11572 return; 11573 } 11574 11575 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11576 Integer stackFingerprint = info.hashCode(); 11577 boolean logIt = true; 11578 synchronized (mAlreadyLoggedViolatedStacks) { 11579 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11580 logIt = false; 11581 // TODO: sub-sample into EventLog for these, with 11582 // the info.durationMillis? Then we'd get 11583 // the relative pain numbers, without logging all 11584 // the stack traces repeatedly. We'd want to do 11585 // likewise in the client code, which also does 11586 // dup suppression, before the Binder call. 11587 } else { 11588 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11589 mAlreadyLoggedViolatedStacks.clear(); 11590 } 11591 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11592 } 11593 } 11594 if (logIt) { 11595 logStrictModeViolationToDropBox(r, info); 11596 } 11597 } 11598 11599 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11600 AppErrorResult result = new AppErrorResult(); 11601 synchronized (this) { 11602 final long origId = Binder.clearCallingIdentity(); 11603 11604 Message msg = Message.obtain(); 11605 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11606 HashMap<String, Object> data = new HashMap<String, Object>(); 11607 data.put("result", result); 11608 data.put("app", r); 11609 data.put("violationMask", violationMask); 11610 data.put("info", info); 11611 msg.obj = data; 11612 mHandler.sendMessage(msg); 11613 11614 Binder.restoreCallingIdentity(origId); 11615 } 11616 int res = result.get(); 11617 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11618 } 11619 } 11620 11621 // Depending on the policy in effect, there could be a bunch of 11622 // these in quick succession so we try to batch these together to 11623 // minimize disk writes, number of dropbox entries, and maximize 11624 // compression, by having more fewer, larger records. 11625 private void logStrictModeViolationToDropBox( 11626 ProcessRecord process, 11627 StrictMode.ViolationInfo info) { 11628 if (info == null) { 11629 return; 11630 } 11631 final boolean isSystemApp = process == null || 11632 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11633 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11634 final String processName = process == null ? "unknown" : process.processName; 11635 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11636 final DropBoxManager dbox = (DropBoxManager) 11637 mContext.getSystemService(Context.DROPBOX_SERVICE); 11638 11639 // Exit early if the dropbox isn't configured to accept this report type. 11640 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11641 11642 boolean bufferWasEmpty; 11643 boolean needsFlush; 11644 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11645 synchronized (sb) { 11646 bufferWasEmpty = sb.length() == 0; 11647 appendDropBoxProcessHeaders(process, processName, sb); 11648 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11649 sb.append("System-App: ").append(isSystemApp).append("\n"); 11650 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11651 if (info.violationNumThisLoop != 0) { 11652 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11653 } 11654 if (info.numAnimationsRunning != 0) { 11655 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11656 } 11657 if (info.broadcastIntentAction != null) { 11658 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11659 } 11660 if (info.durationMillis != -1) { 11661 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11662 } 11663 if (info.numInstances != -1) { 11664 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11665 } 11666 if (info.tags != null) { 11667 for (String tag : info.tags) { 11668 sb.append("Span-Tag: ").append(tag).append("\n"); 11669 } 11670 } 11671 sb.append("\n"); 11672 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11673 sb.append(info.crashInfo.stackTrace); 11674 } 11675 sb.append("\n"); 11676 11677 // Only buffer up to ~64k. Various logging bits truncate 11678 // things at 128k. 11679 needsFlush = (sb.length() > 64 * 1024); 11680 } 11681 11682 // Flush immediately if the buffer's grown too large, or this 11683 // is a non-system app. Non-system apps are isolated with a 11684 // different tag & policy and not batched. 11685 // 11686 // Batching is useful during internal testing with 11687 // StrictMode settings turned up high. Without batching, 11688 // thousands of separate files could be created on boot. 11689 if (!isSystemApp || needsFlush) { 11690 new Thread("Error dump: " + dropboxTag) { 11691 @Override 11692 public void run() { 11693 String report; 11694 synchronized (sb) { 11695 report = sb.toString(); 11696 sb.delete(0, sb.length()); 11697 sb.trimToSize(); 11698 } 11699 if (report.length() != 0) { 11700 dbox.addText(dropboxTag, report); 11701 } 11702 } 11703 }.start(); 11704 return; 11705 } 11706 11707 // System app batching: 11708 if (!bufferWasEmpty) { 11709 // An existing dropbox-writing thread is outstanding, so 11710 // we don't need to start it up. The existing thread will 11711 // catch the buffer appends we just did. 11712 return; 11713 } 11714 11715 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11716 // (After this point, we shouldn't access AMS internal data structures.) 11717 new Thread("Error dump: " + dropboxTag) { 11718 @Override 11719 public void run() { 11720 // 5 second sleep to let stacks arrive and be batched together 11721 try { 11722 Thread.sleep(5000); // 5 seconds 11723 } catch (InterruptedException e) {} 11724 11725 String errorReport; 11726 synchronized (mStrictModeBuffer) { 11727 errorReport = mStrictModeBuffer.toString(); 11728 if (errorReport.length() == 0) { 11729 return; 11730 } 11731 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11732 mStrictModeBuffer.trimToSize(); 11733 } 11734 dbox.addText(dropboxTag, errorReport); 11735 } 11736 }.start(); 11737 } 11738 11739 /** 11740 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11741 * @param app object of the crashing app, null for the system server 11742 * @param tag reported by the caller 11743 * @param system whether this wtf is coming from the system 11744 * @param crashInfo describing the context of the error 11745 * @return true if the process should exit immediately (WTF is fatal) 11746 */ 11747 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11748 final ApplicationErrorReport.CrashInfo crashInfo) { 11749 final int callingUid = Binder.getCallingUid(); 11750 final int callingPid = Binder.getCallingPid(); 11751 11752 if (system) { 11753 // If this is coming from the system, we could very well have low-level 11754 // system locks held, so we want to do this all asynchronously. And we 11755 // never want this to become fatal, so there is that too. 11756 mHandler.post(new Runnable() { 11757 @Override public void run() { 11758 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11759 } 11760 }); 11761 return false; 11762 } 11763 11764 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11765 crashInfo); 11766 11767 if (r != null && r.pid != Process.myPid() && 11768 Settings.Global.getInt(mContext.getContentResolver(), 11769 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11770 crashApplication(r, crashInfo); 11771 return true; 11772 } else { 11773 return false; 11774 } 11775 } 11776 11777 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11778 final ApplicationErrorReport.CrashInfo crashInfo) { 11779 final ProcessRecord r = findAppProcess(app, "WTF"); 11780 final String processName = app == null ? "system_server" 11781 : (r == null ? "unknown" : r.processName); 11782 11783 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11784 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11785 11786 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11787 11788 return r; 11789 } 11790 11791 /** 11792 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11793 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11794 */ 11795 private ProcessRecord findAppProcess(IBinder app, String reason) { 11796 if (app == null) { 11797 return null; 11798 } 11799 11800 synchronized (this) { 11801 final int NP = mProcessNames.getMap().size(); 11802 for (int ip=0; ip<NP; ip++) { 11803 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11804 final int NA = apps.size(); 11805 for (int ia=0; ia<NA; ia++) { 11806 ProcessRecord p = apps.valueAt(ia); 11807 if (p.thread != null && p.thread.asBinder() == app) { 11808 return p; 11809 } 11810 } 11811 } 11812 11813 Slog.w(TAG, "Can't find mystery application for " + reason 11814 + " from pid=" + Binder.getCallingPid() 11815 + " uid=" + Binder.getCallingUid() + ": " + app); 11816 return null; 11817 } 11818 } 11819 11820 /** 11821 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11822 * to append various headers to the dropbox log text. 11823 */ 11824 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11825 StringBuilder sb) { 11826 // Watchdog thread ends up invoking this function (with 11827 // a null ProcessRecord) to add the stack file to dropbox. 11828 // Do not acquire a lock on this (am) in such cases, as it 11829 // could cause a potential deadlock, if and when watchdog 11830 // is invoked due to unavailability of lock on am and it 11831 // would prevent watchdog from killing system_server. 11832 if (process == null) { 11833 sb.append("Process: ").append(processName).append("\n"); 11834 return; 11835 } 11836 // Note: ProcessRecord 'process' is guarded by the service 11837 // instance. (notably process.pkgList, which could otherwise change 11838 // concurrently during execution of this method) 11839 synchronized (this) { 11840 sb.append("Process: ").append(processName).append("\n"); 11841 int flags = process.info.flags; 11842 IPackageManager pm = AppGlobals.getPackageManager(); 11843 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11844 for (int ip=0; ip<process.pkgList.size(); ip++) { 11845 String pkg = process.pkgList.keyAt(ip); 11846 sb.append("Package: ").append(pkg); 11847 try { 11848 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11849 if (pi != null) { 11850 sb.append(" v").append(pi.versionCode); 11851 if (pi.versionName != null) { 11852 sb.append(" (").append(pi.versionName).append(")"); 11853 } 11854 } 11855 } catch (RemoteException e) { 11856 Slog.e(TAG, "Error getting package info: " + pkg, e); 11857 } 11858 sb.append("\n"); 11859 } 11860 } 11861 } 11862 11863 private static String processClass(ProcessRecord process) { 11864 if (process == null || process.pid == MY_PID) { 11865 return "system_server"; 11866 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11867 return "system_app"; 11868 } else { 11869 return "data_app"; 11870 } 11871 } 11872 11873 /** 11874 * Write a description of an error (crash, WTF, ANR) to the drop box. 11875 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11876 * @param process which caused the error, null means the system server 11877 * @param activity which triggered the error, null if unknown 11878 * @param parent activity related to the error, null if unknown 11879 * @param subject line related to the error, null if absent 11880 * @param report in long form describing the error, null if absent 11881 * @param logFile to include in the report, null if none 11882 * @param crashInfo giving an application stack trace, null if absent 11883 */ 11884 public void addErrorToDropBox(String eventType, 11885 ProcessRecord process, String processName, ActivityRecord activity, 11886 ActivityRecord parent, String subject, 11887 final String report, final File logFile, 11888 final ApplicationErrorReport.CrashInfo crashInfo) { 11889 // NOTE -- this must never acquire the ActivityManagerService lock, 11890 // otherwise the watchdog may be prevented from resetting the system. 11891 11892 final String dropboxTag = processClass(process) + "_" + eventType; 11893 final DropBoxManager dbox = (DropBoxManager) 11894 mContext.getSystemService(Context.DROPBOX_SERVICE); 11895 11896 // Exit early if the dropbox isn't configured to accept this report type. 11897 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11898 11899 final StringBuilder sb = new StringBuilder(1024); 11900 appendDropBoxProcessHeaders(process, processName, sb); 11901 if (activity != null) { 11902 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11903 } 11904 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11905 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11906 } 11907 if (parent != null && parent != activity) { 11908 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11909 } 11910 if (subject != null) { 11911 sb.append("Subject: ").append(subject).append("\n"); 11912 } 11913 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11914 if (Debug.isDebuggerConnected()) { 11915 sb.append("Debugger: Connected\n"); 11916 } 11917 sb.append("\n"); 11918 11919 // Do the rest in a worker thread to avoid blocking the caller on I/O 11920 // (After this point, we shouldn't access AMS internal data structures.) 11921 Thread worker = new Thread("Error dump: " + dropboxTag) { 11922 @Override 11923 public void run() { 11924 if (report != null) { 11925 sb.append(report); 11926 } 11927 if (logFile != null) { 11928 try { 11929 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11930 "\n\n[[TRUNCATED]]")); 11931 } catch (IOException e) { 11932 Slog.e(TAG, "Error reading " + logFile, e); 11933 } 11934 } 11935 if (crashInfo != null && crashInfo.stackTrace != null) { 11936 sb.append(crashInfo.stackTrace); 11937 } 11938 11939 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11940 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11941 if (lines > 0) { 11942 sb.append("\n"); 11943 11944 // Merge several logcat streams, and take the last N lines 11945 InputStreamReader input = null; 11946 try { 11947 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11948 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11949 "-b", "crash", 11950 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11951 11952 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11953 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11954 input = new InputStreamReader(logcat.getInputStream()); 11955 11956 int num; 11957 char[] buf = new char[8192]; 11958 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11959 } catch (IOException e) { 11960 Slog.e(TAG, "Error running logcat", e); 11961 } finally { 11962 if (input != null) try { input.close(); } catch (IOException e) {} 11963 } 11964 } 11965 11966 dbox.addText(dropboxTag, sb.toString()); 11967 } 11968 }; 11969 11970 if (process == null) { 11971 // If process is null, we are being called from some internal code 11972 // and may be about to die -- run this synchronously. 11973 worker.run(); 11974 } else { 11975 worker.start(); 11976 } 11977 } 11978 11979 /** 11980 * Bring up the "unexpected error" dialog box for a crashing app. 11981 * Deal with edge cases (intercepts from instrumented applications, 11982 * ActivityController, error intent receivers, that sort of thing). 11983 * @param r the application crashing 11984 * @param crashInfo describing the failure 11985 */ 11986 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11987 long timeMillis = System.currentTimeMillis(); 11988 String shortMsg = crashInfo.exceptionClassName; 11989 String longMsg = crashInfo.exceptionMessage; 11990 String stackTrace = crashInfo.stackTrace; 11991 if (shortMsg != null && longMsg != null) { 11992 longMsg = shortMsg + ": " + longMsg; 11993 } else if (shortMsg != null) { 11994 longMsg = shortMsg; 11995 } 11996 11997 AppErrorResult result = new AppErrorResult(); 11998 synchronized (this) { 11999 if (mController != null) { 12000 try { 12001 String name = r != null ? r.processName : null; 12002 int pid = r != null ? r.pid : Binder.getCallingPid(); 12003 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12004 if (!mController.appCrashed(name, pid, 12005 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12006 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12007 && "Native crash".equals(crashInfo.exceptionClassName)) { 12008 Slog.w(TAG, "Skip killing native crashed app " + name 12009 + "(" + pid + ") during testing"); 12010 } else { 12011 Slog.w(TAG, "Force-killing crashed app " + name 12012 + " at watcher's request"); 12013 if (r != null) { 12014 r.kill("crash", true); 12015 } else { 12016 // Huh. 12017 Process.killProcess(pid); 12018 Process.killProcessGroup(uid, pid); 12019 } 12020 } 12021 return; 12022 } 12023 } catch (RemoteException e) { 12024 mController = null; 12025 Watchdog.getInstance().setActivityController(null); 12026 } 12027 } 12028 12029 final long origId = Binder.clearCallingIdentity(); 12030 12031 // If this process is running instrumentation, finish it. 12032 if (r != null && r.instrumentationClass != null) { 12033 Slog.w(TAG, "Error in app " + r.processName 12034 + " running instrumentation " + r.instrumentationClass + ":"); 12035 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12036 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12037 Bundle info = new Bundle(); 12038 info.putString("shortMsg", shortMsg); 12039 info.putString("longMsg", longMsg); 12040 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12041 Binder.restoreCallingIdentity(origId); 12042 return; 12043 } 12044 12045 // Log crash in battery stats. 12046 if (r != null) { 12047 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12048 } 12049 12050 // If we can't identify the process or it's already exceeded its crash quota, 12051 // quit right away without showing a crash dialog. 12052 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12053 Binder.restoreCallingIdentity(origId); 12054 return; 12055 } 12056 12057 Message msg = Message.obtain(); 12058 msg.what = SHOW_ERROR_MSG; 12059 HashMap data = new HashMap(); 12060 data.put("result", result); 12061 data.put("app", r); 12062 msg.obj = data; 12063 mHandler.sendMessage(msg); 12064 12065 Binder.restoreCallingIdentity(origId); 12066 } 12067 12068 int res = result.get(); 12069 12070 Intent appErrorIntent = null; 12071 synchronized (this) { 12072 if (r != null && !r.isolated) { 12073 // XXX Can't keep track of crash time for isolated processes, 12074 // since they don't have a persistent identity. 12075 mProcessCrashTimes.put(r.info.processName, r.uid, 12076 SystemClock.uptimeMillis()); 12077 } 12078 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12079 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12080 } 12081 } 12082 12083 if (appErrorIntent != null) { 12084 try { 12085 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12086 } catch (ActivityNotFoundException e) { 12087 Slog.w(TAG, "bug report receiver dissappeared", e); 12088 } 12089 } 12090 } 12091 12092 Intent createAppErrorIntentLocked(ProcessRecord r, 12093 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12094 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12095 if (report == null) { 12096 return null; 12097 } 12098 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12099 result.setComponent(r.errorReportReceiver); 12100 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12101 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12102 return result; 12103 } 12104 12105 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12106 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12107 if (r.errorReportReceiver == null) { 12108 return null; 12109 } 12110 12111 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12112 return null; 12113 } 12114 12115 ApplicationErrorReport report = new ApplicationErrorReport(); 12116 report.packageName = r.info.packageName; 12117 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12118 report.processName = r.processName; 12119 report.time = timeMillis; 12120 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12121 12122 if (r.crashing || r.forceCrashReport) { 12123 report.type = ApplicationErrorReport.TYPE_CRASH; 12124 report.crashInfo = crashInfo; 12125 } else if (r.notResponding) { 12126 report.type = ApplicationErrorReport.TYPE_ANR; 12127 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12128 12129 report.anrInfo.activity = r.notRespondingReport.tag; 12130 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12131 report.anrInfo.info = r.notRespondingReport.longMsg; 12132 } 12133 12134 return report; 12135 } 12136 12137 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12138 enforceNotIsolatedCaller("getProcessesInErrorState"); 12139 // assume our apps are happy - lazy create the list 12140 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12141 12142 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12143 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12144 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12145 12146 synchronized (this) { 12147 12148 // iterate across all processes 12149 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12150 ProcessRecord app = mLruProcesses.get(i); 12151 if (!allUsers && app.userId != userId) { 12152 continue; 12153 } 12154 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12155 // This one's in trouble, so we'll generate a report for it 12156 // crashes are higher priority (in case there's a crash *and* an anr) 12157 ActivityManager.ProcessErrorStateInfo report = null; 12158 if (app.crashing) { 12159 report = app.crashingReport; 12160 } else if (app.notResponding) { 12161 report = app.notRespondingReport; 12162 } 12163 12164 if (report != null) { 12165 if (errList == null) { 12166 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12167 } 12168 errList.add(report); 12169 } else { 12170 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12171 " crashing = " + app.crashing + 12172 " notResponding = " + app.notResponding); 12173 } 12174 } 12175 } 12176 } 12177 12178 return errList; 12179 } 12180 12181 static int procStateToImportance(int procState, int memAdj, 12182 ActivityManager.RunningAppProcessInfo currApp) { 12183 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12184 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12185 currApp.lru = memAdj; 12186 } else { 12187 currApp.lru = 0; 12188 } 12189 return imp; 12190 } 12191 12192 private void fillInProcMemInfo(ProcessRecord app, 12193 ActivityManager.RunningAppProcessInfo outInfo) { 12194 outInfo.pid = app.pid; 12195 outInfo.uid = app.info.uid; 12196 if (mHeavyWeightProcess == app) { 12197 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12198 } 12199 if (app.persistent) { 12200 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12201 } 12202 if (app.activities.size() > 0) { 12203 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12204 } 12205 outInfo.lastTrimLevel = app.trimMemoryLevel; 12206 int adj = app.curAdj; 12207 int procState = app.curProcState; 12208 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12209 outInfo.importanceReasonCode = app.adjTypeCode; 12210 outInfo.processState = app.curProcState; 12211 } 12212 12213 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12214 enforceNotIsolatedCaller("getRunningAppProcesses"); 12215 // Lazy instantiation of list 12216 List<ActivityManager.RunningAppProcessInfo> runList = null; 12217 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12218 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12219 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12220 synchronized (this) { 12221 // Iterate across all processes 12222 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12223 ProcessRecord app = mLruProcesses.get(i); 12224 if (!allUsers && app.userId != userId) { 12225 continue; 12226 } 12227 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12228 // Generate process state info for running application 12229 ActivityManager.RunningAppProcessInfo currApp = 12230 new ActivityManager.RunningAppProcessInfo(app.processName, 12231 app.pid, app.getPackageList()); 12232 fillInProcMemInfo(app, currApp); 12233 if (app.adjSource instanceof ProcessRecord) { 12234 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12235 currApp.importanceReasonImportance = 12236 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12237 app.adjSourceProcState); 12238 } else if (app.adjSource instanceof ActivityRecord) { 12239 ActivityRecord r = (ActivityRecord)app.adjSource; 12240 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12241 } 12242 if (app.adjTarget instanceof ComponentName) { 12243 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12244 } 12245 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12246 // + " lru=" + currApp.lru); 12247 if (runList == null) { 12248 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12249 } 12250 runList.add(currApp); 12251 } 12252 } 12253 } 12254 return runList; 12255 } 12256 12257 public List<ApplicationInfo> getRunningExternalApplications() { 12258 enforceNotIsolatedCaller("getRunningExternalApplications"); 12259 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12260 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12261 if (runningApps != null && runningApps.size() > 0) { 12262 Set<String> extList = new HashSet<String>(); 12263 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12264 if (app.pkgList != null) { 12265 for (String pkg : app.pkgList) { 12266 extList.add(pkg); 12267 } 12268 } 12269 } 12270 IPackageManager pm = AppGlobals.getPackageManager(); 12271 for (String pkg : extList) { 12272 try { 12273 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12274 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12275 retList.add(info); 12276 } 12277 } catch (RemoteException e) { 12278 } 12279 } 12280 } 12281 return retList; 12282 } 12283 12284 @Override 12285 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12286 enforceNotIsolatedCaller("getMyMemoryState"); 12287 synchronized (this) { 12288 ProcessRecord proc; 12289 synchronized (mPidsSelfLocked) { 12290 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12291 } 12292 fillInProcMemInfo(proc, outInfo); 12293 } 12294 } 12295 12296 @Override 12297 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12298 if (checkCallingPermission(android.Manifest.permission.DUMP) 12299 != PackageManager.PERMISSION_GRANTED) { 12300 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12301 + Binder.getCallingPid() 12302 + ", uid=" + Binder.getCallingUid() 12303 + " without permission " 12304 + android.Manifest.permission.DUMP); 12305 return; 12306 } 12307 12308 boolean dumpAll = false; 12309 boolean dumpClient = false; 12310 String dumpPackage = null; 12311 12312 int opti = 0; 12313 while (opti < args.length) { 12314 String opt = args[opti]; 12315 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12316 break; 12317 } 12318 opti++; 12319 if ("-a".equals(opt)) { 12320 dumpAll = true; 12321 } else if ("-c".equals(opt)) { 12322 dumpClient = true; 12323 } else if ("-h".equals(opt)) { 12324 pw.println("Activity manager dump options:"); 12325 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12326 pw.println(" cmd may be one of:"); 12327 pw.println(" a[ctivities]: activity stack state"); 12328 pw.println(" r[recents]: recent activities state"); 12329 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12330 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12331 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12332 pw.println(" o[om]: out of memory management"); 12333 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12334 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12335 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12336 pw.println(" service [COMP_SPEC]: service client-side state"); 12337 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12338 pw.println(" all: dump all activities"); 12339 pw.println(" top: dump the top activity"); 12340 pw.println(" write: write all pending state to storage"); 12341 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12342 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12343 pw.println(" a partial substring in a component name, a"); 12344 pw.println(" hex object identifier."); 12345 pw.println(" -a: include all available server state."); 12346 pw.println(" -c: include client state."); 12347 return; 12348 } else { 12349 pw.println("Unknown argument: " + opt + "; use -h for help"); 12350 } 12351 } 12352 12353 long origId = Binder.clearCallingIdentity(); 12354 boolean more = false; 12355 // Is the caller requesting to dump a particular piece of data? 12356 if (opti < args.length) { 12357 String cmd = args[opti]; 12358 opti++; 12359 if ("activities".equals(cmd) || "a".equals(cmd)) { 12360 synchronized (this) { 12361 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12362 } 12363 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12364 synchronized (this) { 12365 dumpRecentsLocked(fd, pw, args, opti, true, null); 12366 } 12367 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12368 String[] newArgs; 12369 String name; 12370 if (opti >= args.length) { 12371 name = null; 12372 newArgs = EMPTY_STRING_ARRAY; 12373 } else { 12374 name = args[opti]; 12375 opti++; 12376 newArgs = new String[args.length - opti]; 12377 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12378 args.length - opti); 12379 } 12380 synchronized (this) { 12381 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12382 } 12383 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12384 String[] newArgs; 12385 String name; 12386 if (opti >= args.length) { 12387 name = null; 12388 newArgs = EMPTY_STRING_ARRAY; 12389 } else { 12390 name = args[opti]; 12391 opti++; 12392 newArgs = new String[args.length - opti]; 12393 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12394 args.length - opti); 12395 } 12396 synchronized (this) { 12397 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12398 } 12399 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12400 String[] newArgs; 12401 String name; 12402 if (opti >= args.length) { 12403 name = null; 12404 newArgs = EMPTY_STRING_ARRAY; 12405 } else { 12406 name = args[opti]; 12407 opti++; 12408 newArgs = new String[args.length - opti]; 12409 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12410 args.length - opti); 12411 } 12412 synchronized (this) { 12413 dumpProcessesLocked(fd, pw, args, opti, true, name); 12414 } 12415 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12416 synchronized (this) { 12417 dumpOomLocked(fd, pw, args, opti, true); 12418 } 12419 } else if ("provider".equals(cmd)) { 12420 String[] newArgs; 12421 String name; 12422 if (opti >= args.length) { 12423 name = null; 12424 newArgs = EMPTY_STRING_ARRAY; 12425 } else { 12426 name = args[opti]; 12427 opti++; 12428 newArgs = new String[args.length - opti]; 12429 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12430 } 12431 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12432 pw.println("No providers match: " + name); 12433 pw.println("Use -h for help."); 12434 } 12435 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12436 synchronized (this) { 12437 dumpProvidersLocked(fd, pw, args, opti, true, null); 12438 } 12439 } else if ("service".equals(cmd)) { 12440 String[] newArgs; 12441 String name; 12442 if (opti >= args.length) { 12443 name = null; 12444 newArgs = EMPTY_STRING_ARRAY; 12445 } else { 12446 name = args[opti]; 12447 opti++; 12448 newArgs = new String[args.length - opti]; 12449 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12450 args.length - opti); 12451 } 12452 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12453 pw.println("No services match: " + name); 12454 pw.println("Use -h for help."); 12455 } 12456 } else if ("package".equals(cmd)) { 12457 String[] newArgs; 12458 if (opti >= args.length) { 12459 pw.println("package: no package name specified"); 12460 pw.println("Use -h for help."); 12461 } else { 12462 dumpPackage = args[opti]; 12463 opti++; 12464 newArgs = new String[args.length - opti]; 12465 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12466 args.length - opti); 12467 args = newArgs; 12468 opti = 0; 12469 more = true; 12470 } 12471 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12472 synchronized (this) { 12473 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12474 } 12475 } else if ("write".equals(cmd)) { 12476 mTaskPersister.flush(); 12477 pw.println("All tasks persisted."); 12478 return; 12479 } else { 12480 // Dumping a single activity? 12481 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12482 pw.println("Bad activity command, or no activities match: " + cmd); 12483 pw.println("Use -h for help."); 12484 } 12485 } 12486 if (!more) { 12487 Binder.restoreCallingIdentity(origId); 12488 return; 12489 } 12490 } 12491 12492 // No piece of data specified, dump everything. 12493 synchronized (this) { 12494 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12495 pw.println(); 12496 if (dumpAll) { 12497 pw.println("-------------------------------------------------------------------------------"); 12498 } 12499 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12500 pw.println(); 12501 if (dumpAll) { 12502 pw.println("-------------------------------------------------------------------------------"); 12503 } 12504 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12505 pw.println(); 12506 if (dumpAll) { 12507 pw.println("-------------------------------------------------------------------------------"); 12508 } 12509 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12510 pw.println(); 12511 if (dumpAll) { 12512 pw.println("-------------------------------------------------------------------------------"); 12513 } 12514 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12515 pw.println(); 12516 if (dumpAll) { 12517 pw.println("-------------------------------------------------------------------------------"); 12518 } 12519 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12520 pw.println(); 12521 if (dumpAll) { 12522 pw.println("-------------------------------------------------------------------------------"); 12523 } 12524 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12525 } 12526 Binder.restoreCallingIdentity(origId); 12527 } 12528 12529 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12530 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12531 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12532 12533 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12534 dumpPackage); 12535 boolean needSep = printedAnything; 12536 12537 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12538 dumpPackage, needSep, " mFocusedActivity: "); 12539 if (printed) { 12540 printedAnything = true; 12541 needSep = false; 12542 } 12543 12544 if (dumpPackage == null) { 12545 if (needSep) { 12546 pw.println(); 12547 } 12548 needSep = true; 12549 printedAnything = true; 12550 mStackSupervisor.dump(pw, " "); 12551 } 12552 12553 if (!printedAnything) { 12554 pw.println(" (nothing)"); 12555 } 12556 } 12557 12558 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12559 int opti, boolean dumpAll, String dumpPackage) { 12560 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12561 12562 boolean printedAnything = false; 12563 12564 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12565 boolean printedHeader = false; 12566 12567 final int N = mRecentTasks.size(); 12568 for (int i=0; i<N; i++) { 12569 TaskRecord tr = mRecentTasks.get(i); 12570 if (dumpPackage != null) { 12571 if (tr.realActivity == null || 12572 !dumpPackage.equals(tr.realActivity)) { 12573 continue; 12574 } 12575 } 12576 if (!printedHeader) { 12577 pw.println(" Recent tasks:"); 12578 printedHeader = true; 12579 printedAnything = true; 12580 } 12581 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12582 pw.println(tr); 12583 if (dumpAll) { 12584 mRecentTasks.get(i).dump(pw, " "); 12585 } 12586 } 12587 } 12588 12589 if (!printedAnything) { 12590 pw.println(" (nothing)"); 12591 } 12592 } 12593 12594 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12595 int opti, boolean dumpAll, String dumpPackage) { 12596 boolean needSep = false; 12597 boolean printedAnything = false; 12598 int numPers = 0; 12599 12600 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12601 12602 if (dumpAll) { 12603 final int NP = mProcessNames.getMap().size(); 12604 for (int ip=0; ip<NP; ip++) { 12605 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12606 final int NA = procs.size(); 12607 for (int ia=0; ia<NA; ia++) { 12608 ProcessRecord r = procs.valueAt(ia); 12609 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12610 continue; 12611 } 12612 if (!needSep) { 12613 pw.println(" All known processes:"); 12614 needSep = true; 12615 printedAnything = true; 12616 } 12617 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12618 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12619 pw.print(" "); pw.println(r); 12620 r.dump(pw, " "); 12621 if (r.persistent) { 12622 numPers++; 12623 } 12624 } 12625 } 12626 } 12627 12628 if (mIsolatedProcesses.size() > 0) { 12629 boolean printed = false; 12630 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12631 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12632 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12633 continue; 12634 } 12635 if (!printed) { 12636 if (needSep) { 12637 pw.println(); 12638 } 12639 pw.println(" Isolated process list (sorted by uid):"); 12640 printedAnything = true; 12641 printed = true; 12642 needSep = true; 12643 } 12644 pw.println(String.format("%sIsolated #%2d: %s", 12645 " ", i, r.toString())); 12646 } 12647 } 12648 12649 if (mLruProcesses.size() > 0) { 12650 if (needSep) { 12651 pw.println(); 12652 } 12653 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12654 pw.print(" total, non-act at "); 12655 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12656 pw.print(", non-svc at "); 12657 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12658 pw.println("):"); 12659 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12660 needSep = true; 12661 printedAnything = true; 12662 } 12663 12664 if (dumpAll || dumpPackage != null) { 12665 synchronized (mPidsSelfLocked) { 12666 boolean printed = false; 12667 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12668 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12669 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12670 continue; 12671 } 12672 if (!printed) { 12673 if (needSep) pw.println(); 12674 needSep = true; 12675 pw.println(" PID mappings:"); 12676 printed = true; 12677 printedAnything = true; 12678 } 12679 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12680 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12681 } 12682 } 12683 } 12684 12685 if (mForegroundProcesses.size() > 0) { 12686 synchronized (mPidsSelfLocked) { 12687 boolean printed = false; 12688 for (int i=0; i<mForegroundProcesses.size(); i++) { 12689 ProcessRecord r = mPidsSelfLocked.get( 12690 mForegroundProcesses.valueAt(i).pid); 12691 if (dumpPackage != null && (r == null 12692 || !r.pkgList.containsKey(dumpPackage))) { 12693 continue; 12694 } 12695 if (!printed) { 12696 if (needSep) pw.println(); 12697 needSep = true; 12698 pw.println(" Foreground Processes:"); 12699 printed = true; 12700 printedAnything = true; 12701 } 12702 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12703 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12704 } 12705 } 12706 } 12707 12708 if (mPersistentStartingProcesses.size() > 0) { 12709 if (needSep) pw.println(); 12710 needSep = true; 12711 printedAnything = true; 12712 pw.println(" Persisent processes that are starting:"); 12713 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12714 "Starting Norm", "Restarting PERS", dumpPackage); 12715 } 12716 12717 if (mRemovedProcesses.size() > 0) { 12718 if (needSep) pw.println(); 12719 needSep = true; 12720 printedAnything = true; 12721 pw.println(" Processes that are being removed:"); 12722 dumpProcessList(pw, this, mRemovedProcesses, " ", 12723 "Removed Norm", "Removed PERS", dumpPackage); 12724 } 12725 12726 if (mProcessesOnHold.size() > 0) { 12727 if (needSep) pw.println(); 12728 needSep = true; 12729 printedAnything = true; 12730 pw.println(" Processes that are on old until the system is ready:"); 12731 dumpProcessList(pw, this, mProcessesOnHold, " ", 12732 "OnHold Norm", "OnHold PERS", dumpPackage); 12733 } 12734 12735 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12736 12737 if (mProcessCrashTimes.getMap().size() > 0) { 12738 boolean printed = false; 12739 long now = SystemClock.uptimeMillis(); 12740 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12741 final int NP = pmap.size(); 12742 for (int ip=0; ip<NP; ip++) { 12743 String pname = pmap.keyAt(ip); 12744 SparseArray<Long> uids = pmap.valueAt(ip); 12745 final int N = uids.size(); 12746 for (int i=0; i<N; i++) { 12747 int puid = uids.keyAt(i); 12748 ProcessRecord r = mProcessNames.get(pname, puid); 12749 if (dumpPackage != null && (r == null 12750 || !r.pkgList.containsKey(dumpPackage))) { 12751 continue; 12752 } 12753 if (!printed) { 12754 if (needSep) pw.println(); 12755 needSep = true; 12756 pw.println(" Time since processes crashed:"); 12757 printed = true; 12758 printedAnything = true; 12759 } 12760 pw.print(" Process "); pw.print(pname); 12761 pw.print(" uid "); pw.print(puid); 12762 pw.print(": last crashed "); 12763 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12764 pw.println(" ago"); 12765 } 12766 } 12767 } 12768 12769 if (mBadProcesses.getMap().size() > 0) { 12770 boolean printed = false; 12771 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12772 final int NP = pmap.size(); 12773 for (int ip=0; ip<NP; ip++) { 12774 String pname = pmap.keyAt(ip); 12775 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12776 final int N = uids.size(); 12777 for (int i=0; i<N; i++) { 12778 int puid = uids.keyAt(i); 12779 ProcessRecord r = mProcessNames.get(pname, puid); 12780 if (dumpPackage != null && (r == null 12781 || !r.pkgList.containsKey(dumpPackage))) { 12782 continue; 12783 } 12784 if (!printed) { 12785 if (needSep) pw.println(); 12786 needSep = true; 12787 pw.println(" Bad processes:"); 12788 printedAnything = true; 12789 } 12790 BadProcessInfo info = uids.valueAt(i); 12791 pw.print(" Bad process "); pw.print(pname); 12792 pw.print(" uid "); pw.print(puid); 12793 pw.print(": crashed at time "); pw.println(info.time); 12794 if (info.shortMsg != null) { 12795 pw.print(" Short msg: "); pw.println(info.shortMsg); 12796 } 12797 if (info.longMsg != null) { 12798 pw.print(" Long msg: "); pw.println(info.longMsg); 12799 } 12800 if (info.stack != null) { 12801 pw.println(" Stack:"); 12802 int lastPos = 0; 12803 for (int pos=0; pos<info.stack.length(); pos++) { 12804 if (info.stack.charAt(pos) == '\n') { 12805 pw.print(" "); 12806 pw.write(info.stack, lastPos, pos-lastPos); 12807 pw.println(); 12808 lastPos = pos+1; 12809 } 12810 } 12811 if (lastPos < info.stack.length()) { 12812 pw.print(" "); 12813 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12814 pw.println(); 12815 } 12816 } 12817 } 12818 } 12819 } 12820 12821 if (dumpPackage == null) { 12822 pw.println(); 12823 needSep = false; 12824 pw.println(" mStartedUsers:"); 12825 for (int i=0; i<mStartedUsers.size(); i++) { 12826 UserStartedState uss = mStartedUsers.valueAt(i); 12827 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12828 pw.print(": "); uss.dump("", pw); 12829 } 12830 pw.print(" mStartedUserArray: ["); 12831 for (int i=0; i<mStartedUserArray.length; i++) { 12832 if (i > 0) pw.print(", "); 12833 pw.print(mStartedUserArray[i]); 12834 } 12835 pw.println("]"); 12836 pw.print(" mUserLru: ["); 12837 for (int i=0; i<mUserLru.size(); i++) { 12838 if (i > 0) pw.print(", "); 12839 pw.print(mUserLru.get(i)); 12840 } 12841 pw.println("]"); 12842 if (dumpAll) { 12843 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12844 } 12845 synchronized (mUserProfileGroupIdsSelfLocked) { 12846 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12847 pw.println(" mUserProfileGroupIds:"); 12848 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12849 pw.print(" User #"); 12850 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12851 pw.print(" -> profile #"); 12852 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12853 } 12854 } 12855 } 12856 } 12857 if (mHomeProcess != null && (dumpPackage == null 12858 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12859 if (needSep) { 12860 pw.println(); 12861 needSep = false; 12862 } 12863 pw.println(" mHomeProcess: " + mHomeProcess); 12864 } 12865 if (mPreviousProcess != null && (dumpPackage == null 12866 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12867 if (needSep) { 12868 pw.println(); 12869 needSep = false; 12870 } 12871 pw.println(" mPreviousProcess: " + mPreviousProcess); 12872 } 12873 if (dumpAll) { 12874 StringBuilder sb = new StringBuilder(128); 12875 sb.append(" mPreviousProcessVisibleTime: "); 12876 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12877 pw.println(sb); 12878 } 12879 if (mHeavyWeightProcess != null && (dumpPackage == null 12880 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12881 if (needSep) { 12882 pw.println(); 12883 needSep = false; 12884 } 12885 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12886 } 12887 if (dumpPackage == null) { 12888 pw.println(" mConfiguration: " + mConfiguration); 12889 } 12890 if (dumpAll) { 12891 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12892 if (mCompatModePackages.getPackages().size() > 0) { 12893 boolean printed = false; 12894 for (Map.Entry<String, Integer> entry 12895 : mCompatModePackages.getPackages().entrySet()) { 12896 String pkg = entry.getKey(); 12897 int mode = entry.getValue(); 12898 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12899 continue; 12900 } 12901 if (!printed) { 12902 pw.println(" mScreenCompatPackages:"); 12903 printed = true; 12904 } 12905 pw.print(" "); pw.print(pkg); pw.print(": "); 12906 pw.print(mode); pw.println(); 12907 } 12908 } 12909 } 12910 if (dumpPackage == null) { 12911 pw.println(" mWakefulness=" 12912 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12913 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12914 + lockScreenShownToString()); 12915 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 12916 + " mTestPssMode=" + mTestPssMode); 12917 } 12918 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12919 || mOrigWaitForDebugger) { 12920 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12921 || dumpPackage.equals(mOrigDebugApp)) { 12922 if (needSep) { 12923 pw.println(); 12924 needSep = false; 12925 } 12926 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12927 + " mDebugTransient=" + mDebugTransient 12928 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12929 } 12930 } 12931 if (mOpenGlTraceApp != null) { 12932 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12933 if (needSep) { 12934 pw.println(); 12935 needSep = false; 12936 } 12937 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12938 } 12939 } 12940 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12941 || mProfileFd != null) { 12942 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12943 if (needSep) { 12944 pw.println(); 12945 needSep = false; 12946 } 12947 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12948 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12949 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12950 + mAutoStopProfiler); 12951 pw.println(" mProfileType=" + mProfileType); 12952 } 12953 } 12954 if (dumpPackage == null) { 12955 if (mAlwaysFinishActivities || mController != null) { 12956 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12957 + " mController=" + mController); 12958 } 12959 if (dumpAll) { 12960 pw.println(" Total persistent processes: " + numPers); 12961 pw.println(" mProcessesReady=" + mProcessesReady 12962 + " mSystemReady=" + mSystemReady 12963 + " mBooted=" + mBooted 12964 + " mFactoryTest=" + mFactoryTest); 12965 pw.println(" mBooting=" + mBooting 12966 + " mCallFinishBooting=" + mCallFinishBooting 12967 + " mBootAnimationComplete=" + mBootAnimationComplete); 12968 pw.print(" mLastPowerCheckRealtime="); 12969 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12970 pw.println(""); 12971 pw.print(" mLastPowerCheckUptime="); 12972 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12973 pw.println(""); 12974 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12975 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12976 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12977 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12978 + " (" + mLruProcesses.size() + " total)" 12979 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12980 + " mNumServiceProcs=" + mNumServiceProcs 12981 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12982 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12983 + " mLastMemoryLevel" + mLastMemoryLevel 12984 + " mLastNumProcesses" + mLastNumProcesses); 12985 long now = SystemClock.uptimeMillis(); 12986 pw.print(" mLastIdleTime="); 12987 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12988 pw.print(" mLowRamSinceLastIdle="); 12989 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12990 pw.println(); 12991 } 12992 } 12993 12994 if (!printedAnything) { 12995 pw.println(" (nothing)"); 12996 } 12997 } 12998 12999 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13000 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13001 if (mProcessesToGc.size() > 0) { 13002 boolean printed = false; 13003 long now = SystemClock.uptimeMillis(); 13004 for (int i=0; i<mProcessesToGc.size(); i++) { 13005 ProcessRecord proc = mProcessesToGc.get(i); 13006 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13007 continue; 13008 } 13009 if (!printed) { 13010 if (needSep) pw.println(); 13011 needSep = true; 13012 pw.println(" Processes that are waiting to GC:"); 13013 printed = true; 13014 } 13015 pw.print(" Process "); pw.println(proc); 13016 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13017 pw.print(", last gced="); 13018 pw.print(now-proc.lastRequestedGc); 13019 pw.print(" ms ago, last lowMem="); 13020 pw.print(now-proc.lastLowMemory); 13021 pw.println(" ms ago"); 13022 13023 } 13024 } 13025 return needSep; 13026 } 13027 13028 void printOomLevel(PrintWriter pw, String name, int adj) { 13029 pw.print(" "); 13030 if (adj >= 0) { 13031 pw.print(' '); 13032 if (adj < 10) pw.print(' '); 13033 } else { 13034 if (adj > -10) pw.print(' '); 13035 } 13036 pw.print(adj); 13037 pw.print(": "); 13038 pw.print(name); 13039 pw.print(" ("); 13040 pw.print(mProcessList.getMemLevel(adj)/1024); 13041 pw.println(" kB)"); 13042 } 13043 13044 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13045 int opti, boolean dumpAll) { 13046 boolean needSep = false; 13047 13048 if (mLruProcesses.size() > 0) { 13049 if (needSep) pw.println(); 13050 needSep = true; 13051 pw.println(" OOM levels:"); 13052 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13053 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13054 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13055 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13056 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13057 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13058 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13059 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13060 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13061 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13062 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13063 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13064 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13065 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13066 13067 if (needSep) pw.println(); 13068 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13069 pw.print(" total, non-act at "); 13070 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13071 pw.print(", non-svc at "); 13072 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13073 pw.println("):"); 13074 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13075 needSep = true; 13076 } 13077 13078 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13079 13080 pw.println(); 13081 pw.println(" mHomeProcess: " + mHomeProcess); 13082 pw.println(" mPreviousProcess: " + mPreviousProcess); 13083 if (mHeavyWeightProcess != null) { 13084 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13085 } 13086 13087 return true; 13088 } 13089 13090 /** 13091 * There are three ways to call this: 13092 * - no provider specified: dump all the providers 13093 * - a flattened component name that matched an existing provider was specified as the 13094 * first arg: dump that one provider 13095 * - the first arg isn't the flattened component name of an existing provider: 13096 * dump all providers whose component contains the first arg as a substring 13097 */ 13098 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13099 int opti, boolean dumpAll) { 13100 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13101 } 13102 13103 static class ItemMatcher { 13104 ArrayList<ComponentName> components; 13105 ArrayList<String> strings; 13106 ArrayList<Integer> objects; 13107 boolean all; 13108 13109 ItemMatcher() { 13110 all = true; 13111 } 13112 13113 void build(String name) { 13114 ComponentName componentName = ComponentName.unflattenFromString(name); 13115 if (componentName != null) { 13116 if (components == null) { 13117 components = new ArrayList<ComponentName>(); 13118 } 13119 components.add(componentName); 13120 all = false; 13121 } else { 13122 int objectId = 0; 13123 // Not a '/' separated full component name; maybe an object ID? 13124 try { 13125 objectId = Integer.parseInt(name, 16); 13126 if (objects == null) { 13127 objects = new ArrayList<Integer>(); 13128 } 13129 objects.add(objectId); 13130 all = false; 13131 } catch (RuntimeException e) { 13132 // Not an integer; just do string match. 13133 if (strings == null) { 13134 strings = new ArrayList<String>(); 13135 } 13136 strings.add(name); 13137 all = false; 13138 } 13139 } 13140 } 13141 13142 int build(String[] args, int opti) { 13143 for (; opti<args.length; opti++) { 13144 String name = args[opti]; 13145 if ("--".equals(name)) { 13146 return opti+1; 13147 } 13148 build(name); 13149 } 13150 return opti; 13151 } 13152 13153 boolean match(Object object, ComponentName comp) { 13154 if (all) { 13155 return true; 13156 } 13157 if (components != null) { 13158 for (int i=0; i<components.size(); i++) { 13159 if (components.get(i).equals(comp)) { 13160 return true; 13161 } 13162 } 13163 } 13164 if (objects != null) { 13165 for (int i=0; i<objects.size(); i++) { 13166 if (System.identityHashCode(object) == objects.get(i)) { 13167 return true; 13168 } 13169 } 13170 } 13171 if (strings != null) { 13172 String flat = comp.flattenToString(); 13173 for (int i=0; i<strings.size(); i++) { 13174 if (flat.contains(strings.get(i))) { 13175 return true; 13176 } 13177 } 13178 } 13179 return false; 13180 } 13181 } 13182 13183 /** 13184 * There are three things that cmd can be: 13185 * - a flattened component name that matches an existing activity 13186 * - the cmd arg isn't the flattened component name of an existing activity: 13187 * dump all activity whose component contains the cmd as a substring 13188 * - A hex number of the ActivityRecord object instance. 13189 */ 13190 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13191 int opti, boolean dumpAll) { 13192 ArrayList<ActivityRecord> activities; 13193 13194 synchronized (this) { 13195 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13196 } 13197 13198 if (activities.size() <= 0) { 13199 return false; 13200 } 13201 13202 String[] newArgs = new String[args.length - opti]; 13203 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13204 13205 TaskRecord lastTask = null; 13206 boolean needSep = false; 13207 for (int i=activities.size()-1; i>=0; i--) { 13208 ActivityRecord r = activities.get(i); 13209 if (needSep) { 13210 pw.println(); 13211 } 13212 needSep = true; 13213 synchronized (this) { 13214 if (lastTask != r.task) { 13215 lastTask = r.task; 13216 pw.print("TASK "); pw.print(lastTask.affinity); 13217 pw.print(" id="); pw.println(lastTask.taskId); 13218 if (dumpAll) { 13219 lastTask.dump(pw, " "); 13220 } 13221 } 13222 } 13223 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13224 } 13225 return true; 13226 } 13227 13228 /** 13229 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13230 * there is a thread associated with the activity. 13231 */ 13232 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13233 final ActivityRecord r, String[] args, boolean dumpAll) { 13234 String innerPrefix = prefix + " "; 13235 synchronized (this) { 13236 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13237 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13238 pw.print(" pid="); 13239 if (r.app != null) pw.println(r.app.pid); 13240 else pw.println("(not running)"); 13241 if (dumpAll) { 13242 r.dump(pw, innerPrefix); 13243 } 13244 } 13245 if (r.app != null && r.app.thread != null) { 13246 // flush anything that is already in the PrintWriter since the thread is going 13247 // to write to the file descriptor directly 13248 pw.flush(); 13249 try { 13250 TransferPipe tp = new TransferPipe(); 13251 try { 13252 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13253 r.appToken, innerPrefix, args); 13254 tp.go(fd); 13255 } finally { 13256 tp.kill(); 13257 } 13258 } catch (IOException e) { 13259 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13260 } catch (RemoteException e) { 13261 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13262 } 13263 } 13264 } 13265 13266 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13267 int opti, boolean dumpAll, String dumpPackage) { 13268 boolean needSep = false; 13269 boolean onlyHistory = false; 13270 boolean printedAnything = false; 13271 13272 if ("history".equals(dumpPackage)) { 13273 if (opti < args.length && "-s".equals(args[opti])) { 13274 dumpAll = false; 13275 } 13276 onlyHistory = true; 13277 dumpPackage = null; 13278 } 13279 13280 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13281 if (!onlyHistory && dumpAll) { 13282 if (mRegisteredReceivers.size() > 0) { 13283 boolean printed = false; 13284 Iterator it = mRegisteredReceivers.values().iterator(); 13285 while (it.hasNext()) { 13286 ReceiverList r = (ReceiverList)it.next(); 13287 if (dumpPackage != null && (r.app == null || 13288 !dumpPackage.equals(r.app.info.packageName))) { 13289 continue; 13290 } 13291 if (!printed) { 13292 pw.println(" Registered Receivers:"); 13293 needSep = true; 13294 printed = true; 13295 printedAnything = true; 13296 } 13297 pw.print(" * "); pw.println(r); 13298 r.dump(pw, " "); 13299 } 13300 } 13301 13302 if (mReceiverResolver.dump(pw, needSep ? 13303 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13304 " ", dumpPackage, false, false)) { 13305 needSep = true; 13306 printedAnything = true; 13307 } 13308 } 13309 13310 for (BroadcastQueue q : mBroadcastQueues) { 13311 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13312 printedAnything |= needSep; 13313 } 13314 13315 needSep = true; 13316 13317 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13318 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13319 if (needSep) { 13320 pw.println(); 13321 } 13322 needSep = true; 13323 printedAnything = true; 13324 pw.print(" Sticky broadcasts for user "); 13325 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13326 StringBuilder sb = new StringBuilder(128); 13327 for (Map.Entry<String, ArrayList<Intent>> ent 13328 : mStickyBroadcasts.valueAt(user).entrySet()) { 13329 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13330 if (dumpAll) { 13331 pw.println(":"); 13332 ArrayList<Intent> intents = ent.getValue(); 13333 final int N = intents.size(); 13334 for (int i=0; i<N; i++) { 13335 sb.setLength(0); 13336 sb.append(" Intent: "); 13337 intents.get(i).toShortString(sb, false, true, false, false); 13338 pw.println(sb.toString()); 13339 Bundle bundle = intents.get(i).getExtras(); 13340 if (bundle != null) { 13341 pw.print(" "); 13342 pw.println(bundle.toString()); 13343 } 13344 } 13345 } else { 13346 pw.println(""); 13347 } 13348 } 13349 } 13350 } 13351 13352 if (!onlyHistory && dumpAll) { 13353 pw.println(); 13354 for (BroadcastQueue queue : mBroadcastQueues) { 13355 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13356 + queue.mBroadcastsScheduled); 13357 } 13358 pw.println(" mHandler:"); 13359 mHandler.dump(new PrintWriterPrinter(pw), " "); 13360 needSep = true; 13361 printedAnything = true; 13362 } 13363 13364 if (!printedAnything) { 13365 pw.println(" (nothing)"); 13366 } 13367 } 13368 13369 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13370 int opti, boolean dumpAll, String dumpPackage) { 13371 boolean needSep; 13372 boolean printedAnything = false; 13373 13374 ItemMatcher matcher = new ItemMatcher(); 13375 matcher.build(args, opti); 13376 13377 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13378 13379 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13380 printedAnything |= needSep; 13381 13382 if (mLaunchingProviders.size() > 0) { 13383 boolean printed = false; 13384 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13385 ContentProviderRecord r = mLaunchingProviders.get(i); 13386 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13387 continue; 13388 } 13389 if (!printed) { 13390 if (needSep) pw.println(); 13391 needSep = true; 13392 pw.println(" Launching content providers:"); 13393 printed = true; 13394 printedAnything = true; 13395 } 13396 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13397 pw.println(r); 13398 } 13399 } 13400 13401 if (mGrantedUriPermissions.size() > 0) { 13402 boolean printed = false; 13403 int dumpUid = -2; 13404 if (dumpPackage != null) { 13405 try { 13406 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13407 } catch (NameNotFoundException e) { 13408 dumpUid = -1; 13409 } 13410 } 13411 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13412 int uid = mGrantedUriPermissions.keyAt(i); 13413 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13414 continue; 13415 } 13416 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13417 if (!printed) { 13418 if (needSep) pw.println(); 13419 needSep = true; 13420 pw.println(" Granted Uri Permissions:"); 13421 printed = true; 13422 printedAnything = true; 13423 } 13424 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13425 for (UriPermission perm : perms.values()) { 13426 pw.print(" "); pw.println(perm); 13427 if (dumpAll) { 13428 perm.dump(pw, " "); 13429 } 13430 } 13431 } 13432 } 13433 13434 if (!printedAnything) { 13435 pw.println(" (nothing)"); 13436 } 13437 } 13438 13439 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13440 int opti, boolean dumpAll, String dumpPackage) { 13441 boolean printed = false; 13442 13443 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13444 13445 if (mIntentSenderRecords.size() > 0) { 13446 Iterator<WeakReference<PendingIntentRecord>> it 13447 = mIntentSenderRecords.values().iterator(); 13448 while (it.hasNext()) { 13449 WeakReference<PendingIntentRecord> ref = it.next(); 13450 PendingIntentRecord rec = ref != null ? ref.get(): null; 13451 if (dumpPackage != null && (rec == null 13452 || !dumpPackage.equals(rec.key.packageName))) { 13453 continue; 13454 } 13455 printed = true; 13456 if (rec != null) { 13457 pw.print(" * "); pw.println(rec); 13458 if (dumpAll) { 13459 rec.dump(pw, " "); 13460 } 13461 } else { 13462 pw.print(" * "); pw.println(ref); 13463 } 13464 } 13465 } 13466 13467 if (!printed) { 13468 pw.println(" (nothing)"); 13469 } 13470 } 13471 13472 private static final int dumpProcessList(PrintWriter pw, 13473 ActivityManagerService service, List list, 13474 String prefix, String normalLabel, String persistentLabel, 13475 String dumpPackage) { 13476 int numPers = 0; 13477 final int N = list.size()-1; 13478 for (int i=N; i>=0; i--) { 13479 ProcessRecord r = (ProcessRecord)list.get(i); 13480 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13481 continue; 13482 } 13483 pw.println(String.format("%s%s #%2d: %s", 13484 prefix, (r.persistent ? persistentLabel : normalLabel), 13485 i, r.toString())); 13486 if (r.persistent) { 13487 numPers++; 13488 } 13489 } 13490 return numPers; 13491 } 13492 13493 private static final boolean dumpProcessOomList(PrintWriter pw, 13494 ActivityManagerService service, List<ProcessRecord> origList, 13495 String prefix, String normalLabel, String persistentLabel, 13496 boolean inclDetails, String dumpPackage) { 13497 13498 ArrayList<Pair<ProcessRecord, Integer>> list 13499 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13500 for (int i=0; i<origList.size(); i++) { 13501 ProcessRecord r = origList.get(i); 13502 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13503 continue; 13504 } 13505 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13506 } 13507 13508 if (list.size() <= 0) { 13509 return false; 13510 } 13511 13512 Comparator<Pair<ProcessRecord, Integer>> comparator 13513 = new Comparator<Pair<ProcessRecord, Integer>>() { 13514 @Override 13515 public int compare(Pair<ProcessRecord, Integer> object1, 13516 Pair<ProcessRecord, Integer> object2) { 13517 if (object1.first.setAdj != object2.first.setAdj) { 13518 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13519 } 13520 if (object1.second.intValue() != object2.second.intValue()) { 13521 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13522 } 13523 return 0; 13524 } 13525 }; 13526 13527 Collections.sort(list, comparator); 13528 13529 final long curRealtime = SystemClock.elapsedRealtime(); 13530 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13531 final long curUptime = SystemClock.uptimeMillis(); 13532 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13533 13534 for (int i=list.size()-1; i>=0; i--) { 13535 ProcessRecord r = list.get(i).first; 13536 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13537 char schedGroup; 13538 switch (r.setSchedGroup) { 13539 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13540 schedGroup = 'B'; 13541 break; 13542 case Process.THREAD_GROUP_DEFAULT: 13543 schedGroup = 'F'; 13544 break; 13545 default: 13546 schedGroup = '?'; 13547 break; 13548 } 13549 char foreground; 13550 if (r.foregroundActivities) { 13551 foreground = 'A'; 13552 } else if (r.foregroundServices) { 13553 foreground = 'S'; 13554 } else { 13555 foreground = ' '; 13556 } 13557 String procState = ProcessList.makeProcStateString(r.curProcState); 13558 pw.print(prefix); 13559 pw.print(r.persistent ? persistentLabel : normalLabel); 13560 pw.print(" #"); 13561 int num = (origList.size()-1)-list.get(i).second; 13562 if (num < 10) pw.print(' '); 13563 pw.print(num); 13564 pw.print(": "); 13565 pw.print(oomAdj); 13566 pw.print(' '); 13567 pw.print(schedGroup); 13568 pw.print('/'); 13569 pw.print(foreground); 13570 pw.print('/'); 13571 pw.print(procState); 13572 pw.print(" trm:"); 13573 if (r.trimMemoryLevel < 10) pw.print(' '); 13574 pw.print(r.trimMemoryLevel); 13575 pw.print(' '); 13576 pw.print(r.toShortString()); 13577 pw.print(" ("); 13578 pw.print(r.adjType); 13579 pw.println(')'); 13580 if (r.adjSource != null || r.adjTarget != null) { 13581 pw.print(prefix); 13582 pw.print(" "); 13583 if (r.adjTarget instanceof ComponentName) { 13584 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13585 } else if (r.adjTarget != null) { 13586 pw.print(r.adjTarget.toString()); 13587 } else { 13588 pw.print("{null}"); 13589 } 13590 pw.print("<="); 13591 if (r.adjSource instanceof ProcessRecord) { 13592 pw.print("Proc{"); 13593 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13594 pw.println("}"); 13595 } else if (r.adjSource != null) { 13596 pw.println(r.adjSource.toString()); 13597 } else { 13598 pw.println("{null}"); 13599 } 13600 } 13601 if (inclDetails) { 13602 pw.print(prefix); 13603 pw.print(" "); 13604 pw.print("oom: max="); pw.print(r.maxAdj); 13605 pw.print(" curRaw="); pw.print(r.curRawAdj); 13606 pw.print(" setRaw="); pw.print(r.setRawAdj); 13607 pw.print(" cur="); pw.print(r.curAdj); 13608 pw.print(" set="); pw.println(r.setAdj); 13609 pw.print(prefix); 13610 pw.print(" "); 13611 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13612 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13613 pw.print(" lastPss="); pw.print(r.lastPss); 13614 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13615 pw.print(prefix); 13616 pw.print(" "); 13617 pw.print("cached="); pw.print(r.cached); 13618 pw.print(" empty="); pw.print(r.empty); 13619 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13620 13621 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13622 if (r.lastWakeTime != 0) { 13623 long wtime; 13624 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13625 synchronized (stats) { 13626 wtime = stats.getProcessWakeTime(r.info.uid, 13627 r.pid, curRealtime); 13628 } 13629 long timeUsed = wtime - r.lastWakeTime; 13630 pw.print(prefix); 13631 pw.print(" "); 13632 pw.print("keep awake over "); 13633 TimeUtils.formatDuration(realtimeSince, pw); 13634 pw.print(" used "); 13635 TimeUtils.formatDuration(timeUsed, pw); 13636 pw.print(" ("); 13637 pw.print((timeUsed*100)/realtimeSince); 13638 pw.println("%)"); 13639 } 13640 if (r.lastCpuTime != 0) { 13641 long timeUsed = r.curCpuTime - r.lastCpuTime; 13642 pw.print(prefix); 13643 pw.print(" "); 13644 pw.print("run cpu over "); 13645 TimeUtils.formatDuration(uptimeSince, pw); 13646 pw.print(" used "); 13647 TimeUtils.formatDuration(timeUsed, pw); 13648 pw.print(" ("); 13649 pw.print((timeUsed*100)/uptimeSince); 13650 pw.println("%)"); 13651 } 13652 } 13653 } 13654 } 13655 return true; 13656 } 13657 13658 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13659 String[] args) { 13660 ArrayList<ProcessRecord> procs; 13661 synchronized (this) { 13662 if (args != null && args.length > start 13663 && args[start].charAt(0) != '-') { 13664 procs = new ArrayList<ProcessRecord>(); 13665 int pid = -1; 13666 try { 13667 pid = Integer.parseInt(args[start]); 13668 } catch (NumberFormatException e) { 13669 } 13670 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13671 ProcessRecord proc = mLruProcesses.get(i); 13672 if (proc.pid == pid) { 13673 procs.add(proc); 13674 } else if (allPkgs && proc.pkgList != null 13675 && proc.pkgList.containsKey(args[start])) { 13676 procs.add(proc); 13677 } else if (proc.processName.equals(args[start])) { 13678 procs.add(proc); 13679 } 13680 } 13681 if (procs.size() <= 0) { 13682 return null; 13683 } 13684 } else { 13685 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13686 } 13687 } 13688 return procs; 13689 } 13690 13691 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13692 PrintWriter pw, String[] args) { 13693 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13694 if (procs == null) { 13695 pw.println("No process found for: " + args[0]); 13696 return; 13697 } 13698 13699 long uptime = SystemClock.uptimeMillis(); 13700 long realtime = SystemClock.elapsedRealtime(); 13701 pw.println("Applications Graphics Acceleration Info:"); 13702 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13703 13704 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13705 ProcessRecord r = procs.get(i); 13706 if (r.thread != null) { 13707 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13708 pw.flush(); 13709 try { 13710 TransferPipe tp = new TransferPipe(); 13711 try { 13712 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13713 tp.go(fd); 13714 } finally { 13715 tp.kill(); 13716 } 13717 } catch (IOException e) { 13718 pw.println("Failure while dumping the app: " + r); 13719 pw.flush(); 13720 } catch (RemoteException e) { 13721 pw.println("Got a RemoteException while dumping the app " + r); 13722 pw.flush(); 13723 } 13724 } 13725 } 13726 } 13727 13728 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13729 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13730 if (procs == null) { 13731 pw.println("No process found for: " + args[0]); 13732 return; 13733 } 13734 13735 pw.println("Applications Database Info:"); 13736 13737 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13738 ProcessRecord r = procs.get(i); 13739 if (r.thread != null) { 13740 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13741 pw.flush(); 13742 try { 13743 TransferPipe tp = new TransferPipe(); 13744 try { 13745 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13746 tp.go(fd); 13747 } finally { 13748 tp.kill(); 13749 } 13750 } catch (IOException e) { 13751 pw.println("Failure while dumping the app: " + r); 13752 pw.flush(); 13753 } catch (RemoteException e) { 13754 pw.println("Got a RemoteException while dumping the app " + r); 13755 pw.flush(); 13756 } 13757 } 13758 } 13759 } 13760 13761 final static class MemItem { 13762 final boolean isProc; 13763 final String label; 13764 final String shortLabel; 13765 final long pss; 13766 final int id; 13767 final boolean hasActivities; 13768 ArrayList<MemItem> subitems; 13769 13770 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13771 boolean _hasActivities) { 13772 isProc = true; 13773 label = _label; 13774 shortLabel = _shortLabel; 13775 pss = _pss; 13776 id = _id; 13777 hasActivities = _hasActivities; 13778 } 13779 13780 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13781 isProc = false; 13782 label = _label; 13783 shortLabel = _shortLabel; 13784 pss = _pss; 13785 id = _id; 13786 hasActivities = false; 13787 } 13788 } 13789 13790 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13791 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13792 if (sort && !isCompact) { 13793 Collections.sort(items, new Comparator<MemItem>() { 13794 @Override 13795 public int compare(MemItem lhs, MemItem rhs) { 13796 if (lhs.pss < rhs.pss) { 13797 return 1; 13798 } else if (lhs.pss > rhs.pss) { 13799 return -1; 13800 } 13801 return 0; 13802 } 13803 }); 13804 } 13805 13806 for (int i=0; i<items.size(); i++) { 13807 MemItem mi = items.get(i); 13808 if (!isCompact) { 13809 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13810 } else if (mi.isProc) { 13811 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13812 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13813 pw.println(mi.hasActivities ? ",a" : ",e"); 13814 } else { 13815 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13816 pw.println(mi.pss); 13817 } 13818 if (mi.subitems != null) { 13819 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13820 true, isCompact); 13821 } 13822 } 13823 } 13824 13825 // These are in KB. 13826 static final long[] DUMP_MEM_BUCKETS = new long[] { 13827 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13828 120*1024, 160*1024, 200*1024, 13829 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13830 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13831 }; 13832 13833 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13834 boolean stackLike) { 13835 int start = label.lastIndexOf('.'); 13836 if (start >= 0) start++; 13837 else start = 0; 13838 int end = label.length(); 13839 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13840 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13841 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13842 out.append(bucket); 13843 out.append(stackLike ? "MB." : "MB "); 13844 out.append(label, start, end); 13845 return; 13846 } 13847 } 13848 out.append(memKB/1024); 13849 out.append(stackLike ? "MB." : "MB "); 13850 out.append(label, start, end); 13851 } 13852 13853 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13854 ProcessList.NATIVE_ADJ, 13855 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13856 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13857 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13858 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13859 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13860 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13861 }; 13862 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13863 "Native", 13864 "System", "Persistent", "Persistent Service", "Foreground", 13865 "Visible", "Perceptible", 13866 "Heavy Weight", "Backup", 13867 "A Services", "Home", 13868 "Previous", "B Services", "Cached" 13869 }; 13870 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13871 "native", 13872 "sys", "pers", "persvc", "fore", 13873 "vis", "percept", 13874 "heavy", "backup", 13875 "servicea", "home", 13876 "prev", "serviceb", "cached" 13877 }; 13878 13879 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13880 long realtime, boolean isCheckinRequest, boolean isCompact) { 13881 if (isCheckinRequest || isCompact) { 13882 // short checkin version 13883 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13884 } else { 13885 pw.println("Applications Memory Usage (kB):"); 13886 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13887 } 13888 } 13889 13890 private static final int KSM_SHARED = 0; 13891 private static final int KSM_SHARING = 1; 13892 private static final int KSM_UNSHARED = 2; 13893 private static final int KSM_VOLATILE = 3; 13894 13895 private final long[] getKsmInfo() { 13896 long[] longOut = new long[4]; 13897 final int[] SINGLE_LONG_FORMAT = new int[] { 13898 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13899 }; 13900 long[] longTmp = new long[1]; 13901 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13902 SINGLE_LONG_FORMAT, null, longTmp, null); 13903 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13904 longTmp[0] = 0; 13905 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13906 SINGLE_LONG_FORMAT, null, longTmp, null); 13907 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13908 longTmp[0] = 0; 13909 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13910 SINGLE_LONG_FORMAT, null, longTmp, null); 13911 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13912 longTmp[0] = 0; 13913 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13914 SINGLE_LONG_FORMAT, null, longTmp, null); 13915 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13916 return longOut; 13917 } 13918 13919 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13920 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13921 boolean dumpDetails = false; 13922 boolean dumpFullDetails = false; 13923 boolean dumpDalvik = false; 13924 boolean oomOnly = false; 13925 boolean isCompact = false; 13926 boolean localOnly = false; 13927 boolean packages = false; 13928 13929 int opti = 0; 13930 while (opti < args.length) { 13931 String opt = args[opti]; 13932 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13933 break; 13934 } 13935 opti++; 13936 if ("-a".equals(opt)) { 13937 dumpDetails = true; 13938 dumpFullDetails = true; 13939 dumpDalvik = true; 13940 } else if ("-d".equals(opt)) { 13941 dumpDalvik = true; 13942 } else if ("-c".equals(opt)) { 13943 isCompact = true; 13944 } else if ("--oom".equals(opt)) { 13945 oomOnly = true; 13946 } else if ("--local".equals(opt)) { 13947 localOnly = true; 13948 } else if ("--package".equals(opt)) { 13949 packages = true; 13950 } else if ("-h".equals(opt)) { 13951 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13952 pw.println(" -a: include all available information for each process."); 13953 pw.println(" -d: include dalvik details when dumping process details."); 13954 pw.println(" -c: dump in a compact machine-parseable representation."); 13955 pw.println(" --oom: only show processes organized by oom adj."); 13956 pw.println(" --local: only collect details locally, don't call process."); 13957 pw.println(" --package: interpret process arg as package, dumping all"); 13958 pw.println(" processes that have loaded that package."); 13959 pw.println("If [process] is specified it can be the name or "); 13960 pw.println("pid of a specific process to dump."); 13961 return; 13962 } else { 13963 pw.println("Unknown argument: " + opt + "; use -h for help"); 13964 } 13965 } 13966 13967 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13968 long uptime = SystemClock.uptimeMillis(); 13969 long realtime = SystemClock.elapsedRealtime(); 13970 final long[] tmpLong = new long[1]; 13971 13972 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13973 if (procs == null) { 13974 // No Java processes. Maybe they want to print a native process. 13975 if (args != null && args.length > opti 13976 && args[opti].charAt(0) != '-') { 13977 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13978 = new ArrayList<ProcessCpuTracker.Stats>(); 13979 updateCpuStatsNow(); 13980 int findPid = -1; 13981 try { 13982 findPid = Integer.parseInt(args[opti]); 13983 } catch (NumberFormatException e) { 13984 } 13985 synchronized (mProcessCpuTracker) { 13986 final int N = mProcessCpuTracker.countStats(); 13987 for (int i=0; i<N; i++) { 13988 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13989 if (st.pid == findPid || (st.baseName != null 13990 && st.baseName.equals(args[opti]))) { 13991 nativeProcs.add(st); 13992 } 13993 } 13994 } 13995 if (nativeProcs.size() > 0) { 13996 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13997 isCompact); 13998 Debug.MemoryInfo mi = null; 13999 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14000 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14001 final int pid = r.pid; 14002 if (!isCheckinRequest && dumpDetails) { 14003 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14004 } 14005 if (mi == null) { 14006 mi = new Debug.MemoryInfo(); 14007 } 14008 if (dumpDetails || (!brief && !oomOnly)) { 14009 Debug.getMemoryInfo(pid, mi); 14010 } else { 14011 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14012 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14013 } 14014 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14015 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14016 if (isCheckinRequest) { 14017 pw.println(); 14018 } 14019 } 14020 return; 14021 } 14022 } 14023 pw.println("No process found for: " + args[opti]); 14024 return; 14025 } 14026 14027 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14028 dumpDetails = true; 14029 } 14030 14031 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14032 14033 String[] innerArgs = new String[args.length-opti]; 14034 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14035 14036 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14037 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14038 long nativePss = 0; 14039 long dalvikPss = 0; 14040 long otherPss = 0; 14041 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14042 14043 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14044 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14045 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14046 14047 long totalPss = 0; 14048 long cachedPss = 0; 14049 14050 Debug.MemoryInfo mi = null; 14051 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14052 final ProcessRecord r = procs.get(i); 14053 final IApplicationThread thread; 14054 final int pid; 14055 final int oomAdj; 14056 final boolean hasActivities; 14057 synchronized (this) { 14058 thread = r.thread; 14059 pid = r.pid; 14060 oomAdj = r.getSetAdjWithServices(); 14061 hasActivities = r.activities.size() > 0; 14062 } 14063 if (thread != null) { 14064 if (!isCheckinRequest && dumpDetails) { 14065 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14066 } 14067 if (mi == null) { 14068 mi = new Debug.MemoryInfo(); 14069 } 14070 if (dumpDetails || (!brief && !oomOnly)) { 14071 Debug.getMemoryInfo(pid, mi); 14072 } else { 14073 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14074 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14075 } 14076 if (dumpDetails) { 14077 if (localOnly) { 14078 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14079 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14080 if (isCheckinRequest) { 14081 pw.println(); 14082 } 14083 } else { 14084 try { 14085 pw.flush(); 14086 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14087 dumpDalvik, innerArgs); 14088 } catch (RemoteException e) { 14089 if (!isCheckinRequest) { 14090 pw.println("Got RemoteException!"); 14091 pw.flush(); 14092 } 14093 } 14094 } 14095 } 14096 14097 final long myTotalPss = mi.getTotalPss(); 14098 final long myTotalUss = mi.getTotalUss(); 14099 14100 synchronized (this) { 14101 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14102 // Record this for posterity if the process has been stable. 14103 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14104 } 14105 } 14106 14107 if (!isCheckinRequest && mi != null) { 14108 totalPss += myTotalPss; 14109 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14110 (hasActivities ? " / activities)" : ")"), 14111 r.processName, myTotalPss, pid, hasActivities); 14112 procMems.add(pssItem); 14113 procMemsMap.put(pid, pssItem); 14114 14115 nativePss += mi.nativePss; 14116 dalvikPss += mi.dalvikPss; 14117 otherPss += mi.otherPss; 14118 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14119 long mem = mi.getOtherPss(j); 14120 miscPss[j] += mem; 14121 otherPss -= mem; 14122 } 14123 14124 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14125 cachedPss += myTotalPss; 14126 } 14127 14128 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14129 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14130 || oomIndex == (oomPss.length-1)) { 14131 oomPss[oomIndex] += myTotalPss; 14132 if (oomProcs[oomIndex] == null) { 14133 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14134 } 14135 oomProcs[oomIndex].add(pssItem); 14136 break; 14137 } 14138 } 14139 } 14140 } 14141 } 14142 14143 long nativeProcTotalPss = 0; 14144 14145 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14146 // If we are showing aggregations, also look for native processes to 14147 // include so that our aggregations are more accurate. 14148 updateCpuStatsNow(); 14149 mi = null; 14150 synchronized (mProcessCpuTracker) { 14151 final int N = mProcessCpuTracker.countStats(); 14152 for (int i=0; i<N; i++) { 14153 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14154 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14155 if (mi == null) { 14156 mi = new Debug.MemoryInfo(); 14157 } 14158 if (!brief && !oomOnly) { 14159 Debug.getMemoryInfo(st.pid, mi); 14160 } else { 14161 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14162 mi.nativePrivateDirty = (int)tmpLong[0]; 14163 } 14164 14165 final long myTotalPss = mi.getTotalPss(); 14166 totalPss += myTotalPss; 14167 nativeProcTotalPss += myTotalPss; 14168 14169 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14170 st.name, myTotalPss, st.pid, false); 14171 procMems.add(pssItem); 14172 14173 nativePss += mi.nativePss; 14174 dalvikPss += mi.dalvikPss; 14175 otherPss += mi.otherPss; 14176 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14177 long mem = mi.getOtherPss(j); 14178 miscPss[j] += mem; 14179 otherPss -= mem; 14180 } 14181 oomPss[0] += myTotalPss; 14182 if (oomProcs[0] == null) { 14183 oomProcs[0] = new ArrayList<MemItem>(); 14184 } 14185 oomProcs[0].add(pssItem); 14186 } 14187 } 14188 } 14189 14190 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14191 14192 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14193 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14194 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14195 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14196 String label = Debug.MemoryInfo.getOtherLabel(j); 14197 catMems.add(new MemItem(label, label, miscPss[j], j)); 14198 } 14199 14200 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14201 for (int j=0; j<oomPss.length; j++) { 14202 if (oomPss[j] != 0) { 14203 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14204 : DUMP_MEM_OOM_LABEL[j]; 14205 MemItem item = new MemItem(label, label, oomPss[j], 14206 DUMP_MEM_OOM_ADJ[j]); 14207 item.subitems = oomProcs[j]; 14208 oomMems.add(item); 14209 } 14210 } 14211 14212 if (!brief && !oomOnly && !isCompact) { 14213 pw.println(); 14214 pw.println("Total PSS by process:"); 14215 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14216 pw.println(); 14217 } 14218 if (!isCompact) { 14219 pw.println("Total PSS by OOM adjustment:"); 14220 } 14221 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14222 if (!brief && !oomOnly) { 14223 PrintWriter out = categoryPw != null ? categoryPw : pw; 14224 if (!isCompact) { 14225 out.println(); 14226 out.println("Total PSS by category:"); 14227 } 14228 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14229 } 14230 if (!isCompact) { 14231 pw.println(); 14232 } 14233 MemInfoReader memInfo = new MemInfoReader(); 14234 memInfo.readMemInfo(); 14235 if (nativeProcTotalPss > 0) { 14236 synchronized (this) { 14237 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14238 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14239 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14240 } 14241 } 14242 if (!brief) { 14243 if (!isCompact) { 14244 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14245 pw.print(" kB (status "); 14246 switch (mLastMemoryLevel) { 14247 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14248 pw.println("normal)"); 14249 break; 14250 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14251 pw.println("moderate)"); 14252 break; 14253 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14254 pw.println("low)"); 14255 break; 14256 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14257 pw.println("critical)"); 14258 break; 14259 default: 14260 pw.print(mLastMemoryLevel); 14261 pw.println(")"); 14262 break; 14263 } 14264 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14265 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14266 pw.print(cachedPss); pw.print(" cached pss + "); 14267 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14268 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14269 } else { 14270 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14271 pw.print(cachedPss + memInfo.getCachedSizeKb() 14272 + memInfo.getFreeSizeKb()); pw.print(","); 14273 pw.println(totalPss - cachedPss); 14274 } 14275 } 14276 if (!isCompact) { 14277 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14278 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14279 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14280 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14281 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14282 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14283 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14284 } 14285 if (!brief) { 14286 if (memInfo.getZramTotalSizeKb() != 0) { 14287 if (!isCompact) { 14288 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14289 pw.print(" kB physical used for "); 14290 pw.print(memInfo.getSwapTotalSizeKb() 14291 - memInfo.getSwapFreeSizeKb()); 14292 pw.print(" kB in swap ("); 14293 pw.print(memInfo.getSwapTotalSizeKb()); 14294 pw.println(" kB total swap)"); 14295 } else { 14296 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14297 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14298 pw.println(memInfo.getSwapFreeSizeKb()); 14299 } 14300 } 14301 final long[] ksm = getKsmInfo(); 14302 if (!isCompact) { 14303 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14304 || ksm[KSM_VOLATILE] != 0) { 14305 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14306 pw.print(" kB saved from shared "); 14307 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14308 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14309 pw.print(" kB unshared; "); 14310 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14311 } 14312 pw.print(" Tuning: "); 14313 pw.print(ActivityManager.staticGetMemoryClass()); 14314 pw.print(" (large "); 14315 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14316 pw.print("), oom "); 14317 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14318 pw.print(" kB"); 14319 pw.print(", restore limit "); 14320 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14321 pw.print(" kB"); 14322 if (ActivityManager.isLowRamDeviceStatic()) { 14323 pw.print(" (low-ram)"); 14324 } 14325 if (ActivityManager.isHighEndGfx()) { 14326 pw.print(" (high-end-gfx)"); 14327 } 14328 pw.println(); 14329 } else { 14330 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14331 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14332 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14333 pw.print("tuning,"); 14334 pw.print(ActivityManager.staticGetMemoryClass()); 14335 pw.print(','); 14336 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14337 pw.print(','); 14338 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14339 if (ActivityManager.isLowRamDeviceStatic()) { 14340 pw.print(",low-ram"); 14341 } 14342 if (ActivityManager.isHighEndGfx()) { 14343 pw.print(",high-end-gfx"); 14344 } 14345 pw.println(); 14346 } 14347 } 14348 } 14349 } 14350 14351 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14352 long memtrack, String name) { 14353 sb.append(" "); 14354 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14355 sb.append(' '); 14356 sb.append(ProcessList.makeProcStateString(procState)); 14357 sb.append(' '); 14358 ProcessList.appendRamKb(sb, pss); 14359 sb.append(" kB: "); 14360 sb.append(name); 14361 if (memtrack > 0) { 14362 sb.append(" ("); 14363 sb.append(memtrack); 14364 sb.append(" kB memtrack)"); 14365 } 14366 } 14367 14368 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14369 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14370 sb.append(" (pid "); 14371 sb.append(mi.pid); 14372 sb.append(") "); 14373 sb.append(mi.adjType); 14374 sb.append('\n'); 14375 if (mi.adjReason != null) { 14376 sb.append(" "); 14377 sb.append(mi.adjReason); 14378 sb.append('\n'); 14379 } 14380 } 14381 14382 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14383 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14384 for (int i=0, N=memInfos.size(); i<N; i++) { 14385 ProcessMemInfo mi = memInfos.get(i); 14386 infoMap.put(mi.pid, mi); 14387 } 14388 updateCpuStatsNow(); 14389 long[] memtrackTmp = new long[1]; 14390 synchronized (mProcessCpuTracker) { 14391 final int N = mProcessCpuTracker.countStats(); 14392 for (int i=0; i<N; i++) { 14393 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14394 if (st.vsize > 0) { 14395 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14396 if (pss > 0) { 14397 if (infoMap.indexOfKey(st.pid) < 0) { 14398 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14399 ProcessList.NATIVE_ADJ, -1, "native", null); 14400 mi.pss = pss; 14401 mi.memtrack = memtrackTmp[0]; 14402 memInfos.add(mi); 14403 } 14404 } 14405 } 14406 } 14407 } 14408 14409 long totalPss = 0; 14410 long totalMemtrack = 0; 14411 for (int i=0, N=memInfos.size(); i<N; i++) { 14412 ProcessMemInfo mi = memInfos.get(i); 14413 if (mi.pss == 0) { 14414 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14415 mi.memtrack = memtrackTmp[0]; 14416 } 14417 totalPss += mi.pss; 14418 totalMemtrack += mi.memtrack; 14419 } 14420 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14421 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14422 if (lhs.oomAdj != rhs.oomAdj) { 14423 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14424 } 14425 if (lhs.pss != rhs.pss) { 14426 return lhs.pss < rhs.pss ? 1 : -1; 14427 } 14428 return 0; 14429 } 14430 }); 14431 14432 StringBuilder tag = new StringBuilder(128); 14433 StringBuilder stack = new StringBuilder(128); 14434 tag.append("Low on memory -- "); 14435 appendMemBucket(tag, totalPss, "total", false); 14436 appendMemBucket(stack, totalPss, "total", true); 14437 14438 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14439 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14440 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14441 14442 boolean firstLine = true; 14443 int lastOomAdj = Integer.MIN_VALUE; 14444 long extraNativeRam = 0; 14445 long extraNativeMemtrack = 0; 14446 long cachedPss = 0; 14447 for (int i=0, N=memInfos.size(); i<N; i++) { 14448 ProcessMemInfo mi = memInfos.get(i); 14449 14450 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14451 cachedPss += mi.pss; 14452 } 14453 14454 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14455 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14456 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14457 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14458 if (lastOomAdj != mi.oomAdj) { 14459 lastOomAdj = mi.oomAdj; 14460 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14461 tag.append(" / "); 14462 } 14463 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14464 if (firstLine) { 14465 stack.append(":"); 14466 firstLine = false; 14467 } 14468 stack.append("\n\t at "); 14469 } else { 14470 stack.append("$"); 14471 } 14472 } else { 14473 tag.append(" "); 14474 stack.append("$"); 14475 } 14476 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14477 appendMemBucket(tag, mi.pss, mi.name, false); 14478 } 14479 appendMemBucket(stack, mi.pss, mi.name, true); 14480 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14481 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14482 stack.append("("); 14483 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14484 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14485 stack.append(DUMP_MEM_OOM_LABEL[k]); 14486 stack.append(":"); 14487 stack.append(DUMP_MEM_OOM_ADJ[k]); 14488 } 14489 } 14490 stack.append(")"); 14491 } 14492 } 14493 14494 appendMemInfo(fullNativeBuilder, mi); 14495 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14496 // The short form only has native processes that are >= 512K. 14497 if (mi.pss >= 512) { 14498 appendMemInfo(shortNativeBuilder, mi); 14499 } else { 14500 extraNativeRam += mi.pss; 14501 extraNativeMemtrack += mi.memtrack; 14502 } 14503 } else { 14504 // Short form has all other details, but if we have collected RAM 14505 // from smaller native processes let's dump a summary of that. 14506 if (extraNativeRam > 0) { 14507 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14508 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14509 shortNativeBuilder.append('\n'); 14510 extraNativeRam = 0; 14511 } 14512 appendMemInfo(fullJavaBuilder, mi); 14513 } 14514 } 14515 14516 fullJavaBuilder.append(" "); 14517 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14518 fullJavaBuilder.append(" kB: TOTAL"); 14519 if (totalMemtrack > 0) { 14520 fullJavaBuilder.append(" ("); 14521 fullJavaBuilder.append(totalMemtrack); 14522 fullJavaBuilder.append(" kB memtrack)"); 14523 } else { 14524 } 14525 fullJavaBuilder.append("\n"); 14526 14527 MemInfoReader memInfo = new MemInfoReader(); 14528 memInfo.readMemInfo(); 14529 final long[] infos = memInfo.getRawInfo(); 14530 14531 StringBuilder memInfoBuilder = new StringBuilder(1024); 14532 Debug.getMemInfo(infos); 14533 memInfoBuilder.append(" MemInfo: "); 14534 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14535 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14536 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14537 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14538 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14539 memInfoBuilder.append(" "); 14540 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14541 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14542 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14543 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14544 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14545 memInfoBuilder.append(" ZRAM: "); 14546 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14547 memInfoBuilder.append(" kB RAM, "); 14548 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14549 memInfoBuilder.append(" kB swap total, "); 14550 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14551 memInfoBuilder.append(" kB swap free\n"); 14552 } 14553 final long[] ksm = getKsmInfo(); 14554 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14555 || ksm[KSM_VOLATILE] != 0) { 14556 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14557 memInfoBuilder.append(" kB saved from shared "); 14558 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14559 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14560 memInfoBuilder.append(" kB unshared; "); 14561 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14562 } 14563 memInfoBuilder.append(" Free RAM: "); 14564 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14565 + memInfo.getFreeSizeKb()); 14566 memInfoBuilder.append(" kB\n"); 14567 memInfoBuilder.append(" Used RAM: "); 14568 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14569 memInfoBuilder.append(" kB\n"); 14570 memInfoBuilder.append(" Lost RAM: "); 14571 memInfoBuilder.append(memInfo.getTotalSizeKb() 14572 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14573 - memInfo.getKernelUsedSizeKb()); 14574 memInfoBuilder.append(" kB\n"); 14575 Slog.i(TAG, "Low on memory:"); 14576 Slog.i(TAG, shortNativeBuilder.toString()); 14577 Slog.i(TAG, fullJavaBuilder.toString()); 14578 Slog.i(TAG, memInfoBuilder.toString()); 14579 14580 StringBuilder dropBuilder = new StringBuilder(1024); 14581 /* 14582 StringWriter oomSw = new StringWriter(); 14583 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14584 StringWriter catSw = new StringWriter(); 14585 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14586 String[] emptyArgs = new String[] { }; 14587 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14588 oomPw.flush(); 14589 String oomString = oomSw.toString(); 14590 */ 14591 dropBuilder.append("Low on memory:"); 14592 dropBuilder.append(stack); 14593 dropBuilder.append('\n'); 14594 dropBuilder.append(fullNativeBuilder); 14595 dropBuilder.append(fullJavaBuilder); 14596 dropBuilder.append('\n'); 14597 dropBuilder.append(memInfoBuilder); 14598 dropBuilder.append('\n'); 14599 /* 14600 dropBuilder.append(oomString); 14601 dropBuilder.append('\n'); 14602 */ 14603 StringWriter catSw = new StringWriter(); 14604 synchronized (ActivityManagerService.this) { 14605 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14606 String[] emptyArgs = new String[] { }; 14607 catPw.println(); 14608 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14609 catPw.println(); 14610 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14611 false, false, null); 14612 catPw.println(); 14613 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14614 catPw.flush(); 14615 } 14616 dropBuilder.append(catSw.toString()); 14617 addErrorToDropBox("lowmem", null, "system_server", null, 14618 null, tag.toString(), dropBuilder.toString(), null, null); 14619 //Slog.i(TAG, "Sent to dropbox:"); 14620 //Slog.i(TAG, dropBuilder.toString()); 14621 synchronized (ActivityManagerService.this) { 14622 long now = SystemClock.uptimeMillis(); 14623 if (mLastMemUsageReportTime < now) { 14624 mLastMemUsageReportTime = now; 14625 } 14626 } 14627 } 14628 14629 /** 14630 * Searches array of arguments for the specified string 14631 * @param args array of argument strings 14632 * @param value value to search for 14633 * @return true if the value is contained in the array 14634 */ 14635 private static boolean scanArgs(String[] args, String value) { 14636 if (args != null) { 14637 for (String arg : args) { 14638 if (value.equals(arg)) { 14639 return true; 14640 } 14641 } 14642 } 14643 return false; 14644 } 14645 14646 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14647 ContentProviderRecord cpr, boolean always) { 14648 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14649 14650 if (!inLaunching || always) { 14651 synchronized (cpr) { 14652 cpr.launchingApp = null; 14653 cpr.notifyAll(); 14654 } 14655 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14656 String names[] = cpr.info.authority.split(";"); 14657 for (int j = 0; j < names.length; j++) { 14658 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14659 } 14660 } 14661 14662 for (int i=0; i<cpr.connections.size(); i++) { 14663 ContentProviderConnection conn = cpr.connections.get(i); 14664 if (conn.waiting) { 14665 // If this connection is waiting for the provider, then we don't 14666 // need to mess with its process unless we are always removing 14667 // or for some reason the provider is not currently launching. 14668 if (inLaunching && !always) { 14669 continue; 14670 } 14671 } 14672 ProcessRecord capp = conn.client; 14673 conn.dead = true; 14674 if (conn.stableCount > 0) { 14675 if (!capp.persistent && capp.thread != null 14676 && capp.pid != 0 14677 && capp.pid != MY_PID) { 14678 capp.kill("depends on provider " 14679 + cpr.name.flattenToShortString() 14680 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14681 } 14682 } else if (capp.thread != null && conn.provider.provider != null) { 14683 try { 14684 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14685 } catch (RemoteException e) { 14686 } 14687 // In the protocol here, we don't expect the client to correctly 14688 // clean up this connection, we'll just remove it. 14689 cpr.connections.remove(i); 14690 conn.client.conProviders.remove(conn); 14691 } 14692 } 14693 14694 if (inLaunching && always) { 14695 mLaunchingProviders.remove(cpr); 14696 } 14697 return inLaunching; 14698 } 14699 14700 /** 14701 * Main code for cleaning up a process when it has gone away. This is 14702 * called both as a result of the process dying, or directly when stopping 14703 * a process when running in single process mode. 14704 * 14705 * @return Returns true if the given process has been restarted, so the 14706 * app that was passed in must remain on the process lists. 14707 */ 14708 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14709 boolean restarting, boolean allowRestart, int index) { 14710 if (index >= 0) { 14711 removeLruProcessLocked(app); 14712 ProcessList.remove(app.pid); 14713 } 14714 14715 mProcessesToGc.remove(app); 14716 mPendingPssProcesses.remove(app); 14717 14718 // Dismiss any open dialogs. 14719 if (app.crashDialog != null && !app.forceCrashReport) { 14720 app.crashDialog.dismiss(); 14721 app.crashDialog = null; 14722 } 14723 if (app.anrDialog != null) { 14724 app.anrDialog.dismiss(); 14725 app.anrDialog = null; 14726 } 14727 if (app.waitDialog != null) { 14728 app.waitDialog.dismiss(); 14729 app.waitDialog = null; 14730 } 14731 14732 app.crashing = false; 14733 app.notResponding = false; 14734 14735 app.resetPackageList(mProcessStats); 14736 app.unlinkDeathRecipient(); 14737 app.makeInactive(mProcessStats); 14738 app.waitingToKill = null; 14739 app.forcingToForeground = null; 14740 updateProcessForegroundLocked(app, false, false); 14741 app.foregroundActivities = false; 14742 app.hasShownUi = false; 14743 app.treatLikeActivity = false; 14744 app.hasAboveClient = false; 14745 app.hasClientActivities = false; 14746 14747 mServices.killServicesLocked(app, allowRestart); 14748 14749 boolean restart = false; 14750 14751 // Remove published content providers. 14752 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14753 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14754 final boolean always = app.bad || !allowRestart; 14755 if (removeDyingProviderLocked(app, cpr, always) || always) { 14756 // We left the provider in the launching list, need to 14757 // restart it. 14758 restart = true; 14759 } 14760 14761 cpr.provider = null; 14762 cpr.proc = null; 14763 } 14764 app.pubProviders.clear(); 14765 14766 // Take care of any launching providers waiting for this process. 14767 if (checkAppInLaunchingProvidersLocked(app, false)) { 14768 restart = true; 14769 } 14770 14771 // Unregister from connected content providers. 14772 if (!app.conProviders.isEmpty()) { 14773 for (int i=0; i<app.conProviders.size(); i++) { 14774 ContentProviderConnection conn = app.conProviders.get(i); 14775 conn.provider.connections.remove(conn); 14776 } 14777 app.conProviders.clear(); 14778 } 14779 14780 // At this point there may be remaining entries in mLaunchingProviders 14781 // where we were the only one waiting, so they are no longer of use. 14782 // Look for these and clean up if found. 14783 // XXX Commented out for now. Trying to figure out a way to reproduce 14784 // the actual situation to identify what is actually going on. 14785 if (false) { 14786 for (int i=0; i<mLaunchingProviders.size(); i++) { 14787 ContentProviderRecord cpr = (ContentProviderRecord) 14788 mLaunchingProviders.get(i); 14789 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14790 synchronized (cpr) { 14791 cpr.launchingApp = null; 14792 cpr.notifyAll(); 14793 } 14794 } 14795 } 14796 } 14797 14798 skipCurrentReceiverLocked(app); 14799 14800 // Unregister any receivers. 14801 for (int i=app.receivers.size()-1; i>=0; i--) { 14802 removeReceiverLocked(app.receivers.valueAt(i)); 14803 } 14804 app.receivers.clear(); 14805 14806 // If the app is undergoing backup, tell the backup manager about it 14807 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14808 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14809 + mBackupTarget.appInfo + " died during backup"); 14810 try { 14811 IBackupManager bm = IBackupManager.Stub.asInterface( 14812 ServiceManager.getService(Context.BACKUP_SERVICE)); 14813 bm.agentDisconnected(app.info.packageName); 14814 } catch (RemoteException e) { 14815 // can't happen; backup manager is local 14816 } 14817 } 14818 14819 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14820 ProcessChangeItem item = mPendingProcessChanges.get(i); 14821 if (item.pid == app.pid) { 14822 mPendingProcessChanges.remove(i); 14823 mAvailProcessChanges.add(item); 14824 } 14825 } 14826 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14827 14828 // If the caller is restarting this app, then leave it in its 14829 // current lists and let the caller take care of it. 14830 if (restarting) { 14831 return false; 14832 } 14833 14834 if (!app.persistent || app.isolated) { 14835 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14836 "Removing non-persistent process during cleanup: " + app); 14837 mProcessNames.remove(app.processName, app.uid); 14838 mIsolatedProcesses.remove(app.uid); 14839 if (mHeavyWeightProcess == app) { 14840 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14841 mHeavyWeightProcess.userId, 0)); 14842 mHeavyWeightProcess = null; 14843 } 14844 } else if (!app.removed) { 14845 // This app is persistent, so we need to keep its record around. 14846 // If it is not already on the pending app list, add it there 14847 // and start a new process for it. 14848 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14849 mPersistentStartingProcesses.add(app); 14850 restart = true; 14851 } 14852 } 14853 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14854 "Clean-up removing on hold: " + app); 14855 mProcessesOnHold.remove(app); 14856 14857 if (app == mHomeProcess) { 14858 mHomeProcess = null; 14859 } 14860 if (app == mPreviousProcess) { 14861 mPreviousProcess = null; 14862 } 14863 14864 if (restart && !app.isolated) { 14865 // We have components that still need to be running in the 14866 // process, so re-launch it. 14867 if (index < 0) { 14868 ProcessList.remove(app.pid); 14869 } 14870 mProcessNames.put(app.processName, app.uid, app); 14871 startProcessLocked(app, "restart", app.processName); 14872 return true; 14873 } else if (app.pid > 0 && app.pid != MY_PID) { 14874 // Goodbye! 14875 boolean removed; 14876 synchronized (mPidsSelfLocked) { 14877 mPidsSelfLocked.remove(app.pid); 14878 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14879 } 14880 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14881 if (app.isolated) { 14882 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14883 } 14884 app.setPid(0); 14885 } 14886 return false; 14887 } 14888 14889 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14890 // Look through the content providers we are waiting to have launched, 14891 // and if any run in this process then either schedule a restart of 14892 // the process or kill the client waiting for it if this process has 14893 // gone bad. 14894 int NL = mLaunchingProviders.size(); 14895 boolean restart = false; 14896 for (int i=0; i<NL; i++) { 14897 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14898 if (cpr.launchingApp == app) { 14899 if (!alwaysBad && !app.bad) { 14900 restart = true; 14901 } else { 14902 removeDyingProviderLocked(app, cpr, true); 14903 // cpr should have been removed from mLaunchingProviders 14904 NL = mLaunchingProviders.size(); 14905 i--; 14906 } 14907 } 14908 } 14909 return restart; 14910 } 14911 14912 // ========================================================= 14913 // SERVICES 14914 // ========================================================= 14915 14916 @Override 14917 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14918 int flags) { 14919 enforceNotIsolatedCaller("getServices"); 14920 synchronized (this) { 14921 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14922 } 14923 } 14924 14925 @Override 14926 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14927 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14928 synchronized (this) { 14929 return mServices.getRunningServiceControlPanelLocked(name); 14930 } 14931 } 14932 14933 @Override 14934 public ComponentName startService(IApplicationThread caller, Intent service, 14935 String resolvedType, int userId) { 14936 enforceNotIsolatedCaller("startService"); 14937 // Refuse possible leaked file descriptors 14938 if (service != null && service.hasFileDescriptors() == true) { 14939 throw new IllegalArgumentException("File descriptors passed in Intent"); 14940 } 14941 14942 if (DEBUG_SERVICE) 14943 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14944 synchronized(this) { 14945 final int callingPid = Binder.getCallingPid(); 14946 final int callingUid = Binder.getCallingUid(); 14947 final long origId = Binder.clearCallingIdentity(); 14948 ComponentName res = mServices.startServiceLocked(caller, service, 14949 resolvedType, callingPid, callingUid, userId); 14950 Binder.restoreCallingIdentity(origId); 14951 return res; 14952 } 14953 } 14954 14955 ComponentName startServiceInPackage(int uid, 14956 Intent service, String resolvedType, int userId) { 14957 synchronized(this) { 14958 if (DEBUG_SERVICE) 14959 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14960 final long origId = Binder.clearCallingIdentity(); 14961 ComponentName res = mServices.startServiceLocked(null, service, 14962 resolvedType, -1, uid, userId); 14963 Binder.restoreCallingIdentity(origId); 14964 return res; 14965 } 14966 } 14967 14968 @Override 14969 public int stopService(IApplicationThread caller, Intent service, 14970 String resolvedType, int userId) { 14971 enforceNotIsolatedCaller("stopService"); 14972 // Refuse possible leaked file descriptors 14973 if (service != null && service.hasFileDescriptors() == true) { 14974 throw new IllegalArgumentException("File descriptors passed in Intent"); 14975 } 14976 14977 synchronized(this) { 14978 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14979 } 14980 } 14981 14982 @Override 14983 public IBinder peekService(Intent service, String resolvedType) { 14984 enforceNotIsolatedCaller("peekService"); 14985 // Refuse possible leaked file descriptors 14986 if (service != null && service.hasFileDescriptors() == true) { 14987 throw new IllegalArgumentException("File descriptors passed in Intent"); 14988 } 14989 synchronized(this) { 14990 return mServices.peekServiceLocked(service, resolvedType); 14991 } 14992 } 14993 14994 @Override 14995 public boolean stopServiceToken(ComponentName className, IBinder token, 14996 int startId) { 14997 synchronized(this) { 14998 return mServices.stopServiceTokenLocked(className, token, startId); 14999 } 15000 } 15001 15002 @Override 15003 public void setServiceForeground(ComponentName className, IBinder token, 15004 int id, Notification notification, boolean removeNotification) { 15005 synchronized(this) { 15006 mServices.setServiceForegroundLocked(className, token, id, notification, 15007 removeNotification); 15008 } 15009 } 15010 15011 @Override 15012 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15013 boolean requireFull, String name, String callerPackage) { 15014 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15015 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15016 } 15017 15018 int unsafeConvertIncomingUser(int userId) { 15019 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15020 ? mCurrentUserId : userId; 15021 } 15022 15023 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15024 int allowMode, String name, String callerPackage) { 15025 final int callingUserId = UserHandle.getUserId(callingUid); 15026 if (callingUserId == userId) { 15027 return userId; 15028 } 15029 15030 // Note that we may be accessing mCurrentUserId outside of a lock... 15031 // shouldn't be a big deal, if this is being called outside 15032 // of a locked context there is intrinsically a race with 15033 // the value the caller will receive and someone else changing it. 15034 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15035 // we will switch to the calling user if access to the current user fails. 15036 int targetUserId = unsafeConvertIncomingUser(userId); 15037 15038 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15039 final boolean allow; 15040 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15041 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15042 // If the caller has this permission, they always pass go. And collect $200. 15043 allow = true; 15044 } else if (allowMode == ALLOW_FULL_ONLY) { 15045 // We require full access, sucks to be you. 15046 allow = false; 15047 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15048 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15049 // If the caller does not have either permission, they are always doomed. 15050 allow = false; 15051 } else if (allowMode == ALLOW_NON_FULL) { 15052 // We are blanket allowing non-full access, you lucky caller! 15053 allow = true; 15054 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15055 // We may or may not allow this depending on whether the two users are 15056 // in the same profile. 15057 synchronized (mUserProfileGroupIdsSelfLocked) { 15058 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15059 UserInfo.NO_PROFILE_GROUP_ID); 15060 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15061 UserInfo.NO_PROFILE_GROUP_ID); 15062 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15063 && callingProfile == targetProfile; 15064 } 15065 } else { 15066 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15067 } 15068 if (!allow) { 15069 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15070 // In this case, they would like to just execute as their 15071 // owner user instead of failing. 15072 targetUserId = callingUserId; 15073 } else { 15074 StringBuilder builder = new StringBuilder(128); 15075 builder.append("Permission Denial: "); 15076 builder.append(name); 15077 if (callerPackage != null) { 15078 builder.append(" from "); 15079 builder.append(callerPackage); 15080 } 15081 builder.append(" asks to run as user "); 15082 builder.append(userId); 15083 builder.append(" but is calling from user "); 15084 builder.append(UserHandle.getUserId(callingUid)); 15085 builder.append("; this requires "); 15086 builder.append(INTERACT_ACROSS_USERS_FULL); 15087 if (allowMode != ALLOW_FULL_ONLY) { 15088 builder.append(" or "); 15089 builder.append(INTERACT_ACROSS_USERS); 15090 } 15091 String msg = builder.toString(); 15092 Slog.w(TAG, msg); 15093 throw new SecurityException(msg); 15094 } 15095 } 15096 } 15097 if (!allowAll && targetUserId < 0) { 15098 throw new IllegalArgumentException( 15099 "Call does not support special user #" + targetUserId); 15100 } 15101 // Check shell permission 15102 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15103 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15104 targetUserId)) { 15105 throw new SecurityException("Shell does not have permission to access user " 15106 + targetUserId + "\n " + Debug.getCallers(3)); 15107 } 15108 } 15109 return targetUserId; 15110 } 15111 15112 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15113 String className, int flags) { 15114 boolean result = false; 15115 // For apps that don't have pre-defined UIDs, check for permission 15116 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15117 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15118 if (ActivityManager.checkUidPermission( 15119 INTERACT_ACROSS_USERS, 15120 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15121 ComponentName comp = new ComponentName(aInfo.packageName, className); 15122 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15123 + " requests FLAG_SINGLE_USER, but app does not hold " 15124 + INTERACT_ACROSS_USERS; 15125 Slog.w(TAG, msg); 15126 throw new SecurityException(msg); 15127 } 15128 // Permission passed 15129 result = true; 15130 } 15131 } else if ("system".equals(componentProcessName)) { 15132 result = true; 15133 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15134 // Phone app and persistent apps are allowed to export singleuser providers. 15135 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15136 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15137 } 15138 if (DEBUG_MU) { 15139 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15140 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15141 } 15142 return result; 15143 } 15144 15145 /** 15146 * Checks to see if the caller is in the same app as the singleton 15147 * component, or the component is in a special app. It allows special apps 15148 * to export singleton components but prevents exporting singleton 15149 * components for regular apps. 15150 */ 15151 boolean isValidSingletonCall(int callingUid, int componentUid) { 15152 int componentAppId = UserHandle.getAppId(componentUid); 15153 return UserHandle.isSameApp(callingUid, componentUid) 15154 || componentAppId == Process.SYSTEM_UID 15155 || componentAppId == Process.PHONE_UID 15156 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15157 == PackageManager.PERMISSION_GRANTED; 15158 } 15159 15160 public int bindService(IApplicationThread caller, IBinder token, 15161 Intent service, String resolvedType, 15162 IServiceConnection connection, int flags, int userId) { 15163 enforceNotIsolatedCaller("bindService"); 15164 15165 // Refuse possible leaked file descriptors 15166 if (service != null && service.hasFileDescriptors() == true) { 15167 throw new IllegalArgumentException("File descriptors passed in Intent"); 15168 } 15169 15170 synchronized(this) { 15171 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15172 connection, flags, userId); 15173 } 15174 } 15175 15176 public boolean unbindService(IServiceConnection connection) { 15177 synchronized (this) { 15178 return mServices.unbindServiceLocked(connection); 15179 } 15180 } 15181 15182 public void publishService(IBinder token, Intent intent, IBinder service) { 15183 // Refuse possible leaked file descriptors 15184 if (intent != null && intent.hasFileDescriptors() == true) { 15185 throw new IllegalArgumentException("File descriptors passed in Intent"); 15186 } 15187 15188 synchronized(this) { 15189 if (!(token instanceof ServiceRecord)) { 15190 throw new IllegalArgumentException("Invalid service token"); 15191 } 15192 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15193 } 15194 } 15195 15196 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15197 // Refuse possible leaked file descriptors 15198 if (intent != null && intent.hasFileDescriptors() == true) { 15199 throw new IllegalArgumentException("File descriptors passed in Intent"); 15200 } 15201 15202 synchronized(this) { 15203 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15204 } 15205 } 15206 15207 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15208 synchronized(this) { 15209 if (!(token instanceof ServiceRecord)) { 15210 throw new IllegalArgumentException("Invalid service token"); 15211 } 15212 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15213 } 15214 } 15215 15216 // ========================================================= 15217 // BACKUP AND RESTORE 15218 // ========================================================= 15219 15220 // Cause the target app to be launched if necessary and its backup agent 15221 // instantiated. The backup agent will invoke backupAgentCreated() on the 15222 // activity manager to announce its creation. 15223 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15224 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15225 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15226 15227 synchronized(this) { 15228 // !!! TODO: currently no check here that we're already bound 15229 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15230 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15231 synchronized (stats) { 15232 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15233 } 15234 15235 // Backup agent is now in use, its package can't be stopped. 15236 try { 15237 AppGlobals.getPackageManager().setPackageStoppedState( 15238 app.packageName, false, UserHandle.getUserId(app.uid)); 15239 } catch (RemoteException e) { 15240 } catch (IllegalArgumentException e) { 15241 Slog.w(TAG, "Failed trying to unstop package " 15242 + app.packageName + ": " + e); 15243 } 15244 15245 BackupRecord r = new BackupRecord(ss, app, backupMode); 15246 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15247 ? new ComponentName(app.packageName, app.backupAgentName) 15248 : new ComponentName("android", "FullBackupAgent"); 15249 // startProcessLocked() returns existing proc's record if it's already running 15250 ProcessRecord proc = startProcessLocked(app.processName, app, 15251 false, 0, "backup", hostingName, false, false, false); 15252 if (proc == null) { 15253 Slog.e(TAG, "Unable to start backup agent process " + r); 15254 return false; 15255 } 15256 15257 r.app = proc; 15258 mBackupTarget = r; 15259 mBackupAppName = app.packageName; 15260 15261 // Try not to kill the process during backup 15262 updateOomAdjLocked(proc); 15263 15264 // If the process is already attached, schedule the creation of the backup agent now. 15265 // If it is not yet live, this will be done when it attaches to the framework. 15266 if (proc.thread != null) { 15267 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15268 try { 15269 proc.thread.scheduleCreateBackupAgent(app, 15270 compatibilityInfoForPackageLocked(app), backupMode); 15271 } catch (RemoteException e) { 15272 // Will time out on the backup manager side 15273 } 15274 } else { 15275 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15276 } 15277 // Invariants: at this point, the target app process exists and the application 15278 // is either already running or in the process of coming up. mBackupTarget and 15279 // mBackupAppName describe the app, so that when it binds back to the AM we 15280 // know that it's scheduled for a backup-agent operation. 15281 } 15282 15283 return true; 15284 } 15285 15286 @Override 15287 public void clearPendingBackup() { 15288 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15289 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15290 15291 synchronized (this) { 15292 mBackupTarget = null; 15293 mBackupAppName = null; 15294 } 15295 } 15296 15297 // A backup agent has just come up 15298 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15299 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15300 + " = " + agent); 15301 15302 synchronized(this) { 15303 if (!agentPackageName.equals(mBackupAppName)) { 15304 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15305 return; 15306 } 15307 } 15308 15309 long oldIdent = Binder.clearCallingIdentity(); 15310 try { 15311 IBackupManager bm = IBackupManager.Stub.asInterface( 15312 ServiceManager.getService(Context.BACKUP_SERVICE)); 15313 bm.agentConnected(agentPackageName, agent); 15314 } catch (RemoteException e) { 15315 // can't happen; the backup manager service is local 15316 } catch (Exception e) { 15317 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15318 e.printStackTrace(); 15319 } finally { 15320 Binder.restoreCallingIdentity(oldIdent); 15321 } 15322 } 15323 15324 // done with this agent 15325 public void unbindBackupAgent(ApplicationInfo appInfo) { 15326 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15327 if (appInfo == null) { 15328 Slog.w(TAG, "unbind backup agent for null app"); 15329 return; 15330 } 15331 15332 synchronized(this) { 15333 try { 15334 if (mBackupAppName == null) { 15335 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15336 return; 15337 } 15338 15339 if (!mBackupAppName.equals(appInfo.packageName)) { 15340 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15341 return; 15342 } 15343 15344 // Not backing this app up any more; reset its OOM adjustment 15345 final ProcessRecord proc = mBackupTarget.app; 15346 updateOomAdjLocked(proc); 15347 15348 // If the app crashed during backup, 'thread' will be null here 15349 if (proc.thread != null) { 15350 try { 15351 proc.thread.scheduleDestroyBackupAgent(appInfo, 15352 compatibilityInfoForPackageLocked(appInfo)); 15353 } catch (Exception e) { 15354 Slog.e(TAG, "Exception when unbinding backup agent:"); 15355 e.printStackTrace(); 15356 } 15357 } 15358 } finally { 15359 mBackupTarget = null; 15360 mBackupAppName = null; 15361 } 15362 } 15363 } 15364 // ========================================================= 15365 // BROADCASTS 15366 // ========================================================= 15367 15368 private final List getStickiesLocked(String action, IntentFilter filter, 15369 List cur, int userId) { 15370 final ContentResolver resolver = mContext.getContentResolver(); 15371 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15372 if (stickies == null) { 15373 return cur; 15374 } 15375 final ArrayList<Intent> list = stickies.get(action); 15376 if (list == null) { 15377 return cur; 15378 } 15379 int N = list.size(); 15380 for (int i=0; i<N; i++) { 15381 Intent intent = list.get(i); 15382 if (filter.match(resolver, intent, true, TAG) >= 0) { 15383 if (cur == null) { 15384 cur = new ArrayList<Intent>(); 15385 } 15386 cur.add(intent); 15387 } 15388 } 15389 return cur; 15390 } 15391 15392 boolean isPendingBroadcastProcessLocked(int pid) { 15393 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15394 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15395 } 15396 15397 void skipPendingBroadcastLocked(int pid) { 15398 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15399 for (BroadcastQueue queue : mBroadcastQueues) { 15400 queue.skipPendingBroadcastLocked(pid); 15401 } 15402 } 15403 15404 // The app just attached; send any pending broadcasts that it should receive 15405 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15406 boolean didSomething = false; 15407 for (BroadcastQueue queue : mBroadcastQueues) { 15408 didSomething |= queue.sendPendingBroadcastsLocked(app); 15409 } 15410 return didSomething; 15411 } 15412 15413 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15414 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15415 enforceNotIsolatedCaller("registerReceiver"); 15416 int callingUid; 15417 int callingPid; 15418 synchronized(this) { 15419 ProcessRecord callerApp = null; 15420 if (caller != null) { 15421 callerApp = getRecordForAppLocked(caller); 15422 if (callerApp == null) { 15423 throw new SecurityException( 15424 "Unable to find app for caller " + caller 15425 + " (pid=" + Binder.getCallingPid() 15426 + ") when registering receiver " + receiver); 15427 } 15428 if (callerApp.info.uid != Process.SYSTEM_UID && 15429 !callerApp.pkgList.containsKey(callerPackage) && 15430 !"android".equals(callerPackage)) { 15431 throw new SecurityException("Given caller package " + callerPackage 15432 + " is not running in process " + callerApp); 15433 } 15434 callingUid = callerApp.info.uid; 15435 callingPid = callerApp.pid; 15436 } else { 15437 callerPackage = null; 15438 callingUid = Binder.getCallingUid(); 15439 callingPid = Binder.getCallingPid(); 15440 } 15441 15442 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15443 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15444 15445 List allSticky = null; 15446 15447 // Look for any matching sticky broadcasts... 15448 Iterator actions = filter.actionsIterator(); 15449 if (actions != null) { 15450 while (actions.hasNext()) { 15451 String action = (String)actions.next(); 15452 allSticky = getStickiesLocked(action, filter, allSticky, 15453 UserHandle.USER_ALL); 15454 allSticky = getStickiesLocked(action, filter, allSticky, 15455 UserHandle.getUserId(callingUid)); 15456 } 15457 } else { 15458 allSticky = getStickiesLocked(null, filter, allSticky, 15459 UserHandle.USER_ALL); 15460 allSticky = getStickiesLocked(null, filter, allSticky, 15461 UserHandle.getUserId(callingUid)); 15462 } 15463 15464 // The first sticky in the list is returned directly back to 15465 // the client. 15466 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15467 15468 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15469 + ": " + sticky); 15470 15471 if (receiver == null) { 15472 return sticky; 15473 } 15474 15475 ReceiverList rl 15476 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15477 if (rl == null) { 15478 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15479 userId, receiver); 15480 if (rl.app != null) { 15481 rl.app.receivers.add(rl); 15482 } else { 15483 try { 15484 receiver.asBinder().linkToDeath(rl, 0); 15485 } catch (RemoteException e) { 15486 return sticky; 15487 } 15488 rl.linkedToDeath = true; 15489 } 15490 mRegisteredReceivers.put(receiver.asBinder(), rl); 15491 } else if (rl.uid != callingUid) { 15492 throw new IllegalArgumentException( 15493 "Receiver requested to register for uid " + callingUid 15494 + " was previously registered for uid " + rl.uid); 15495 } else if (rl.pid != callingPid) { 15496 throw new IllegalArgumentException( 15497 "Receiver requested to register for pid " + callingPid 15498 + " was previously registered for pid " + rl.pid); 15499 } else if (rl.userId != userId) { 15500 throw new IllegalArgumentException( 15501 "Receiver requested to register for user " + userId 15502 + " was previously registered for user " + rl.userId); 15503 } 15504 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15505 permission, callingUid, userId); 15506 rl.add(bf); 15507 if (!bf.debugCheck()) { 15508 Slog.w(TAG, "==> For Dynamic broadast"); 15509 } 15510 mReceiverResolver.addFilter(bf); 15511 15512 // Enqueue broadcasts for all existing stickies that match 15513 // this filter. 15514 if (allSticky != null) { 15515 ArrayList receivers = new ArrayList(); 15516 receivers.add(bf); 15517 15518 int N = allSticky.size(); 15519 for (int i=0; i<N; i++) { 15520 Intent intent = (Intent)allSticky.get(i); 15521 BroadcastQueue queue = broadcastQueueForIntent(intent); 15522 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15523 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15524 null, null, false, true, true, -1); 15525 queue.enqueueParallelBroadcastLocked(r); 15526 queue.scheduleBroadcastsLocked(); 15527 } 15528 } 15529 15530 return sticky; 15531 } 15532 } 15533 15534 public void unregisterReceiver(IIntentReceiver receiver) { 15535 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15536 15537 final long origId = Binder.clearCallingIdentity(); 15538 try { 15539 boolean doTrim = false; 15540 15541 synchronized(this) { 15542 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15543 if (rl != null) { 15544 if (rl.curBroadcast != null) { 15545 BroadcastRecord r = rl.curBroadcast; 15546 final boolean doNext = finishReceiverLocked( 15547 receiver.asBinder(), r.resultCode, r.resultData, 15548 r.resultExtras, r.resultAbort); 15549 if (doNext) { 15550 doTrim = true; 15551 r.queue.processNextBroadcast(false); 15552 } 15553 } 15554 15555 if (rl.app != null) { 15556 rl.app.receivers.remove(rl); 15557 } 15558 removeReceiverLocked(rl); 15559 if (rl.linkedToDeath) { 15560 rl.linkedToDeath = false; 15561 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15562 } 15563 } 15564 } 15565 15566 // If we actually concluded any broadcasts, we might now be able 15567 // to trim the recipients' apps from our working set 15568 if (doTrim) { 15569 trimApplications(); 15570 return; 15571 } 15572 15573 } finally { 15574 Binder.restoreCallingIdentity(origId); 15575 } 15576 } 15577 15578 void removeReceiverLocked(ReceiverList rl) { 15579 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15580 int N = rl.size(); 15581 for (int i=0; i<N; i++) { 15582 mReceiverResolver.removeFilter(rl.get(i)); 15583 } 15584 } 15585 15586 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15587 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15588 ProcessRecord r = mLruProcesses.get(i); 15589 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15590 try { 15591 r.thread.dispatchPackageBroadcast(cmd, packages); 15592 } catch (RemoteException ex) { 15593 } 15594 } 15595 } 15596 } 15597 15598 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15599 int callingUid, int[] users) { 15600 List<ResolveInfo> receivers = null; 15601 try { 15602 HashSet<ComponentName> singleUserReceivers = null; 15603 boolean scannedFirstReceivers = false; 15604 for (int user : users) { 15605 // Skip users that have Shell restrictions 15606 if (callingUid == Process.SHELL_UID 15607 && getUserManagerLocked().hasUserRestriction( 15608 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15609 continue; 15610 } 15611 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15612 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15613 if (user != 0 && newReceivers != null) { 15614 // If this is not the primary user, we need to check for 15615 // any receivers that should be filtered out. 15616 for (int i=0; i<newReceivers.size(); i++) { 15617 ResolveInfo ri = newReceivers.get(i); 15618 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15619 newReceivers.remove(i); 15620 i--; 15621 } 15622 } 15623 } 15624 if (newReceivers != null && newReceivers.size() == 0) { 15625 newReceivers = null; 15626 } 15627 if (receivers == null) { 15628 receivers = newReceivers; 15629 } else if (newReceivers != null) { 15630 // We need to concatenate the additional receivers 15631 // found with what we have do far. This would be easy, 15632 // but we also need to de-dup any receivers that are 15633 // singleUser. 15634 if (!scannedFirstReceivers) { 15635 // Collect any single user receivers we had already retrieved. 15636 scannedFirstReceivers = true; 15637 for (int i=0; i<receivers.size(); i++) { 15638 ResolveInfo ri = receivers.get(i); 15639 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15640 ComponentName cn = new ComponentName( 15641 ri.activityInfo.packageName, ri.activityInfo.name); 15642 if (singleUserReceivers == null) { 15643 singleUserReceivers = new HashSet<ComponentName>(); 15644 } 15645 singleUserReceivers.add(cn); 15646 } 15647 } 15648 } 15649 // Add the new results to the existing results, tracking 15650 // and de-dupping single user receivers. 15651 for (int i=0; i<newReceivers.size(); i++) { 15652 ResolveInfo ri = newReceivers.get(i); 15653 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15654 ComponentName cn = new ComponentName( 15655 ri.activityInfo.packageName, ri.activityInfo.name); 15656 if (singleUserReceivers == null) { 15657 singleUserReceivers = new HashSet<ComponentName>(); 15658 } 15659 if (!singleUserReceivers.contains(cn)) { 15660 singleUserReceivers.add(cn); 15661 receivers.add(ri); 15662 } 15663 } else { 15664 receivers.add(ri); 15665 } 15666 } 15667 } 15668 } 15669 } catch (RemoteException ex) { 15670 // pm is in same process, this will never happen. 15671 } 15672 return receivers; 15673 } 15674 15675 private final int broadcastIntentLocked(ProcessRecord callerApp, 15676 String callerPackage, Intent intent, String resolvedType, 15677 IIntentReceiver resultTo, int resultCode, String resultData, 15678 Bundle map, String requiredPermission, int appOp, 15679 boolean ordered, boolean sticky, int callingPid, int callingUid, 15680 int userId) { 15681 intent = new Intent(intent); 15682 15683 // By default broadcasts do not go to stopped apps. 15684 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15685 15686 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15687 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15688 + " ordered=" + ordered + " userid=" + userId); 15689 if ((resultTo != null) && !ordered) { 15690 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15691 } 15692 15693 userId = handleIncomingUser(callingPid, callingUid, userId, 15694 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15695 15696 // Make sure that the user who is receiving this broadcast is running. 15697 // If not, we will just skip it. Make an exception for shutdown broadcasts 15698 // and upgrade steps. 15699 15700 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15701 if ((callingUid != Process.SYSTEM_UID 15702 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15703 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15704 Slog.w(TAG, "Skipping broadcast of " + intent 15705 + ": user " + userId + " is stopped"); 15706 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15707 } 15708 } 15709 15710 /* 15711 * Prevent non-system code (defined here to be non-persistent 15712 * processes) from sending protected broadcasts. 15713 */ 15714 int callingAppId = UserHandle.getAppId(callingUid); 15715 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15716 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15717 || callingAppId == Process.NFC_UID || callingUid == 0) { 15718 // Always okay. 15719 } else if (callerApp == null || !callerApp.persistent) { 15720 try { 15721 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15722 intent.getAction())) { 15723 String msg = "Permission Denial: not allowed to send broadcast " 15724 + intent.getAction() + " from pid=" 15725 + callingPid + ", uid=" + callingUid; 15726 Slog.w(TAG, msg); 15727 throw new SecurityException(msg); 15728 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15729 // Special case for compatibility: we don't want apps to send this, 15730 // but historically it has not been protected and apps may be using it 15731 // to poke their own app widget. So, instead of making it protected, 15732 // just limit it to the caller. 15733 if (callerApp == null) { 15734 String msg = "Permission Denial: not allowed to send broadcast " 15735 + intent.getAction() + " from unknown caller."; 15736 Slog.w(TAG, msg); 15737 throw new SecurityException(msg); 15738 } else if (intent.getComponent() != null) { 15739 // They are good enough to send to an explicit component... verify 15740 // it is being sent to the calling app. 15741 if (!intent.getComponent().getPackageName().equals( 15742 callerApp.info.packageName)) { 15743 String msg = "Permission Denial: not allowed to send broadcast " 15744 + intent.getAction() + " to " 15745 + intent.getComponent().getPackageName() + " from " 15746 + callerApp.info.packageName; 15747 Slog.w(TAG, msg); 15748 throw new SecurityException(msg); 15749 } 15750 } else { 15751 // Limit broadcast to their own package. 15752 intent.setPackage(callerApp.info.packageName); 15753 } 15754 } 15755 } catch (RemoteException e) { 15756 Slog.w(TAG, "Remote exception", e); 15757 return ActivityManager.BROADCAST_SUCCESS; 15758 } 15759 } 15760 15761 final String action = intent.getAction(); 15762 if (action != null) { 15763 switch (action) { 15764 case Intent.ACTION_UID_REMOVED: 15765 case Intent.ACTION_PACKAGE_REMOVED: 15766 case Intent.ACTION_PACKAGE_CHANGED: 15767 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15768 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15769 // Handle special intents: if this broadcast is from the package 15770 // manager about a package being removed, we need to remove all of 15771 // its activities from the history stack. 15772 if (checkComponentPermission( 15773 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15774 callingPid, callingUid, -1, true) 15775 != PackageManager.PERMISSION_GRANTED) { 15776 String msg = "Permission Denial: " + intent.getAction() 15777 + " broadcast from " + callerPackage + " (pid=" + callingPid 15778 + ", uid=" + callingUid + ")" 15779 + " requires " 15780 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15781 Slog.w(TAG, msg); 15782 throw new SecurityException(msg); 15783 } 15784 switch (action) { 15785 case Intent.ACTION_UID_REMOVED: 15786 final Bundle intentExtras = intent.getExtras(); 15787 final int uid = intentExtras != null 15788 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15789 if (uid >= 0) { 15790 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15791 synchronized (bs) { 15792 bs.removeUidStatsLocked(uid); 15793 } 15794 mAppOpsService.uidRemoved(uid); 15795 } 15796 break; 15797 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15798 // If resources are unavailable just force stop all those packages 15799 // and flush the attribute cache as well. 15800 String list[] = 15801 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15802 if (list != null && list.length > 0) { 15803 for (int i = 0; i < list.length; i++) { 15804 forceStopPackageLocked(list[i], -1, false, true, true, 15805 false, false, userId, "storage unmount"); 15806 } 15807 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15808 sendPackageBroadcastLocked( 15809 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15810 userId); 15811 } 15812 break; 15813 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15814 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15815 break; 15816 case Intent.ACTION_PACKAGE_REMOVED: 15817 case Intent.ACTION_PACKAGE_CHANGED: 15818 Uri data = intent.getData(); 15819 String ssp; 15820 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15821 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15822 boolean fullUninstall = removed && 15823 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15824 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15825 forceStopPackageLocked(ssp, UserHandle.getAppId( 15826 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15827 false, true, true, false, fullUninstall, userId, 15828 removed ? "pkg removed" : "pkg changed"); 15829 } 15830 if (removed) { 15831 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15832 new String[] {ssp}, userId); 15833 if (fullUninstall) { 15834 mAppOpsService.packageRemoved( 15835 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15836 15837 // Remove all permissions granted from/to this package 15838 removeUriPermissionsForPackageLocked(ssp, userId, true); 15839 15840 removeTasksByPackageNameLocked(ssp, userId); 15841 } 15842 } else { 15843 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15844 if (userId == UserHandle.USER_OWNER) { 15845 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15846 } 15847 } 15848 } 15849 break; 15850 } 15851 break; 15852 case Intent.ACTION_PACKAGE_ADDED: 15853 // Special case for adding a package: by default turn on compatibility mode. 15854 Uri data = intent.getData(); 15855 String ssp; 15856 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15857 final boolean replacing = 15858 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15859 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15860 15861 if (replacing) { 15862 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15863 } 15864 if (userId == UserHandle.USER_OWNER) { 15865 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15866 } 15867 } 15868 break; 15869 case Intent.ACTION_TIMEZONE_CHANGED: 15870 // If this is the time zone changed action, queue up a message that will reset 15871 // the timezone of all currently running processes. This message will get 15872 // queued up before the broadcast happens. 15873 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15874 break; 15875 case Intent.ACTION_TIME_CHANGED: 15876 // If the user set the time, let all running processes know. 15877 final int is24Hour = 15878 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15879 : 0; 15880 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15881 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15882 synchronized (stats) { 15883 stats.noteCurrentTimeChangedLocked(); 15884 } 15885 break; 15886 case Intent.ACTION_CLEAR_DNS_CACHE: 15887 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15888 break; 15889 case Proxy.PROXY_CHANGE_ACTION: 15890 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15891 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15892 break; 15893 } 15894 } 15895 15896 // Add to the sticky list if requested. 15897 if (sticky) { 15898 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15899 callingPid, callingUid) 15900 != PackageManager.PERMISSION_GRANTED) { 15901 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15902 + callingPid + ", uid=" + callingUid 15903 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15904 Slog.w(TAG, msg); 15905 throw new SecurityException(msg); 15906 } 15907 if (requiredPermission != null) { 15908 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15909 + " and enforce permission " + requiredPermission); 15910 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15911 } 15912 if (intent.getComponent() != null) { 15913 throw new SecurityException( 15914 "Sticky broadcasts can't target a specific component"); 15915 } 15916 // We use userId directly here, since the "all" target is maintained 15917 // as a separate set of sticky broadcasts. 15918 if (userId != UserHandle.USER_ALL) { 15919 // But first, if this is not a broadcast to all users, then 15920 // make sure it doesn't conflict with an existing broadcast to 15921 // all users. 15922 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15923 UserHandle.USER_ALL); 15924 if (stickies != null) { 15925 ArrayList<Intent> list = stickies.get(intent.getAction()); 15926 if (list != null) { 15927 int N = list.size(); 15928 int i; 15929 for (i=0; i<N; i++) { 15930 if (intent.filterEquals(list.get(i))) { 15931 throw new IllegalArgumentException( 15932 "Sticky broadcast " + intent + " for user " 15933 + userId + " conflicts with existing global broadcast"); 15934 } 15935 } 15936 } 15937 } 15938 } 15939 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15940 if (stickies == null) { 15941 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15942 mStickyBroadcasts.put(userId, stickies); 15943 } 15944 ArrayList<Intent> list = stickies.get(intent.getAction()); 15945 if (list == null) { 15946 list = new ArrayList<Intent>(); 15947 stickies.put(intent.getAction(), list); 15948 } 15949 int N = list.size(); 15950 int i; 15951 for (i=0; i<N; i++) { 15952 if (intent.filterEquals(list.get(i))) { 15953 // This sticky already exists, replace it. 15954 list.set(i, new Intent(intent)); 15955 break; 15956 } 15957 } 15958 if (i >= N) { 15959 list.add(new Intent(intent)); 15960 } 15961 } 15962 15963 int[] users; 15964 if (userId == UserHandle.USER_ALL) { 15965 // Caller wants broadcast to go to all started users. 15966 users = mStartedUserArray; 15967 } else { 15968 // Caller wants broadcast to go to one specific user. 15969 users = new int[] {userId}; 15970 } 15971 15972 // Figure out who all will receive this broadcast. 15973 List receivers = null; 15974 List<BroadcastFilter> registeredReceivers = null; 15975 // Need to resolve the intent to interested receivers... 15976 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15977 == 0) { 15978 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15979 } 15980 if (intent.getComponent() == null) { 15981 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15982 // Query one target user at a time, excluding shell-restricted users 15983 UserManagerService ums = getUserManagerLocked(); 15984 for (int i = 0; i < users.length; i++) { 15985 if (ums.hasUserRestriction( 15986 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15987 continue; 15988 } 15989 List<BroadcastFilter> registeredReceiversForUser = 15990 mReceiverResolver.queryIntent(intent, 15991 resolvedType, false, users[i]); 15992 if (registeredReceivers == null) { 15993 registeredReceivers = registeredReceiversForUser; 15994 } else if (registeredReceiversForUser != null) { 15995 registeredReceivers.addAll(registeredReceiversForUser); 15996 } 15997 } 15998 } else { 15999 registeredReceivers = mReceiverResolver.queryIntent(intent, 16000 resolvedType, false, userId); 16001 } 16002 } 16003 16004 final boolean replacePending = 16005 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16006 16007 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16008 + " replacePending=" + replacePending); 16009 16010 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16011 if (!ordered && NR > 0) { 16012 // If we are not serializing this broadcast, then send the 16013 // registered receivers separately so they don't wait for the 16014 // components to be launched. 16015 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16016 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16017 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16018 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16019 ordered, sticky, false, userId); 16020 if (DEBUG_BROADCAST) Slog.v( 16021 TAG, "Enqueueing parallel broadcast " + r); 16022 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16023 if (!replaced) { 16024 queue.enqueueParallelBroadcastLocked(r); 16025 queue.scheduleBroadcastsLocked(); 16026 } 16027 registeredReceivers = null; 16028 NR = 0; 16029 } 16030 16031 // Merge into one list. 16032 int ir = 0; 16033 if (receivers != null) { 16034 // A special case for PACKAGE_ADDED: do not allow the package 16035 // being added to see this broadcast. This prevents them from 16036 // using this as a back door to get run as soon as they are 16037 // installed. Maybe in the future we want to have a special install 16038 // broadcast or such for apps, but we'd like to deliberately make 16039 // this decision. 16040 String skipPackages[] = null; 16041 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16042 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16043 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16044 Uri data = intent.getData(); 16045 if (data != null) { 16046 String pkgName = data.getSchemeSpecificPart(); 16047 if (pkgName != null) { 16048 skipPackages = new String[] { pkgName }; 16049 } 16050 } 16051 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16052 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16053 } 16054 if (skipPackages != null && (skipPackages.length > 0)) { 16055 for (String skipPackage : skipPackages) { 16056 if (skipPackage != null) { 16057 int NT = receivers.size(); 16058 for (int it=0; it<NT; it++) { 16059 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16060 if (curt.activityInfo.packageName.equals(skipPackage)) { 16061 receivers.remove(it); 16062 it--; 16063 NT--; 16064 } 16065 } 16066 } 16067 } 16068 } 16069 16070 int NT = receivers != null ? receivers.size() : 0; 16071 int it = 0; 16072 ResolveInfo curt = null; 16073 BroadcastFilter curr = null; 16074 while (it < NT && ir < NR) { 16075 if (curt == null) { 16076 curt = (ResolveInfo)receivers.get(it); 16077 } 16078 if (curr == null) { 16079 curr = registeredReceivers.get(ir); 16080 } 16081 if (curr.getPriority() >= curt.priority) { 16082 // Insert this broadcast record into the final list. 16083 receivers.add(it, curr); 16084 ir++; 16085 curr = null; 16086 it++; 16087 NT++; 16088 } else { 16089 // Skip to the next ResolveInfo in the final list. 16090 it++; 16091 curt = null; 16092 } 16093 } 16094 } 16095 while (ir < NR) { 16096 if (receivers == null) { 16097 receivers = new ArrayList(); 16098 } 16099 receivers.add(registeredReceivers.get(ir)); 16100 ir++; 16101 } 16102 16103 if ((receivers != null && receivers.size() > 0) 16104 || resultTo != null) { 16105 BroadcastQueue queue = broadcastQueueForIntent(intent); 16106 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16107 callerPackage, callingPid, callingUid, resolvedType, 16108 requiredPermission, appOp, receivers, resultTo, resultCode, 16109 resultData, map, ordered, sticky, false, userId); 16110 if (DEBUG_BROADCAST) Slog.v( 16111 TAG, "Enqueueing ordered broadcast " + r 16112 + ": prev had " + queue.mOrderedBroadcasts.size()); 16113 if (DEBUG_BROADCAST) { 16114 int seq = r.intent.getIntExtra("seq", -1); 16115 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16116 } 16117 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16118 if (!replaced) { 16119 queue.enqueueOrderedBroadcastLocked(r); 16120 queue.scheduleBroadcastsLocked(); 16121 } 16122 } 16123 16124 return ActivityManager.BROADCAST_SUCCESS; 16125 } 16126 16127 final Intent verifyBroadcastLocked(Intent intent) { 16128 // Refuse possible leaked file descriptors 16129 if (intent != null && intent.hasFileDescriptors() == true) { 16130 throw new IllegalArgumentException("File descriptors passed in Intent"); 16131 } 16132 16133 int flags = intent.getFlags(); 16134 16135 if (!mProcessesReady) { 16136 // if the caller really truly claims to know what they're doing, go 16137 // ahead and allow the broadcast without launching any receivers 16138 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16139 intent = new Intent(intent); 16140 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16141 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16142 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16143 + " before boot completion"); 16144 throw new IllegalStateException("Cannot broadcast before boot completed"); 16145 } 16146 } 16147 16148 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16149 throw new IllegalArgumentException( 16150 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16151 } 16152 16153 return intent; 16154 } 16155 16156 public final int broadcastIntent(IApplicationThread caller, 16157 Intent intent, String resolvedType, IIntentReceiver resultTo, 16158 int resultCode, String resultData, Bundle map, 16159 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16160 enforceNotIsolatedCaller("broadcastIntent"); 16161 synchronized(this) { 16162 intent = verifyBroadcastLocked(intent); 16163 16164 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16165 final int callingPid = Binder.getCallingPid(); 16166 final int callingUid = Binder.getCallingUid(); 16167 final long origId = Binder.clearCallingIdentity(); 16168 int res = broadcastIntentLocked(callerApp, 16169 callerApp != null ? callerApp.info.packageName : null, 16170 intent, resolvedType, resultTo, 16171 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16172 callingPid, callingUid, userId); 16173 Binder.restoreCallingIdentity(origId); 16174 return res; 16175 } 16176 } 16177 16178 int broadcastIntentInPackage(String packageName, int uid, 16179 Intent intent, String resolvedType, IIntentReceiver resultTo, 16180 int resultCode, String resultData, Bundle map, 16181 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16182 synchronized(this) { 16183 intent = verifyBroadcastLocked(intent); 16184 16185 final long origId = Binder.clearCallingIdentity(); 16186 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16187 resultTo, resultCode, resultData, map, requiredPermission, 16188 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16189 Binder.restoreCallingIdentity(origId); 16190 return res; 16191 } 16192 } 16193 16194 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16195 // Refuse possible leaked file descriptors 16196 if (intent != null && intent.hasFileDescriptors() == true) { 16197 throw new IllegalArgumentException("File descriptors passed in Intent"); 16198 } 16199 16200 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16201 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16202 16203 synchronized(this) { 16204 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16205 != PackageManager.PERMISSION_GRANTED) { 16206 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16207 + Binder.getCallingPid() 16208 + ", uid=" + Binder.getCallingUid() 16209 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16210 Slog.w(TAG, msg); 16211 throw new SecurityException(msg); 16212 } 16213 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16214 if (stickies != null) { 16215 ArrayList<Intent> list = stickies.get(intent.getAction()); 16216 if (list != null) { 16217 int N = list.size(); 16218 int i; 16219 for (i=0; i<N; i++) { 16220 if (intent.filterEquals(list.get(i))) { 16221 list.remove(i); 16222 break; 16223 } 16224 } 16225 if (list.size() <= 0) { 16226 stickies.remove(intent.getAction()); 16227 } 16228 } 16229 if (stickies.size() <= 0) { 16230 mStickyBroadcasts.remove(userId); 16231 } 16232 } 16233 } 16234 } 16235 16236 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16237 String resultData, Bundle resultExtras, boolean resultAbort) { 16238 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16239 if (r == null) { 16240 Slog.w(TAG, "finishReceiver called but not found on queue"); 16241 return false; 16242 } 16243 16244 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16245 } 16246 16247 void backgroundServicesFinishedLocked(int userId) { 16248 for (BroadcastQueue queue : mBroadcastQueues) { 16249 queue.backgroundServicesFinishedLocked(userId); 16250 } 16251 } 16252 16253 public void finishReceiver(IBinder who, int resultCode, String resultData, 16254 Bundle resultExtras, boolean resultAbort) { 16255 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16256 16257 // Refuse possible leaked file descriptors 16258 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16259 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16260 } 16261 16262 final long origId = Binder.clearCallingIdentity(); 16263 try { 16264 boolean doNext = false; 16265 BroadcastRecord r; 16266 16267 synchronized(this) { 16268 r = broadcastRecordForReceiverLocked(who); 16269 if (r != null) { 16270 doNext = r.queue.finishReceiverLocked(r, resultCode, 16271 resultData, resultExtras, resultAbort, true); 16272 } 16273 } 16274 16275 if (doNext) { 16276 r.queue.processNextBroadcast(false); 16277 } 16278 trimApplications(); 16279 } finally { 16280 Binder.restoreCallingIdentity(origId); 16281 } 16282 } 16283 16284 // ========================================================= 16285 // INSTRUMENTATION 16286 // ========================================================= 16287 16288 public boolean startInstrumentation(ComponentName className, 16289 String profileFile, int flags, Bundle arguments, 16290 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16291 int userId, String abiOverride) { 16292 enforceNotIsolatedCaller("startInstrumentation"); 16293 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16294 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16295 // Refuse possible leaked file descriptors 16296 if (arguments != null && arguments.hasFileDescriptors()) { 16297 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16298 } 16299 16300 synchronized(this) { 16301 InstrumentationInfo ii = null; 16302 ApplicationInfo ai = null; 16303 try { 16304 ii = mContext.getPackageManager().getInstrumentationInfo( 16305 className, STOCK_PM_FLAGS); 16306 ai = AppGlobals.getPackageManager().getApplicationInfo( 16307 ii.targetPackage, STOCK_PM_FLAGS, userId); 16308 } catch (PackageManager.NameNotFoundException e) { 16309 } catch (RemoteException e) { 16310 } 16311 if (ii == null) { 16312 reportStartInstrumentationFailure(watcher, className, 16313 "Unable to find instrumentation info for: " + className); 16314 return false; 16315 } 16316 if (ai == null) { 16317 reportStartInstrumentationFailure(watcher, className, 16318 "Unable to find instrumentation target package: " + ii.targetPackage); 16319 return false; 16320 } 16321 16322 int match = mContext.getPackageManager().checkSignatures( 16323 ii.targetPackage, ii.packageName); 16324 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16325 String msg = "Permission Denial: starting instrumentation " 16326 + className + " from pid=" 16327 + Binder.getCallingPid() 16328 + ", uid=" + Binder.getCallingPid() 16329 + " not allowed because package " + ii.packageName 16330 + " does not have a signature matching the target " 16331 + ii.targetPackage; 16332 reportStartInstrumentationFailure(watcher, className, msg); 16333 throw new SecurityException(msg); 16334 } 16335 16336 final long origId = Binder.clearCallingIdentity(); 16337 // Instrumentation can kill and relaunch even persistent processes 16338 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16339 "start instr"); 16340 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16341 app.instrumentationClass = className; 16342 app.instrumentationInfo = ai; 16343 app.instrumentationProfileFile = profileFile; 16344 app.instrumentationArguments = arguments; 16345 app.instrumentationWatcher = watcher; 16346 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16347 app.instrumentationResultClass = className; 16348 Binder.restoreCallingIdentity(origId); 16349 } 16350 16351 return true; 16352 } 16353 16354 /** 16355 * Report errors that occur while attempting to start Instrumentation. Always writes the 16356 * error to the logs, but if somebody is watching, send the report there too. This enables 16357 * the "am" command to report errors with more information. 16358 * 16359 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16360 * @param cn The component name of the instrumentation. 16361 * @param report The error report. 16362 */ 16363 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16364 ComponentName cn, String report) { 16365 Slog.w(TAG, report); 16366 try { 16367 if (watcher != null) { 16368 Bundle results = new Bundle(); 16369 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16370 results.putString("Error", report); 16371 watcher.instrumentationStatus(cn, -1, results); 16372 } 16373 } catch (RemoteException e) { 16374 Slog.w(TAG, e); 16375 } 16376 } 16377 16378 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16379 if (app.instrumentationWatcher != null) { 16380 try { 16381 // NOTE: IInstrumentationWatcher *must* be oneway here 16382 app.instrumentationWatcher.instrumentationFinished( 16383 app.instrumentationClass, 16384 resultCode, 16385 results); 16386 } catch (RemoteException e) { 16387 } 16388 } 16389 if (app.instrumentationUiAutomationConnection != null) { 16390 try { 16391 app.instrumentationUiAutomationConnection.shutdown(); 16392 } catch (RemoteException re) { 16393 /* ignore */ 16394 } 16395 // Only a UiAutomation can set this flag and now that 16396 // it is finished we make sure it is reset to its default. 16397 mUserIsMonkey = false; 16398 } 16399 app.instrumentationWatcher = null; 16400 app.instrumentationUiAutomationConnection = null; 16401 app.instrumentationClass = null; 16402 app.instrumentationInfo = null; 16403 app.instrumentationProfileFile = null; 16404 app.instrumentationArguments = null; 16405 16406 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16407 "finished inst"); 16408 } 16409 16410 public void finishInstrumentation(IApplicationThread target, 16411 int resultCode, Bundle results) { 16412 int userId = UserHandle.getCallingUserId(); 16413 // Refuse possible leaked file descriptors 16414 if (results != null && results.hasFileDescriptors()) { 16415 throw new IllegalArgumentException("File descriptors passed in Intent"); 16416 } 16417 16418 synchronized(this) { 16419 ProcessRecord app = getRecordForAppLocked(target); 16420 if (app == null) { 16421 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16422 return; 16423 } 16424 final long origId = Binder.clearCallingIdentity(); 16425 finishInstrumentationLocked(app, resultCode, results); 16426 Binder.restoreCallingIdentity(origId); 16427 } 16428 } 16429 16430 // ========================================================= 16431 // CONFIGURATION 16432 // ========================================================= 16433 16434 public ConfigurationInfo getDeviceConfigurationInfo() { 16435 ConfigurationInfo config = new ConfigurationInfo(); 16436 synchronized (this) { 16437 config.reqTouchScreen = mConfiguration.touchscreen; 16438 config.reqKeyboardType = mConfiguration.keyboard; 16439 config.reqNavigation = mConfiguration.navigation; 16440 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16441 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16442 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16443 } 16444 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16445 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16446 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16447 } 16448 config.reqGlEsVersion = GL_ES_VERSION; 16449 } 16450 return config; 16451 } 16452 16453 ActivityStack getFocusedStack() { 16454 return mStackSupervisor.getFocusedStack(); 16455 } 16456 16457 public Configuration getConfiguration() { 16458 Configuration ci; 16459 synchronized(this) { 16460 ci = new Configuration(mConfiguration); 16461 } 16462 return ci; 16463 } 16464 16465 public void updatePersistentConfiguration(Configuration values) { 16466 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16467 "updateConfiguration()"); 16468 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16469 "updateConfiguration()"); 16470 if (values == null) { 16471 throw new NullPointerException("Configuration must not be null"); 16472 } 16473 16474 synchronized(this) { 16475 final long origId = Binder.clearCallingIdentity(); 16476 updateConfigurationLocked(values, null, true, false); 16477 Binder.restoreCallingIdentity(origId); 16478 } 16479 } 16480 16481 public void updateConfiguration(Configuration values) { 16482 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16483 "updateConfiguration()"); 16484 16485 synchronized(this) { 16486 if (values == null && mWindowManager != null) { 16487 // sentinel: fetch the current configuration from the window manager 16488 values = mWindowManager.computeNewConfiguration(); 16489 } 16490 16491 if (mWindowManager != null) { 16492 mProcessList.applyDisplaySize(mWindowManager); 16493 } 16494 16495 final long origId = Binder.clearCallingIdentity(); 16496 if (values != null) { 16497 Settings.System.clearConfiguration(values); 16498 } 16499 updateConfigurationLocked(values, null, false, false); 16500 Binder.restoreCallingIdentity(origId); 16501 } 16502 } 16503 16504 /** 16505 * Do either or both things: (1) change the current configuration, and (2) 16506 * make sure the given activity is running with the (now) current 16507 * configuration. Returns true if the activity has been left running, or 16508 * false if <var>starting</var> is being destroyed to match the new 16509 * configuration. 16510 * @param persistent TODO 16511 */ 16512 boolean updateConfigurationLocked(Configuration values, 16513 ActivityRecord starting, boolean persistent, boolean initLocale) { 16514 int changes = 0; 16515 16516 if (values != null) { 16517 Configuration newConfig = new Configuration(mConfiguration); 16518 changes = newConfig.updateFrom(values); 16519 if (changes != 0) { 16520 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16521 Slog.i(TAG, "Updating configuration to: " + values); 16522 } 16523 16524 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16525 16526 if (values.locale != null && !initLocale) { 16527 saveLocaleLocked(values.locale, 16528 !values.locale.equals(mConfiguration.locale), 16529 values.userSetLocale); 16530 } 16531 16532 mConfigurationSeq++; 16533 if (mConfigurationSeq <= 0) { 16534 mConfigurationSeq = 1; 16535 } 16536 newConfig.seq = mConfigurationSeq; 16537 mConfiguration = newConfig; 16538 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16539 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16540 //mUsageStatsService.noteStartConfig(newConfig); 16541 16542 final Configuration configCopy = new Configuration(mConfiguration); 16543 16544 // TODO: If our config changes, should we auto dismiss any currently 16545 // showing dialogs? 16546 mShowDialogs = shouldShowDialogs(newConfig); 16547 16548 AttributeCache ac = AttributeCache.instance(); 16549 if (ac != null) { 16550 ac.updateConfiguration(configCopy); 16551 } 16552 16553 // Make sure all resources in our process are updated 16554 // right now, so that anyone who is going to retrieve 16555 // resource values after we return will be sure to get 16556 // the new ones. This is especially important during 16557 // boot, where the first config change needs to guarantee 16558 // all resources have that config before following boot 16559 // code is executed. 16560 mSystemThread.applyConfigurationToResources(configCopy); 16561 16562 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16563 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16564 msg.obj = new Configuration(configCopy); 16565 mHandler.sendMessage(msg); 16566 } 16567 16568 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16569 ProcessRecord app = mLruProcesses.get(i); 16570 try { 16571 if (app.thread != null) { 16572 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16573 + app.processName + " new config " + mConfiguration); 16574 app.thread.scheduleConfigurationChanged(configCopy); 16575 } 16576 } catch (Exception e) { 16577 } 16578 } 16579 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16580 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16581 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16582 | Intent.FLAG_RECEIVER_FOREGROUND); 16583 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16584 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16585 Process.SYSTEM_UID, UserHandle.USER_ALL); 16586 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16587 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16588 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16589 broadcastIntentLocked(null, null, intent, 16590 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16591 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16592 } 16593 } 16594 } 16595 16596 boolean kept = true; 16597 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16598 // mainStack is null during startup. 16599 if (mainStack != null) { 16600 if (changes != 0 && starting == null) { 16601 // If the configuration changed, and the caller is not already 16602 // in the process of starting an activity, then find the top 16603 // activity to check if its configuration needs to change. 16604 starting = mainStack.topRunningActivityLocked(null); 16605 } 16606 16607 if (starting != null) { 16608 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16609 // And we need to make sure at this point that all other activities 16610 // are made visible with the correct configuration. 16611 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16612 } 16613 } 16614 16615 if (values != null && mWindowManager != null) { 16616 mWindowManager.setNewConfiguration(mConfiguration); 16617 } 16618 16619 return kept; 16620 } 16621 16622 /** 16623 * Decide based on the configuration whether we should shouw the ANR, 16624 * crash, etc dialogs. The idea is that if there is no affordnace to 16625 * press the on-screen buttons, we shouldn't show the dialog. 16626 * 16627 * A thought: SystemUI might also want to get told about this, the Power 16628 * dialog / global actions also might want different behaviors. 16629 */ 16630 private static final boolean shouldShowDialogs(Configuration config) { 16631 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16632 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16633 } 16634 16635 /** 16636 * Save the locale. You must be inside a synchronized (this) block. 16637 */ 16638 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16639 if(isDiff) { 16640 SystemProperties.set("user.language", l.getLanguage()); 16641 SystemProperties.set("user.region", l.getCountry()); 16642 } 16643 16644 if(isPersist) { 16645 SystemProperties.set("persist.sys.language", l.getLanguage()); 16646 SystemProperties.set("persist.sys.country", l.getCountry()); 16647 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16648 16649 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16650 } 16651 } 16652 16653 @Override 16654 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16655 synchronized (this) { 16656 ActivityRecord srec = ActivityRecord.forToken(token); 16657 if (srec.task != null && srec.task.stack != null) { 16658 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16659 } 16660 } 16661 return false; 16662 } 16663 16664 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16665 Intent resultData) { 16666 16667 synchronized (this) { 16668 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16669 if (stack != null) { 16670 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16671 } 16672 return false; 16673 } 16674 } 16675 16676 public int getLaunchedFromUid(IBinder activityToken) { 16677 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16678 if (srec == null) { 16679 return -1; 16680 } 16681 return srec.launchedFromUid; 16682 } 16683 16684 public String getLaunchedFromPackage(IBinder activityToken) { 16685 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16686 if (srec == null) { 16687 return null; 16688 } 16689 return srec.launchedFromPackage; 16690 } 16691 16692 // ========================================================= 16693 // LIFETIME MANAGEMENT 16694 // ========================================================= 16695 16696 // Returns which broadcast queue the app is the current [or imminent] receiver 16697 // on, or 'null' if the app is not an active broadcast recipient. 16698 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16699 BroadcastRecord r = app.curReceiver; 16700 if (r != null) { 16701 return r.queue; 16702 } 16703 16704 // It's not the current receiver, but it might be starting up to become one 16705 synchronized (this) { 16706 for (BroadcastQueue queue : mBroadcastQueues) { 16707 r = queue.mPendingBroadcast; 16708 if (r != null && r.curApp == app) { 16709 // found it; report which queue it's in 16710 return queue; 16711 } 16712 } 16713 } 16714 16715 return null; 16716 } 16717 16718 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16719 boolean doingAll, long now) { 16720 if (mAdjSeq == app.adjSeq) { 16721 // This adjustment has already been computed. 16722 return app.curRawAdj; 16723 } 16724 16725 if (app.thread == null) { 16726 app.adjSeq = mAdjSeq; 16727 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16728 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16729 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16730 } 16731 16732 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16733 app.adjSource = null; 16734 app.adjTarget = null; 16735 app.empty = false; 16736 app.cached = false; 16737 16738 final int activitiesSize = app.activities.size(); 16739 16740 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16741 // The max adjustment doesn't allow this app to be anything 16742 // below foreground, so it is not worth doing work for it. 16743 app.adjType = "fixed"; 16744 app.adjSeq = mAdjSeq; 16745 app.curRawAdj = app.maxAdj; 16746 app.foregroundActivities = false; 16747 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16748 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16749 // System processes can do UI, and when they do we want to have 16750 // them trim their memory after the user leaves the UI. To 16751 // facilitate this, here we need to determine whether or not it 16752 // is currently showing UI. 16753 app.systemNoUi = true; 16754 if (app == TOP_APP) { 16755 app.systemNoUi = false; 16756 } else if (activitiesSize > 0) { 16757 for (int j = 0; j < activitiesSize; j++) { 16758 final ActivityRecord r = app.activities.get(j); 16759 if (r.visible) { 16760 app.systemNoUi = false; 16761 } 16762 } 16763 } 16764 if (!app.systemNoUi) { 16765 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16766 } 16767 return (app.curAdj=app.maxAdj); 16768 } 16769 16770 app.systemNoUi = false; 16771 16772 // Determine the importance of the process, starting with most 16773 // important to least, and assign an appropriate OOM adjustment. 16774 int adj; 16775 int schedGroup; 16776 int procState; 16777 boolean foregroundActivities = false; 16778 BroadcastQueue queue; 16779 if (app == TOP_APP) { 16780 // The last app on the list is the foreground app. 16781 adj = ProcessList.FOREGROUND_APP_ADJ; 16782 schedGroup = Process.THREAD_GROUP_DEFAULT; 16783 app.adjType = "top-activity"; 16784 foregroundActivities = true; 16785 procState = ActivityManager.PROCESS_STATE_TOP; 16786 } else if (app.instrumentationClass != null) { 16787 // Don't want to kill running instrumentation. 16788 adj = ProcessList.FOREGROUND_APP_ADJ; 16789 schedGroup = Process.THREAD_GROUP_DEFAULT; 16790 app.adjType = "instrumentation"; 16791 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16792 } else if ((queue = isReceivingBroadcast(app)) != null) { 16793 // An app that is currently receiving a broadcast also 16794 // counts as being in the foreground for OOM killer purposes. 16795 // It's placed in a sched group based on the nature of the 16796 // broadcast as reflected by which queue it's active in. 16797 adj = ProcessList.FOREGROUND_APP_ADJ; 16798 schedGroup = (queue == mFgBroadcastQueue) 16799 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16800 app.adjType = "broadcast"; 16801 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16802 } else if (app.executingServices.size() > 0) { 16803 // An app that is currently executing a service callback also 16804 // counts as being in the foreground. 16805 adj = ProcessList.FOREGROUND_APP_ADJ; 16806 schedGroup = app.execServicesFg ? 16807 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16808 app.adjType = "exec-service"; 16809 procState = ActivityManager.PROCESS_STATE_SERVICE; 16810 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16811 } else { 16812 // As far as we know the process is empty. We may change our mind later. 16813 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16814 // At this point we don't actually know the adjustment. Use the cached adj 16815 // value that the caller wants us to. 16816 adj = cachedAdj; 16817 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16818 app.cached = true; 16819 app.empty = true; 16820 app.adjType = "cch-empty"; 16821 } 16822 16823 // Examine all activities if not already foreground. 16824 if (!foregroundActivities && activitiesSize > 0) { 16825 for (int j = 0; j < activitiesSize; j++) { 16826 final ActivityRecord r = app.activities.get(j); 16827 if (r.app != app) { 16828 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16829 + app + "?!?"); 16830 continue; 16831 } 16832 if (r.visible) { 16833 // App has a visible activity; only upgrade adjustment. 16834 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16835 adj = ProcessList.VISIBLE_APP_ADJ; 16836 app.adjType = "visible"; 16837 } 16838 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16839 procState = ActivityManager.PROCESS_STATE_TOP; 16840 } 16841 schedGroup = Process.THREAD_GROUP_DEFAULT; 16842 app.cached = false; 16843 app.empty = false; 16844 foregroundActivities = true; 16845 break; 16846 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16847 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16848 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16849 app.adjType = "pausing"; 16850 } 16851 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16852 procState = ActivityManager.PROCESS_STATE_TOP; 16853 } 16854 schedGroup = Process.THREAD_GROUP_DEFAULT; 16855 app.cached = false; 16856 app.empty = false; 16857 foregroundActivities = true; 16858 } else if (r.state == ActivityState.STOPPING) { 16859 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16860 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16861 app.adjType = "stopping"; 16862 } 16863 // For the process state, we will at this point consider the 16864 // process to be cached. It will be cached either as an activity 16865 // or empty depending on whether the activity is finishing. We do 16866 // this so that we can treat the process as cached for purposes of 16867 // memory trimming (determing current memory level, trim command to 16868 // send to process) since there can be an arbitrary number of stopping 16869 // processes and they should soon all go into the cached state. 16870 if (!r.finishing) { 16871 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16872 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16873 } 16874 } 16875 app.cached = false; 16876 app.empty = false; 16877 foregroundActivities = true; 16878 } else { 16879 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16880 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16881 app.adjType = "cch-act"; 16882 } 16883 } 16884 } 16885 } 16886 16887 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16888 if (app.foregroundServices) { 16889 // The user is aware of this app, so make it visible. 16890 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16891 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16892 app.cached = false; 16893 app.adjType = "fg-service"; 16894 schedGroup = Process.THREAD_GROUP_DEFAULT; 16895 } else if (app.forcingToForeground != null) { 16896 // The user is aware of this app, so make it visible. 16897 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16898 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16899 app.cached = false; 16900 app.adjType = "force-fg"; 16901 app.adjSource = app.forcingToForeground; 16902 schedGroup = Process.THREAD_GROUP_DEFAULT; 16903 } 16904 } 16905 16906 if (app == mHeavyWeightProcess) { 16907 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16908 // We don't want to kill the current heavy-weight process. 16909 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16910 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16911 app.cached = false; 16912 app.adjType = "heavy"; 16913 } 16914 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16915 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16916 } 16917 } 16918 16919 if (app == mHomeProcess) { 16920 if (adj > ProcessList.HOME_APP_ADJ) { 16921 // This process is hosting what we currently consider to be the 16922 // home app, so we don't want to let it go into the background. 16923 adj = ProcessList.HOME_APP_ADJ; 16924 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16925 app.cached = false; 16926 app.adjType = "home"; 16927 } 16928 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16929 procState = ActivityManager.PROCESS_STATE_HOME; 16930 } 16931 } 16932 16933 if (app == mPreviousProcess && app.activities.size() > 0) { 16934 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16935 // This was the previous process that showed UI to the user. 16936 // We want to try to keep it around more aggressively, to give 16937 // a good experience around switching between two apps. 16938 adj = ProcessList.PREVIOUS_APP_ADJ; 16939 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16940 app.cached = false; 16941 app.adjType = "previous"; 16942 } 16943 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16944 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16945 } 16946 } 16947 16948 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16949 + " reason=" + app.adjType); 16950 16951 // By default, we use the computed adjustment. It may be changed if 16952 // there are applications dependent on our services or providers, but 16953 // this gives us a baseline and makes sure we don't get into an 16954 // infinite recursion. 16955 app.adjSeq = mAdjSeq; 16956 app.curRawAdj = adj; 16957 app.hasStartedServices = false; 16958 16959 if (mBackupTarget != null && app == mBackupTarget.app) { 16960 // If possible we want to avoid killing apps while they're being backed up 16961 if (adj > ProcessList.BACKUP_APP_ADJ) { 16962 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16963 adj = ProcessList.BACKUP_APP_ADJ; 16964 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16965 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16966 } 16967 app.adjType = "backup"; 16968 app.cached = false; 16969 } 16970 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16971 procState = ActivityManager.PROCESS_STATE_BACKUP; 16972 } 16973 } 16974 16975 boolean mayBeTop = false; 16976 16977 for (int is = app.services.size()-1; 16978 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16979 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16980 || procState > ActivityManager.PROCESS_STATE_TOP); 16981 is--) { 16982 ServiceRecord s = app.services.valueAt(is); 16983 if (s.startRequested) { 16984 app.hasStartedServices = true; 16985 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16986 procState = ActivityManager.PROCESS_STATE_SERVICE; 16987 } 16988 if (app.hasShownUi && app != mHomeProcess) { 16989 // If this process has shown some UI, let it immediately 16990 // go to the LRU list because it may be pretty heavy with 16991 // UI stuff. We'll tag it with a label just to help 16992 // debug and understand what is going on. 16993 if (adj > ProcessList.SERVICE_ADJ) { 16994 app.adjType = "cch-started-ui-services"; 16995 } 16996 } else { 16997 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16998 // This service has seen some activity within 16999 // recent memory, so we will keep its process ahead 17000 // of the background processes. 17001 if (adj > ProcessList.SERVICE_ADJ) { 17002 adj = ProcessList.SERVICE_ADJ; 17003 app.adjType = "started-services"; 17004 app.cached = false; 17005 } 17006 } 17007 // If we have let the service slide into the background 17008 // state, still have some text describing what it is doing 17009 // even though the service no longer has an impact. 17010 if (adj > ProcessList.SERVICE_ADJ) { 17011 app.adjType = "cch-started-services"; 17012 } 17013 } 17014 } 17015 for (int conni = s.connections.size()-1; 17016 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17017 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17018 || procState > ActivityManager.PROCESS_STATE_TOP); 17019 conni--) { 17020 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17021 for (int i = 0; 17022 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17023 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17024 || procState > ActivityManager.PROCESS_STATE_TOP); 17025 i++) { 17026 // XXX should compute this based on the max of 17027 // all connected clients. 17028 ConnectionRecord cr = clist.get(i); 17029 if (cr.binding.client == app) { 17030 // Binding to ourself is not interesting. 17031 continue; 17032 } 17033 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17034 ProcessRecord client = cr.binding.client; 17035 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17036 TOP_APP, doingAll, now); 17037 int clientProcState = client.curProcState; 17038 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17039 // If the other app is cached for any reason, for purposes here 17040 // we are going to consider it empty. The specific cached state 17041 // doesn't propagate except under certain conditions. 17042 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17043 } 17044 String adjType = null; 17045 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17046 // Not doing bind OOM management, so treat 17047 // this guy more like a started service. 17048 if (app.hasShownUi && app != mHomeProcess) { 17049 // If this process has shown some UI, let it immediately 17050 // go to the LRU list because it may be pretty heavy with 17051 // UI stuff. We'll tag it with a label just to help 17052 // debug and understand what is going on. 17053 if (adj > clientAdj) { 17054 adjType = "cch-bound-ui-services"; 17055 } 17056 app.cached = false; 17057 clientAdj = adj; 17058 clientProcState = procState; 17059 } else { 17060 if (now >= (s.lastActivity 17061 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17062 // This service has not seen activity within 17063 // recent memory, so allow it to drop to the 17064 // LRU list if there is no other reason to keep 17065 // it around. We'll also tag it with a label just 17066 // to help debug and undertand what is going on. 17067 if (adj > clientAdj) { 17068 adjType = "cch-bound-services"; 17069 } 17070 clientAdj = adj; 17071 } 17072 } 17073 } 17074 if (adj > clientAdj) { 17075 // If this process has recently shown UI, and 17076 // the process that is binding to it is less 17077 // important than being visible, then we don't 17078 // care about the binding as much as we care 17079 // about letting this process get into the LRU 17080 // list to be killed and restarted if needed for 17081 // memory. 17082 if (app.hasShownUi && app != mHomeProcess 17083 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17084 adjType = "cch-bound-ui-services"; 17085 } else { 17086 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17087 |Context.BIND_IMPORTANT)) != 0) { 17088 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17089 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17090 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17091 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17092 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17093 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17094 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17095 adj = clientAdj; 17096 } else { 17097 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17098 adj = ProcessList.VISIBLE_APP_ADJ; 17099 } 17100 } 17101 if (!client.cached) { 17102 app.cached = false; 17103 } 17104 adjType = "service"; 17105 } 17106 } 17107 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17108 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17109 schedGroup = Process.THREAD_GROUP_DEFAULT; 17110 } 17111 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17112 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17113 // Special handling of clients who are in the top state. 17114 // We *may* want to consider this process to be in the 17115 // top state as well, but only if there is not another 17116 // reason for it to be running. Being on the top is a 17117 // special state, meaning you are specifically running 17118 // for the current top app. If the process is already 17119 // running in the background for some other reason, it 17120 // is more important to continue considering it to be 17121 // in the background state. 17122 mayBeTop = true; 17123 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17124 } else { 17125 // Special handling for above-top states (persistent 17126 // processes). These should not bring the current process 17127 // into the top state, since they are not on top. Instead 17128 // give them the best state after that. 17129 clientProcState = 17130 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17131 } 17132 } 17133 } else { 17134 if (clientProcState < 17135 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17136 clientProcState = 17137 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17138 } 17139 } 17140 if (procState > clientProcState) { 17141 procState = clientProcState; 17142 } 17143 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17144 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17145 app.pendingUiClean = true; 17146 } 17147 if (adjType != null) { 17148 app.adjType = adjType; 17149 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17150 .REASON_SERVICE_IN_USE; 17151 app.adjSource = cr.binding.client; 17152 app.adjSourceProcState = clientProcState; 17153 app.adjTarget = s.name; 17154 } 17155 } 17156 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17157 app.treatLikeActivity = true; 17158 } 17159 final ActivityRecord a = cr.activity; 17160 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17161 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17162 (a.visible || a.state == ActivityState.RESUMED 17163 || a.state == ActivityState.PAUSING)) { 17164 adj = ProcessList.FOREGROUND_APP_ADJ; 17165 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17166 schedGroup = Process.THREAD_GROUP_DEFAULT; 17167 } 17168 app.cached = false; 17169 app.adjType = "service"; 17170 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17171 .REASON_SERVICE_IN_USE; 17172 app.adjSource = a; 17173 app.adjSourceProcState = procState; 17174 app.adjTarget = s.name; 17175 } 17176 } 17177 } 17178 } 17179 } 17180 17181 for (int provi = app.pubProviders.size()-1; 17182 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17183 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17184 || procState > ActivityManager.PROCESS_STATE_TOP); 17185 provi--) { 17186 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17187 for (int i = cpr.connections.size()-1; 17188 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17189 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17190 || procState > ActivityManager.PROCESS_STATE_TOP); 17191 i--) { 17192 ContentProviderConnection conn = cpr.connections.get(i); 17193 ProcessRecord client = conn.client; 17194 if (client == app) { 17195 // Being our own client is not interesting. 17196 continue; 17197 } 17198 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17199 int clientProcState = client.curProcState; 17200 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17201 // If the other app is cached for any reason, for purposes here 17202 // we are going to consider it empty. 17203 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17204 } 17205 if (adj > clientAdj) { 17206 if (app.hasShownUi && app != mHomeProcess 17207 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17208 app.adjType = "cch-ui-provider"; 17209 } else { 17210 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17211 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17212 app.adjType = "provider"; 17213 } 17214 app.cached &= client.cached; 17215 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17216 .REASON_PROVIDER_IN_USE; 17217 app.adjSource = client; 17218 app.adjSourceProcState = clientProcState; 17219 app.adjTarget = cpr.name; 17220 } 17221 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17222 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17223 // Special handling of clients who are in the top state. 17224 // We *may* want to consider this process to be in the 17225 // top state as well, but only if there is not another 17226 // reason for it to be running. Being on the top is a 17227 // special state, meaning you are specifically running 17228 // for the current top app. If the process is already 17229 // running in the background for some other reason, it 17230 // is more important to continue considering it to be 17231 // in the background state. 17232 mayBeTop = true; 17233 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17234 } else { 17235 // Special handling for above-top states (persistent 17236 // processes). These should not bring the current process 17237 // into the top state, since they are not on top. Instead 17238 // give them the best state after that. 17239 clientProcState = 17240 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17241 } 17242 } 17243 if (procState > clientProcState) { 17244 procState = clientProcState; 17245 } 17246 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17247 schedGroup = Process.THREAD_GROUP_DEFAULT; 17248 } 17249 } 17250 // If the provider has external (non-framework) process 17251 // dependencies, ensure that its adjustment is at least 17252 // FOREGROUND_APP_ADJ. 17253 if (cpr.hasExternalProcessHandles()) { 17254 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17255 adj = ProcessList.FOREGROUND_APP_ADJ; 17256 schedGroup = Process.THREAD_GROUP_DEFAULT; 17257 app.cached = false; 17258 app.adjType = "provider"; 17259 app.adjTarget = cpr.name; 17260 } 17261 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17262 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17263 } 17264 } 17265 } 17266 17267 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17268 // A client of one of our services or providers is in the top state. We 17269 // *may* want to be in the top state, but not if we are already running in 17270 // the background for some other reason. For the decision here, we are going 17271 // to pick out a few specific states that we want to remain in when a client 17272 // is top (states that tend to be longer-term) and otherwise allow it to go 17273 // to the top state. 17274 switch (procState) { 17275 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17276 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17277 case ActivityManager.PROCESS_STATE_SERVICE: 17278 // These all are longer-term states, so pull them up to the top 17279 // of the background states, but not all the way to the top state. 17280 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17281 break; 17282 default: 17283 // Otherwise, top is a better choice, so take it. 17284 procState = ActivityManager.PROCESS_STATE_TOP; 17285 break; 17286 } 17287 } 17288 17289 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17290 if (app.hasClientActivities) { 17291 // This is a cached process, but with client activities. Mark it so. 17292 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17293 app.adjType = "cch-client-act"; 17294 } else if (app.treatLikeActivity) { 17295 // This is a cached process, but somebody wants us to treat it like it has 17296 // an activity, okay! 17297 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17298 app.adjType = "cch-as-act"; 17299 } 17300 } 17301 17302 if (adj == ProcessList.SERVICE_ADJ) { 17303 if (doingAll) { 17304 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17305 mNewNumServiceProcs++; 17306 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17307 if (!app.serviceb) { 17308 // This service isn't far enough down on the LRU list to 17309 // normally be a B service, but if we are low on RAM and it 17310 // is large we want to force it down since we would prefer to 17311 // keep launcher over it. 17312 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17313 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17314 app.serviceHighRam = true; 17315 app.serviceb = true; 17316 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17317 } else { 17318 mNewNumAServiceProcs++; 17319 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17320 } 17321 } else { 17322 app.serviceHighRam = false; 17323 } 17324 } 17325 if (app.serviceb) { 17326 adj = ProcessList.SERVICE_B_ADJ; 17327 } 17328 } 17329 17330 app.curRawAdj = adj; 17331 17332 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17333 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17334 if (adj > app.maxAdj) { 17335 adj = app.maxAdj; 17336 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17337 schedGroup = Process.THREAD_GROUP_DEFAULT; 17338 } 17339 } 17340 17341 // Do final modification to adj. Everything we do between here and applying 17342 // the final setAdj must be done in this function, because we will also use 17343 // it when computing the final cached adj later. Note that we don't need to 17344 // worry about this for max adj above, since max adj will always be used to 17345 // keep it out of the cached vaues. 17346 app.curAdj = app.modifyRawOomAdj(adj); 17347 app.curSchedGroup = schedGroup; 17348 app.curProcState = procState; 17349 app.foregroundActivities = foregroundActivities; 17350 17351 return app.curRawAdj; 17352 } 17353 17354 /** 17355 * Record new PSS sample for a process. 17356 */ 17357 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17358 proc.lastPssTime = now; 17359 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17360 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17361 + ": " + pss + " lastPss=" + proc.lastPss 17362 + " state=" + ProcessList.makeProcStateString(procState)); 17363 if (proc.initialIdlePss == 0) { 17364 proc.initialIdlePss = pss; 17365 } 17366 proc.lastPss = pss; 17367 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17368 proc.lastCachedPss = pss; 17369 } 17370 } 17371 17372 /** 17373 * Schedule PSS collection of a process. 17374 */ 17375 void requestPssLocked(ProcessRecord proc, int procState) { 17376 if (mPendingPssProcesses.contains(proc)) { 17377 return; 17378 } 17379 if (mPendingPssProcesses.size() == 0) { 17380 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17381 } 17382 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17383 proc.pssProcState = procState; 17384 mPendingPssProcesses.add(proc); 17385 } 17386 17387 /** 17388 * Schedule PSS collection of all processes. 17389 */ 17390 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17391 if (!always) { 17392 if (now < (mLastFullPssTime + 17393 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17394 return; 17395 } 17396 } 17397 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17398 mLastFullPssTime = now; 17399 mFullPssPending = true; 17400 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17401 mPendingPssProcesses.clear(); 17402 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17403 ProcessRecord app = mLruProcesses.get(i); 17404 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17405 app.pssProcState = app.setProcState; 17406 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17407 mTestPssMode, isSleeping(), now); 17408 mPendingPssProcesses.add(app); 17409 } 17410 } 17411 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17412 } 17413 17414 public void setTestPssMode(boolean enabled) { 17415 synchronized (this) { 17416 mTestPssMode = enabled; 17417 if (enabled) { 17418 // Whenever we enable the mode, we want to take a snapshot all of current 17419 // process mem use. 17420 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17421 } 17422 } 17423 } 17424 17425 /** 17426 * Ask a given process to GC right now. 17427 */ 17428 final void performAppGcLocked(ProcessRecord app) { 17429 try { 17430 app.lastRequestedGc = SystemClock.uptimeMillis(); 17431 if (app.thread != null) { 17432 if (app.reportLowMemory) { 17433 app.reportLowMemory = false; 17434 app.thread.scheduleLowMemory(); 17435 } else { 17436 app.thread.processInBackground(); 17437 } 17438 } 17439 } catch (Exception e) { 17440 // whatever. 17441 } 17442 } 17443 17444 /** 17445 * Returns true if things are idle enough to perform GCs. 17446 */ 17447 private final boolean canGcNowLocked() { 17448 boolean processingBroadcasts = false; 17449 for (BroadcastQueue q : mBroadcastQueues) { 17450 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17451 processingBroadcasts = true; 17452 } 17453 } 17454 return !processingBroadcasts 17455 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17456 } 17457 17458 /** 17459 * Perform GCs on all processes that are waiting for it, but only 17460 * if things are idle. 17461 */ 17462 final void performAppGcsLocked() { 17463 final int N = mProcessesToGc.size(); 17464 if (N <= 0) { 17465 return; 17466 } 17467 if (canGcNowLocked()) { 17468 while (mProcessesToGc.size() > 0) { 17469 ProcessRecord proc = mProcessesToGc.remove(0); 17470 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17471 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17472 <= SystemClock.uptimeMillis()) { 17473 // To avoid spamming the system, we will GC processes one 17474 // at a time, waiting a few seconds between each. 17475 performAppGcLocked(proc); 17476 scheduleAppGcsLocked(); 17477 return; 17478 } else { 17479 // It hasn't been long enough since we last GCed this 17480 // process... put it in the list to wait for its time. 17481 addProcessToGcListLocked(proc); 17482 break; 17483 } 17484 } 17485 } 17486 17487 scheduleAppGcsLocked(); 17488 } 17489 } 17490 17491 /** 17492 * If all looks good, perform GCs on all processes waiting for them. 17493 */ 17494 final void performAppGcsIfAppropriateLocked() { 17495 if (canGcNowLocked()) { 17496 performAppGcsLocked(); 17497 return; 17498 } 17499 // Still not idle, wait some more. 17500 scheduleAppGcsLocked(); 17501 } 17502 17503 /** 17504 * Schedule the execution of all pending app GCs. 17505 */ 17506 final void scheduleAppGcsLocked() { 17507 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17508 17509 if (mProcessesToGc.size() > 0) { 17510 // Schedule a GC for the time to the next process. 17511 ProcessRecord proc = mProcessesToGc.get(0); 17512 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17513 17514 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17515 long now = SystemClock.uptimeMillis(); 17516 if (when < (now+GC_TIMEOUT)) { 17517 when = now + GC_TIMEOUT; 17518 } 17519 mHandler.sendMessageAtTime(msg, when); 17520 } 17521 } 17522 17523 /** 17524 * Add a process to the array of processes waiting to be GCed. Keeps the 17525 * list in sorted order by the last GC time. The process can't already be 17526 * on the list. 17527 */ 17528 final void addProcessToGcListLocked(ProcessRecord proc) { 17529 boolean added = false; 17530 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17531 if (mProcessesToGc.get(i).lastRequestedGc < 17532 proc.lastRequestedGc) { 17533 added = true; 17534 mProcessesToGc.add(i+1, proc); 17535 break; 17536 } 17537 } 17538 if (!added) { 17539 mProcessesToGc.add(0, proc); 17540 } 17541 } 17542 17543 /** 17544 * Set up to ask a process to GC itself. This will either do it 17545 * immediately, or put it on the list of processes to gc the next 17546 * time things are idle. 17547 */ 17548 final void scheduleAppGcLocked(ProcessRecord app) { 17549 long now = SystemClock.uptimeMillis(); 17550 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17551 return; 17552 } 17553 if (!mProcessesToGc.contains(app)) { 17554 addProcessToGcListLocked(app); 17555 scheduleAppGcsLocked(); 17556 } 17557 } 17558 17559 final void checkExcessivePowerUsageLocked(boolean doKills) { 17560 updateCpuStatsNow(); 17561 17562 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17563 boolean doWakeKills = doKills; 17564 boolean doCpuKills = doKills; 17565 if (mLastPowerCheckRealtime == 0) { 17566 doWakeKills = false; 17567 } 17568 if (mLastPowerCheckUptime == 0) { 17569 doCpuKills = false; 17570 } 17571 if (stats.isScreenOn()) { 17572 doWakeKills = false; 17573 } 17574 final long curRealtime = SystemClock.elapsedRealtime(); 17575 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17576 final long curUptime = SystemClock.uptimeMillis(); 17577 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17578 mLastPowerCheckRealtime = curRealtime; 17579 mLastPowerCheckUptime = curUptime; 17580 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17581 doWakeKills = false; 17582 } 17583 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17584 doCpuKills = false; 17585 } 17586 int i = mLruProcesses.size(); 17587 while (i > 0) { 17588 i--; 17589 ProcessRecord app = mLruProcesses.get(i); 17590 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17591 long wtime; 17592 synchronized (stats) { 17593 wtime = stats.getProcessWakeTime(app.info.uid, 17594 app.pid, curRealtime); 17595 } 17596 long wtimeUsed = wtime - app.lastWakeTime; 17597 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17598 if (DEBUG_POWER) { 17599 StringBuilder sb = new StringBuilder(128); 17600 sb.append("Wake for "); 17601 app.toShortString(sb); 17602 sb.append(": over "); 17603 TimeUtils.formatDuration(realtimeSince, sb); 17604 sb.append(" used "); 17605 TimeUtils.formatDuration(wtimeUsed, sb); 17606 sb.append(" ("); 17607 sb.append((wtimeUsed*100)/realtimeSince); 17608 sb.append("%)"); 17609 Slog.i(TAG, sb.toString()); 17610 sb.setLength(0); 17611 sb.append("CPU for "); 17612 app.toShortString(sb); 17613 sb.append(": over "); 17614 TimeUtils.formatDuration(uptimeSince, sb); 17615 sb.append(" used "); 17616 TimeUtils.formatDuration(cputimeUsed, sb); 17617 sb.append(" ("); 17618 sb.append((cputimeUsed*100)/uptimeSince); 17619 sb.append("%)"); 17620 Slog.i(TAG, sb.toString()); 17621 } 17622 // If a process has held a wake lock for more 17623 // than 50% of the time during this period, 17624 // that sounds bad. Kill! 17625 if (doWakeKills && realtimeSince > 0 17626 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17627 synchronized (stats) { 17628 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17629 realtimeSince, wtimeUsed); 17630 } 17631 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17632 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17633 } else if (doCpuKills && uptimeSince > 0 17634 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17635 synchronized (stats) { 17636 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17637 uptimeSince, cputimeUsed); 17638 } 17639 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17640 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17641 } else { 17642 app.lastWakeTime = wtime; 17643 app.lastCpuTime = app.curCpuTime; 17644 } 17645 } 17646 } 17647 } 17648 17649 private final boolean applyOomAdjLocked(ProcessRecord app, 17650 ProcessRecord TOP_APP, boolean doingAll, long now) { 17651 boolean success = true; 17652 17653 if (app.curRawAdj != app.setRawAdj) { 17654 app.setRawAdj = app.curRawAdj; 17655 } 17656 17657 int changes = 0; 17658 17659 if (app.curAdj != app.setAdj) { 17660 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17661 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17662 TAG, "Set " + app.pid + " " + app.processName + 17663 " adj " + app.curAdj + ": " + app.adjType); 17664 app.setAdj = app.curAdj; 17665 } 17666 17667 if (app.setSchedGroup != app.curSchedGroup) { 17668 app.setSchedGroup = app.curSchedGroup; 17669 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17670 "Setting process group of " + app.processName 17671 + " to " + app.curSchedGroup); 17672 if (app.waitingToKill != null && 17673 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17674 app.kill(app.waitingToKill, true); 17675 success = false; 17676 } else { 17677 if (true) { 17678 long oldId = Binder.clearCallingIdentity(); 17679 try { 17680 Process.setProcessGroup(app.pid, app.curSchedGroup); 17681 } catch (Exception e) { 17682 Slog.w(TAG, "Failed setting process group of " + app.pid 17683 + " to " + app.curSchedGroup); 17684 e.printStackTrace(); 17685 } finally { 17686 Binder.restoreCallingIdentity(oldId); 17687 } 17688 } else { 17689 if (app.thread != null) { 17690 try { 17691 app.thread.setSchedulingGroup(app.curSchedGroup); 17692 } catch (RemoteException e) { 17693 } 17694 } 17695 } 17696 Process.setSwappiness(app.pid, 17697 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17698 } 17699 } 17700 if (app.repForegroundActivities != app.foregroundActivities) { 17701 app.repForegroundActivities = app.foregroundActivities; 17702 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17703 } 17704 if (app.repProcState != app.curProcState) { 17705 app.repProcState = app.curProcState; 17706 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17707 if (app.thread != null) { 17708 try { 17709 if (false) { 17710 //RuntimeException h = new RuntimeException("here"); 17711 Slog.i(TAG, "Sending new process state " + app.repProcState 17712 + " to " + app /*, h*/); 17713 } 17714 app.thread.setProcessState(app.repProcState); 17715 } catch (RemoteException e) { 17716 } 17717 } 17718 } 17719 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17720 app.setProcState)) { 17721 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17722 // Experimental code to more aggressively collect pss while 17723 // running test... the problem is that this tends to collect 17724 // the data right when a process is transitioning between process 17725 // states, which well tend to give noisy data. 17726 long start = SystemClock.uptimeMillis(); 17727 long pss = Debug.getPss(app.pid, mTmpLong, null); 17728 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17729 mPendingPssProcesses.remove(app); 17730 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17731 + " to " + app.curProcState + ": " 17732 + (SystemClock.uptimeMillis()-start) + "ms"); 17733 } 17734 app.lastStateTime = now; 17735 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17736 mTestPssMode, isSleeping(), now); 17737 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17738 + ProcessList.makeProcStateString(app.setProcState) + " to " 17739 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17740 + (app.nextPssTime-now) + ": " + app); 17741 } else { 17742 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17743 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17744 mTestPssMode)))) { 17745 requestPssLocked(app, app.setProcState); 17746 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17747 mTestPssMode, isSleeping(), now); 17748 } else if (false && DEBUG_PSS) { 17749 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17750 } 17751 } 17752 if (app.setProcState != app.curProcState) { 17753 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17754 "Proc state change of " + app.processName 17755 + " to " + app.curProcState); 17756 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17757 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17758 if (setImportant && !curImportant) { 17759 // This app is no longer something we consider important enough to allow to 17760 // use arbitrary amounts of battery power. Note 17761 // its current wake lock time to later know to kill it if 17762 // it is not behaving well. 17763 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17764 synchronized (stats) { 17765 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17766 app.pid, SystemClock.elapsedRealtime()); 17767 } 17768 app.lastCpuTime = app.curCpuTime; 17769 17770 } 17771 app.setProcState = app.curProcState; 17772 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17773 app.notCachedSinceIdle = false; 17774 } 17775 if (!doingAll) { 17776 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17777 } else { 17778 app.procStateChanged = true; 17779 } 17780 } 17781 17782 if (changes != 0) { 17783 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17784 int i = mPendingProcessChanges.size()-1; 17785 ProcessChangeItem item = null; 17786 while (i >= 0) { 17787 item = mPendingProcessChanges.get(i); 17788 if (item.pid == app.pid) { 17789 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17790 break; 17791 } 17792 i--; 17793 } 17794 if (i < 0) { 17795 // No existing item in pending changes; need a new one. 17796 final int NA = mAvailProcessChanges.size(); 17797 if (NA > 0) { 17798 item = mAvailProcessChanges.remove(NA-1); 17799 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17800 } else { 17801 item = new ProcessChangeItem(); 17802 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17803 } 17804 item.changes = 0; 17805 item.pid = app.pid; 17806 item.uid = app.info.uid; 17807 if (mPendingProcessChanges.size() == 0) { 17808 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17809 "*** Enqueueing dispatch processes changed!"); 17810 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17811 } 17812 mPendingProcessChanges.add(item); 17813 } 17814 item.changes |= changes; 17815 item.processState = app.repProcState; 17816 item.foregroundActivities = app.repForegroundActivities; 17817 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17818 + Integer.toHexString(System.identityHashCode(item)) 17819 + " " + app.toShortString() + ": changes=" + item.changes 17820 + " procState=" + item.processState 17821 + " foreground=" + item.foregroundActivities 17822 + " type=" + app.adjType + " source=" + app.adjSource 17823 + " target=" + app.adjTarget); 17824 } 17825 17826 return success; 17827 } 17828 17829 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17830 if (proc.thread != null) { 17831 if (proc.baseProcessTracker != null) { 17832 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17833 } 17834 if (proc.repProcState >= 0) { 17835 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17836 proc.repProcState); 17837 } 17838 } 17839 } 17840 17841 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17842 ProcessRecord TOP_APP, boolean doingAll, long now) { 17843 if (app.thread == null) { 17844 return false; 17845 } 17846 17847 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17848 17849 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17850 } 17851 17852 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17853 boolean oomAdj) { 17854 if (isForeground != proc.foregroundServices) { 17855 proc.foregroundServices = isForeground; 17856 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17857 proc.info.uid); 17858 if (isForeground) { 17859 if (curProcs == null) { 17860 curProcs = new ArrayList<ProcessRecord>(); 17861 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17862 } 17863 if (!curProcs.contains(proc)) { 17864 curProcs.add(proc); 17865 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17866 proc.info.packageName, proc.info.uid); 17867 } 17868 } else { 17869 if (curProcs != null) { 17870 if (curProcs.remove(proc)) { 17871 mBatteryStatsService.noteEvent( 17872 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17873 proc.info.packageName, proc.info.uid); 17874 if (curProcs.size() <= 0) { 17875 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17876 } 17877 } 17878 } 17879 } 17880 if (oomAdj) { 17881 updateOomAdjLocked(); 17882 } 17883 } 17884 } 17885 17886 private final ActivityRecord resumedAppLocked() { 17887 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17888 String pkg; 17889 int uid; 17890 if (act != null) { 17891 pkg = act.packageName; 17892 uid = act.info.applicationInfo.uid; 17893 } else { 17894 pkg = null; 17895 uid = -1; 17896 } 17897 // Has the UID or resumed package name changed? 17898 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17899 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17900 if (mCurResumedPackage != null) { 17901 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17902 mCurResumedPackage, mCurResumedUid); 17903 } 17904 mCurResumedPackage = pkg; 17905 mCurResumedUid = uid; 17906 if (mCurResumedPackage != null) { 17907 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17908 mCurResumedPackage, mCurResumedUid); 17909 } 17910 } 17911 return act; 17912 } 17913 17914 final boolean updateOomAdjLocked(ProcessRecord app) { 17915 final ActivityRecord TOP_ACT = resumedAppLocked(); 17916 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17917 final boolean wasCached = app.cached; 17918 17919 mAdjSeq++; 17920 17921 // This is the desired cached adjusment we want to tell it to use. 17922 // If our app is currently cached, we know it, and that is it. Otherwise, 17923 // we don't know it yet, and it needs to now be cached we will then 17924 // need to do a complete oom adj. 17925 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17926 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17927 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17928 SystemClock.uptimeMillis()); 17929 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17930 // Changed to/from cached state, so apps after it in the LRU 17931 // list may also be changed. 17932 updateOomAdjLocked(); 17933 } 17934 return success; 17935 } 17936 17937 final void updateOomAdjLocked() { 17938 final ActivityRecord TOP_ACT = resumedAppLocked(); 17939 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17940 final long now = SystemClock.uptimeMillis(); 17941 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17942 final int N = mLruProcesses.size(); 17943 17944 if (false) { 17945 RuntimeException e = new RuntimeException(); 17946 e.fillInStackTrace(); 17947 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17948 } 17949 17950 mAdjSeq++; 17951 mNewNumServiceProcs = 0; 17952 mNewNumAServiceProcs = 0; 17953 17954 final int emptyProcessLimit; 17955 final int cachedProcessLimit; 17956 if (mProcessLimit <= 0) { 17957 emptyProcessLimit = cachedProcessLimit = 0; 17958 } else if (mProcessLimit == 1) { 17959 emptyProcessLimit = 1; 17960 cachedProcessLimit = 0; 17961 } else { 17962 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17963 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17964 } 17965 17966 // Let's determine how many processes we have running vs. 17967 // how many slots we have for background processes; we may want 17968 // to put multiple processes in a slot of there are enough of 17969 // them. 17970 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17971 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17972 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17973 if (numEmptyProcs > cachedProcessLimit) { 17974 // If there are more empty processes than our limit on cached 17975 // processes, then use the cached process limit for the factor. 17976 // This ensures that the really old empty processes get pushed 17977 // down to the bottom, so if we are running low on memory we will 17978 // have a better chance at keeping around more cached processes 17979 // instead of a gazillion empty processes. 17980 numEmptyProcs = cachedProcessLimit; 17981 } 17982 int emptyFactor = numEmptyProcs/numSlots; 17983 if (emptyFactor < 1) emptyFactor = 1; 17984 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17985 if (cachedFactor < 1) cachedFactor = 1; 17986 int stepCached = 0; 17987 int stepEmpty = 0; 17988 int numCached = 0; 17989 int numEmpty = 0; 17990 int numTrimming = 0; 17991 17992 mNumNonCachedProcs = 0; 17993 mNumCachedHiddenProcs = 0; 17994 17995 // First update the OOM adjustment for each of the 17996 // application processes based on their current state. 17997 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17998 int nextCachedAdj = curCachedAdj+1; 17999 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18000 int nextEmptyAdj = curEmptyAdj+2; 18001 for (int i=N-1; i>=0; i--) { 18002 ProcessRecord app = mLruProcesses.get(i); 18003 if (!app.killedByAm && app.thread != null) { 18004 app.procStateChanged = false; 18005 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18006 18007 // If we haven't yet assigned the final cached adj 18008 // to the process, do that now. 18009 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18010 switch (app.curProcState) { 18011 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18012 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18013 // This process is a cached process holding activities... 18014 // assign it the next cached value for that type, and then 18015 // step that cached level. 18016 app.curRawAdj = curCachedAdj; 18017 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18018 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18019 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18020 + ")"); 18021 if (curCachedAdj != nextCachedAdj) { 18022 stepCached++; 18023 if (stepCached >= cachedFactor) { 18024 stepCached = 0; 18025 curCachedAdj = nextCachedAdj; 18026 nextCachedAdj += 2; 18027 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18028 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18029 } 18030 } 18031 } 18032 break; 18033 default: 18034 // For everything else, assign next empty cached process 18035 // level and bump that up. Note that this means that 18036 // long-running services that have dropped down to the 18037 // cached level will be treated as empty (since their process 18038 // state is still as a service), which is what we want. 18039 app.curRawAdj = curEmptyAdj; 18040 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18041 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18042 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18043 + ")"); 18044 if (curEmptyAdj != nextEmptyAdj) { 18045 stepEmpty++; 18046 if (stepEmpty >= emptyFactor) { 18047 stepEmpty = 0; 18048 curEmptyAdj = nextEmptyAdj; 18049 nextEmptyAdj += 2; 18050 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18051 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18052 } 18053 } 18054 } 18055 break; 18056 } 18057 } 18058 18059 applyOomAdjLocked(app, TOP_APP, true, now); 18060 18061 // Count the number of process types. 18062 switch (app.curProcState) { 18063 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18064 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18065 mNumCachedHiddenProcs++; 18066 numCached++; 18067 if (numCached > cachedProcessLimit) { 18068 app.kill("cached #" + numCached, true); 18069 } 18070 break; 18071 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18072 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18073 && app.lastActivityTime < oldTime) { 18074 app.kill("empty for " 18075 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18076 / 1000) + "s", true); 18077 } else { 18078 numEmpty++; 18079 if (numEmpty > emptyProcessLimit) { 18080 app.kill("empty #" + numEmpty, true); 18081 } 18082 } 18083 break; 18084 default: 18085 mNumNonCachedProcs++; 18086 break; 18087 } 18088 18089 if (app.isolated && app.services.size() <= 0) { 18090 // If this is an isolated process, and there are no 18091 // services running in it, then the process is no longer 18092 // needed. We agressively kill these because we can by 18093 // definition not re-use the same process again, and it is 18094 // good to avoid having whatever code was running in them 18095 // left sitting around after no longer needed. 18096 app.kill("isolated not needed", true); 18097 } 18098 18099 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18100 && !app.killedByAm) { 18101 numTrimming++; 18102 } 18103 } 18104 } 18105 18106 mNumServiceProcs = mNewNumServiceProcs; 18107 18108 // Now determine the memory trimming level of background processes. 18109 // Unfortunately we need to start at the back of the list to do this 18110 // properly. We only do this if the number of background apps we 18111 // are managing to keep around is less than half the maximum we desire; 18112 // if we are keeping a good number around, we'll let them use whatever 18113 // memory they want. 18114 final int numCachedAndEmpty = numCached + numEmpty; 18115 int memFactor; 18116 if (numCached <= ProcessList.TRIM_CACHED_APPS 18117 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18118 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18119 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18120 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18121 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18122 } else { 18123 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18124 } 18125 } else { 18126 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18127 } 18128 // We always allow the memory level to go up (better). We only allow it to go 18129 // down if we are in a state where that is allowed, *and* the total number of processes 18130 // has gone down since last time. 18131 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18132 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18133 + " last=" + mLastNumProcesses); 18134 if (memFactor > mLastMemoryLevel) { 18135 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18136 memFactor = mLastMemoryLevel; 18137 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18138 } 18139 } 18140 mLastMemoryLevel = memFactor; 18141 mLastNumProcesses = mLruProcesses.size(); 18142 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18143 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18144 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18145 if (mLowRamStartTime == 0) { 18146 mLowRamStartTime = now; 18147 } 18148 int step = 0; 18149 int fgTrimLevel; 18150 switch (memFactor) { 18151 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18152 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18153 break; 18154 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18155 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18156 break; 18157 default: 18158 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18159 break; 18160 } 18161 int factor = numTrimming/3; 18162 int minFactor = 2; 18163 if (mHomeProcess != null) minFactor++; 18164 if (mPreviousProcess != null) minFactor++; 18165 if (factor < minFactor) factor = minFactor; 18166 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18167 for (int i=N-1; i>=0; i--) { 18168 ProcessRecord app = mLruProcesses.get(i); 18169 if (allChanged || app.procStateChanged) { 18170 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18171 app.procStateChanged = false; 18172 } 18173 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18174 && !app.killedByAm) { 18175 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18176 try { 18177 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18178 "Trimming memory of " + app.processName 18179 + " to " + curLevel); 18180 app.thread.scheduleTrimMemory(curLevel); 18181 } catch (RemoteException e) { 18182 } 18183 if (false) { 18184 // For now we won't do this; our memory trimming seems 18185 // to be good enough at this point that destroying 18186 // activities causes more harm than good. 18187 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18188 && app != mHomeProcess && app != mPreviousProcess) { 18189 // Need to do this on its own message because the stack may not 18190 // be in a consistent state at this point. 18191 // For these apps we will also finish their activities 18192 // to help them free memory. 18193 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18194 } 18195 } 18196 } 18197 app.trimMemoryLevel = curLevel; 18198 step++; 18199 if (step >= factor) { 18200 step = 0; 18201 switch (curLevel) { 18202 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18203 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18204 break; 18205 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18206 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18207 break; 18208 } 18209 } 18210 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18211 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18212 && app.thread != null) { 18213 try { 18214 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18215 "Trimming memory of heavy-weight " + app.processName 18216 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18217 app.thread.scheduleTrimMemory( 18218 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18219 } catch (RemoteException e) { 18220 } 18221 } 18222 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18223 } else { 18224 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18225 || app.systemNoUi) && app.pendingUiClean) { 18226 // If this application is now in the background and it 18227 // had done UI, then give it the special trim level to 18228 // have it free UI resources. 18229 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18230 if (app.trimMemoryLevel < level && app.thread != null) { 18231 try { 18232 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18233 "Trimming memory of bg-ui " + app.processName 18234 + " to " + level); 18235 app.thread.scheduleTrimMemory(level); 18236 } catch (RemoteException e) { 18237 } 18238 } 18239 app.pendingUiClean = false; 18240 } 18241 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18242 try { 18243 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18244 "Trimming memory of fg " + app.processName 18245 + " to " + fgTrimLevel); 18246 app.thread.scheduleTrimMemory(fgTrimLevel); 18247 } catch (RemoteException e) { 18248 } 18249 } 18250 app.trimMemoryLevel = fgTrimLevel; 18251 } 18252 } 18253 } else { 18254 if (mLowRamStartTime != 0) { 18255 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18256 mLowRamStartTime = 0; 18257 } 18258 for (int i=N-1; i>=0; i--) { 18259 ProcessRecord app = mLruProcesses.get(i); 18260 if (allChanged || app.procStateChanged) { 18261 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18262 app.procStateChanged = false; 18263 } 18264 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18265 || app.systemNoUi) && app.pendingUiClean) { 18266 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18267 && app.thread != null) { 18268 try { 18269 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18270 "Trimming memory of ui hidden " + app.processName 18271 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18272 app.thread.scheduleTrimMemory( 18273 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18274 } catch (RemoteException e) { 18275 } 18276 } 18277 app.pendingUiClean = false; 18278 } 18279 app.trimMemoryLevel = 0; 18280 } 18281 } 18282 18283 if (mAlwaysFinishActivities) { 18284 // Need to do this on its own message because the stack may not 18285 // be in a consistent state at this point. 18286 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18287 } 18288 18289 if (allChanged) { 18290 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18291 } 18292 18293 if (mProcessStats.shouldWriteNowLocked(now)) { 18294 mHandler.post(new Runnable() { 18295 @Override public void run() { 18296 synchronized (ActivityManagerService.this) { 18297 mProcessStats.writeStateAsyncLocked(); 18298 } 18299 } 18300 }); 18301 } 18302 18303 if (DEBUG_OOM_ADJ) { 18304 if (false) { 18305 RuntimeException here = new RuntimeException("here"); 18306 here.fillInStackTrace(); 18307 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18308 } else { 18309 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18310 } 18311 } 18312 } 18313 18314 final void trimApplications() { 18315 synchronized (this) { 18316 int i; 18317 18318 // First remove any unused application processes whose package 18319 // has been removed. 18320 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18321 final ProcessRecord app = mRemovedProcesses.get(i); 18322 if (app.activities.size() == 0 18323 && app.curReceiver == null && app.services.size() == 0) { 18324 Slog.i( 18325 TAG, "Exiting empty application process " 18326 + app.processName + " (" 18327 + (app.thread != null ? app.thread.asBinder() : null) 18328 + ")\n"); 18329 if (app.pid > 0 && app.pid != MY_PID) { 18330 app.kill("empty", false); 18331 } else { 18332 try { 18333 app.thread.scheduleExit(); 18334 } catch (Exception e) { 18335 // Ignore exceptions. 18336 } 18337 } 18338 cleanUpApplicationRecordLocked(app, false, true, -1); 18339 mRemovedProcesses.remove(i); 18340 18341 if (app.persistent) { 18342 addAppLocked(app.info, false, null /* ABI override */); 18343 } 18344 } 18345 } 18346 18347 // Now update the oom adj for all processes. 18348 updateOomAdjLocked(); 18349 } 18350 } 18351 18352 /** This method sends the specified signal to each of the persistent apps */ 18353 public void signalPersistentProcesses(int sig) throws RemoteException { 18354 if (sig != Process.SIGNAL_USR1) { 18355 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18356 } 18357 18358 synchronized (this) { 18359 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18360 != PackageManager.PERMISSION_GRANTED) { 18361 throw new SecurityException("Requires permission " 18362 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18363 } 18364 18365 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18366 ProcessRecord r = mLruProcesses.get(i); 18367 if (r.thread != null && r.persistent) { 18368 Process.sendSignal(r.pid, sig); 18369 } 18370 } 18371 } 18372 } 18373 18374 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18375 if (proc == null || proc == mProfileProc) { 18376 proc = mProfileProc; 18377 profileType = mProfileType; 18378 clearProfilerLocked(); 18379 } 18380 if (proc == null) { 18381 return; 18382 } 18383 try { 18384 proc.thread.profilerControl(false, null, profileType); 18385 } catch (RemoteException e) { 18386 throw new IllegalStateException("Process disappeared"); 18387 } 18388 } 18389 18390 private void clearProfilerLocked() { 18391 if (mProfileFd != null) { 18392 try { 18393 mProfileFd.close(); 18394 } catch (IOException e) { 18395 } 18396 } 18397 mProfileApp = null; 18398 mProfileProc = null; 18399 mProfileFile = null; 18400 mProfileType = 0; 18401 mAutoStopProfiler = false; 18402 mSamplingInterval = 0; 18403 } 18404 18405 public boolean profileControl(String process, int userId, boolean start, 18406 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18407 18408 try { 18409 synchronized (this) { 18410 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18411 // its own permission. 18412 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18413 != PackageManager.PERMISSION_GRANTED) { 18414 throw new SecurityException("Requires permission " 18415 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18416 } 18417 18418 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18419 throw new IllegalArgumentException("null profile info or fd"); 18420 } 18421 18422 ProcessRecord proc = null; 18423 if (process != null) { 18424 proc = findProcessLocked(process, userId, "profileControl"); 18425 } 18426 18427 if (start && (proc == null || proc.thread == null)) { 18428 throw new IllegalArgumentException("Unknown process: " + process); 18429 } 18430 18431 if (start) { 18432 stopProfilerLocked(null, 0); 18433 setProfileApp(proc.info, proc.processName, profilerInfo); 18434 mProfileProc = proc; 18435 mProfileType = profileType; 18436 ParcelFileDescriptor fd = profilerInfo.profileFd; 18437 try { 18438 fd = fd.dup(); 18439 } catch (IOException e) { 18440 fd = null; 18441 } 18442 profilerInfo.profileFd = fd; 18443 proc.thread.profilerControl(start, profilerInfo, profileType); 18444 fd = null; 18445 mProfileFd = null; 18446 } else { 18447 stopProfilerLocked(proc, profileType); 18448 if (profilerInfo != null && profilerInfo.profileFd != null) { 18449 try { 18450 profilerInfo.profileFd.close(); 18451 } catch (IOException e) { 18452 } 18453 } 18454 } 18455 18456 return true; 18457 } 18458 } catch (RemoteException e) { 18459 throw new IllegalStateException("Process disappeared"); 18460 } finally { 18461 if (profilerInfo != null && profilerInfo.profileFd != null) { 18462 try { 18463 profilerInfo.profileFd.close(); 18464 } catch (IOException e) { 18465 } 18466 } 18467 } 18468 } 18469 18470 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18471 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18472 userId, true, ALLOW_FULL_ONLY, callName, null); 18473 ProcessRecord proc = null; 18474 try { 18475 int pid = Integer.parseInt(process); 18476 synchronized (mPidsSelfLocked) { 18477 proc = mPidsSelfLocked.get(pid); 18478 } 18479 } catch (NumberFormatException e) { 18480 } 18481 18482 if (proc == null) { 18483 ArrayMap<String, SparseArray<ProcessRecord>> all 18484 = mProcessNames.getMap(); 18485 SparseArray<ProcessRecord> procs = all.get(process); 18486 if (procs != null && procs.size() > 0) { 18487 proc = procs.valueAt(0); 18488 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18489 for (int i=1; i<procs.size(); i++) { 18490 ProcessRecord thisProc = procs.valueAt(i); 18491 if (thisProc.userId == userId) { 18492 proc = thisProc; 18493 break; 18494 } 18495 } 18496 } 18497 } 18498 } 18499 18500 return proc; 18501 } 18502 18503 public boolean dumpHeap(String process, int userId, boolean managed, 18504 String path, ParcelFileDescriptor fd) throws RemoteException { 18505 18506 try { 18507 synchronized (this) { 18508 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18509 // its own permission (same as profileControl). 18510 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18511 != PackageManager.PERMISSION_GRANTED) { 18512 throw new SecurityException("Requires permission " 18513 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18514 } 18515 18516 if (fd == null) { 18517 throw new IllegalArgumentException("null fd"); 18518 } 18519 18520 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18521 if (proc == null || proc.thread == null) { 18522 throw new IllegalArgumentException("Unknown process: " + process); 18523 } 18524 18525 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18526 if (!isDebuggable) { 18527 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18528 throw new SecurityException("Process not debuggable: " + proc); 18529 } 18530 } 18531 18532 proc.thread.dumpHeap(managed, path, fd); 18533 fd = null; 18534 return true; 18535 } 18536 } catch (RemoteException e) { 18537 throw new IllegalStateException("Process disappeared"); 18538 } finally { 18539 if (fd != null) { 18540 try { 18541 fd.close(); 18542 } catch (IOException e) { 18543 } 18544 } 18545 } 18546 } 18547 18548 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18549 public void monitor() { 18550 synchronized (this) { } 18551 } 18552 18553 void onCoreSettingsChange(Bundle settings) { 18554 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18555 ProcessRecord processRecord = mLruProcesses.get(i); 18556 try { 18557 if (processRecord.thread != null) { 18558 processRecord.thread.setCoreSettings(settings); 18559 } 18560 } catch (RemoteException re) { 18561 /* ignore */ 18562 } 18563 } 18564 } 18565 18566 // Multi-user methods 18567 18568 /** 18569 * Start user, if its not already running, but don't bring it to foreground. 18570 */ 18571 @Override 18572 public boolean startUserInBackground(final int userId) { 18573 return startUser(userId, /* foreground */ false); 18574 } 18575 18576 /** 18577 * Start user, if its not already running, and bring it to foreground. 18578 */ 18579 boolean startUserInForeground(final int userId, Dialog dlg) { 18580 boolean result = startUser(userId, /* foreground */ true); 18581 dlg.dismiss(); 18582 return result; 18583 } 18584 18585 /** 18586 * Refreshes the list of users related to the current user when either a 18587 * user switch happens or when a new related user is started in the 18588 * background. 18589 */ 18590 private void updateCurrentProfileIdsLocked() { 18591 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18592 mCurrentUserId, false /* enabledOnly */); 18593 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18594 for (int i = 0; i < currentProfileIds.length; i++) { 18595 currentProfileIds[i] = profiles.get(i).id; 18596 } 18597 mCurrentProfileIds = currentProfileIds; 18598 18599 synchronized (mUserProfileGroupIdsSelfLocked) { 18600 mUserProfileGroupIdsSelfLocked.clear(); 18601 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18602 for (int i = 0; i < users.size(); i++) { 18603 UserInfo user = users.get(i); 18604 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18605 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18606 } 18607 } 18608 } 18609 } 18610 18611 private Set getProfileIdsLocked(int userId) { 18612 Set userIds = new HashSet<Integer>(); 18613 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18614 userId, false /* enabledOnly */); 18615 for (UserInfo user : profiles) { 18616 userIds.add(Integer.valueOf(user.id)); 18617 } 18618 return userIds; 18619 } 18620 18621 @Override 18622 public boolean switchUser(final int userId) { 18623 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18624 String userName; 18625 synchronized (this) { 18626 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18627 if (userInfo == null) { 18628 Slog.w(TAG, "No user info for user #" + userId); 18629 return false; 18630 } 18631 if (userInfo.isManagedProfile()) { 18632 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18633 return false; 18634 } 18635 userName = userInfo.name; 18636 mTargetUserId = userId; 18637 } 18638 mHandler.removeMessages(START_USER_SWITCH_MSG); 18639 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18640 return true; 18641 } 18642 18643 private void showUserSwitchDialog(int userId, String userName) { 18644 // The dialog will show and then initiate the user switch by calling startUserInForeground 18645 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18646 true /* above system */); 18647 d.show(); 18648 } 18649 18650 private boolean startUser(final int userId, final boolean foreground) { 18651 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18652 != PackageManager.PERMISSION_GRANTED) { 18653 String msg = "Permission Denial: switchUser() from pid=" 18654 + Binder.getCallingPid() 18655 + ", uid=" + Binder.getCallingUid() 18656 + " requires " + INTERACT_ACROSS_USERS_FULL; 18657 Slog.w(TAG, msg); 18658 throw new SecurityException(msg); 18659 } 18660 18661 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18662 18663 final long ident = Binder.clearCallingIdentity(); 18664 try { 18665 synchronized (this) { 18666 final int oldUserId = mCurrentUserId; 18667 if (oldUserId == userId) { 18668 return true; 18669 } 18670 18671 mStackSupervisor.setLockTaskModeLocked(null, false); 18672 18673 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18674 if (userInfo == null) { 18675 Slog.w(TAG, "No user info for user #" + userId); 18676 return false; 18677 } 18678 if (foreground && userInfo.isManagedProfile()) { 18679 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18680 return false; 18681 } 18682 18683 if (foreground) { 18684 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18685 R.anim.screen_user_enter); 18686 } 18687 18688 boolean needStart = false; 18689 18690 // If the user we are switching to is not currently started, then 18691 // we need to start it now. 18692 if (mStartedUsers.get(userId) == null) { 18693 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18694 updateStartedUserArrayLocked(); 18695 needStart = true; 18696 } 18697 18698 final Integer userIdInt = Integer.valueOf(userId); 18699 mUserLru.remove(userIdInt); 18700 mUserLru.add(userIdInt); 18701 18702 if (foreground) { 18703 mCurrentUserId = userId; 18704 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18705 updateCurrentProfileIdsLocked(); 18706 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18707 // Once the internal notion of the active user has switched, we lock the device 18708 // with the option to show the user switcher on the keyguard. 18709 mWindowManager.lockNow(null); 18710 } else { 18711 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18712 updateCurrentProfileIdsLocked(); 18713 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18714 mUserLru.remove(currentUserIdInt); 18715 mUserLru.add(currentUserIdInt); 18716 } 18717 18718 final UserStartedState uss = mStartedUsers.get(userId); 18719 18720 // Make sure user is in the started state. If it is currently 18721 // stopping, we need to knock that off. 18722 if (uss.mState == UserStartedState.STATE_STOPPING) { 18723 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18724 // so we can just fairly silently bring the user back from 18725 // the almost-dead. 18726 uss.mState = UserStartedState.STATE_RUNNING; 18727 updateStartedUserArrayLocked(); 18728 needStart = true; 18729 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18730 // This means ACTION_SHUTDOWN has been sent, so we will 18731 // need to treat this as a new boot of the user. 18732 uss.mState = UserStartedState.STATE_BOOTING; 18733 updateStartedUserArrayLocked(); 18734 needStart = true; 18735 } 18736 18737 if (uss.mState == UserStartedState.STATE_BOOTING) { 18738 // Booting up a new user, need to tell system services about it. 18739 // Note that this is on the same handler as scheduling of broadcasts, 18740 // which is important because it needs to go first. 18741 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18742 } 18743 18744 if (foreground) { 18745 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18746 oldUserId)); 18747 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18748 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18749 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18750 oldUserId, userId, uss)); 18751 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18752 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18753 } 18754 18755 if (needStart) { 18756 // Send USER_STARTED broadcast 18757 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18758 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18759 | Intent.FLAG_RECEIVER_FOREGROUND); 18760 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18761 broadcastIntentLocked(null, null, intent, 18762 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18763 false, false, MY_PID, Process.SYSTEM_UID, userId); 18764 } 18765 18766 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18767 if (userId != UserHandle.USER_OWNER) { 18768 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18769 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18770 broadcastIntentLocked(null, null, intent, null, 18771 new IIntentReceiver.Stub() { 18772 public void performReceive(Intent intent, int resultCode, 18773 String data, Bundle extras, boolean ordered, 18774 boolean sticky, int sendingUser) { 18775 onUserInitialized(uss, foreground, oldUserId, userId); 18776 } 18777 }, 0, null, null, null, AppOpsManager.OP_NONE, 18778 true, false, MY_PID, Process.SYSTEM_UID, 18779 userId); 18780 uss.initializing = true; 18781 } else { 18782 getUserManagerLocked().makeInitialized(userInfo.id); 18783 } 18784 } 18785 18786 if (foreground) { 18787 if (!uss.initializing) { 18788 moveUserToForeground(uss, oldUserId, userId); 18789 } 18790 } else { 18791 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18792 } 18793 18794 if (needStart) { 18795 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18796 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18797 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18798 broadcastIntentLocked(null, null, intent, 18799 null, new IIntentReceiver.Stub() { 18800 @Override 18801 public void performReceive(Intent intent, int resultCode, String data, 18802 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18803 throws RemoteException { 18804 } 18805 }, 0, null, null, 18806 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18807 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18808 } 18809 } 18810 } finally { 18811 Binder.restoreCallingIdentity(ident); 18812 } 18813 18814 return true; 18815 } 18816 18817 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18818 long ident = Binder.clearCallingIdentity(); 18819 try { 18820 Intent intent; 18821 if (oldUserId >= 0) { 18822 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18823 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18824 int count = profiles.size(); 18825 for (int i = 0; i < count; i++) { 18826 int profileUserId = profiles.get(i).id; 18827 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18828 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18829 | Intent.FLAG_RECEIVER_FOREGROUND); 18830 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18831 broadcastIntentLocked(null, null, intent, 18832 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18833 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18834 } 18835 } 18836 if (newUserId >= 0) { 18837 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18838 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18839 int count = profiles.size(); 18840 for (int i = 0; i < count; i++) { 18841 int profileUserId = profiles.get(i).id; 18842 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18843 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18844 | Intent.FLAG_RECEIVER_FOREGROUND); 18845 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18846 broadcastIntentLocked(null, null, intent, 18847 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18848 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18849 } 18850 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18851 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18852 | Intent.FLAG_RECEIVER_FOREGROUND); 18853 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18854 broadcastIntentLocked(null, null, intent, 18855 null, null, 0, null, null, 18856 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18857 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18858 } 18859 } finally { 18860 Binder.restoreCallingIdentity(ident); 18861 } 18862 } 18863 18864 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18865 final int newUserId) { 18866 final int N = mUserSwitchObservers.beginBroadcast(); 18867 if (N > 0) { 18868 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18869 int mCount = 0; 18870 @Override 18871 public void sendResult(Bundle data) throws RemoteException { 18872 synchronized (ActivityManagerService.this) { 18873 if (mCurUserSwitchCallback == this) { 18874 mCount++; 18875 if (mCount == N) { 18876 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18877 } 18878 } 18879 } 18880 } 18881 }; 18882 synchronized (this) { 18883 uss.switching = true; 18884 mCurUserSwitchCallback = callback; 18885 } 18886 for (int i=0; i<N; i++) { 18887 try { 18888 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18889 newUserId, callback); 18890 } catch (RemoteException e) { 18891 } 18892 } 18893 } else { 18894 synchronized (this) { 18895 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18896 } 18897 } 18898 mUserSwitchObservers.finishBroadcast(); 18899 } 18900 18901 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18902 synchronized (this) { 18903 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18904 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18905 } 18906 } 18907 18908 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18909 mCurUserSwitchCallback = null; 18910 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18911 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18912 oldUserId, newUserId, uss)); 18913 } 18914 18915 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18916 synchronized (this) { 18917 if (foreground) { 18918 moveUserToForeground(uss, oldUserId, newUserId); 18919 } 18920 } 18921 18922 completeSwitchAndInitalize(uss, newUserId, true, false); 18923 } 18924 18925 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18926 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18927 if (homeInFront) { 18928 startHomeActivityLocked(newUserId); 18929 } else { 18930 mStackSupervisor.resumeTopActivitiesLocked(); 18931 } 18932 EventLogTags.writeAmSwitchUser(newUserId); 18933 getUserManagerLocked().userForeground(newUserId); 18934 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18935 } 18936 18937 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18938 completeSwitchAndInitalize(uss, newUserId, false, true); 18939 } 18940 18941 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18942 boolean clearInitializing, boolean clearSwitching) { 18943 boolean unfrozen = false; 18944 synchronized (this) { 18945 if (clearInitializing) { 18946 uss.initializing = false; 18947 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18948 } 18949 if (clearSwitching) { 18950 uss.switching = false; 18951 } 18952 if (!uss.switching && !uss.initializing) { 18953 mWindowManager.stopFreezingScreen(); 18954 unfrozen = true; 18955 } 18956 } 18957 if (unfrozen) { 18958 final int N = mUserSwitchObservers.beginBroadcast(); 18959 for (int i=0; i<N; i++) { 18960 try { 18961 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18962 } catch (RemoteException e) { 18963 } 18964 } 18965 mUserSwitchObservers.finishBroadcast(); 18966 } 18967 stopGuestUserIfBackground(); 18968 } 18969 18970 /** 18971 * Stops the guest user if it has gone to the background. 18972 */ 18973 private void stopGuestUserIfBackground() { 18974 synchronized (this) { 18975 final int num = mUserLru.size(); 18976 for (int i = 0; i < num; i++) { 18977 Integer oldUserId = mUserLru.get(i); 18978 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18979 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 18980 || oldUss.mState == UserStartedState.STATE_STOPPING 18981 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18982 continue; 18983 } 18984 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 18985 if (userInfo.isGuest()) { 18986 // This is a user to be stopped. 18987 stopUserLocked(oldUserId, null); 18988 break; 18989 } 18990 } 18991 } 18992 } 18993 18994 void scheduleStartProfilesLocked() { 18995 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18996 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18997 DateUtils.SECOND_IN_MILLIS); 18998 } 18999 } 19000 19001 void startProfilesLocked() { 19002 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19003 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19004 mCurrentUserId, false /* enabledOnly */); 19005 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19006 for (UserInfo user : profiles) { 19007 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19008 && user.id != mCurrentUserId) { 19009 toStart.add(user); 19010 } 19011 } 19012 final int n = toStart.size(); 19013 int i = 0; 19014 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19015 startUserInBackground(toStart.get(i).id); 19016 } 19017 if (i < n) { 19018 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19019 } 19020 } 19021 19022 void finishUserBoot(UserStartedState uss) { 19023 synchronized (this) { 19024 if (uss.mState == UserStartedState.STATE_BOOTING 19025 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19026 uss.mState = UserStartedState.STATE_RUNNING; 19027 final int userId = uss.mHandle.getIdentifier(); 19028 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19029 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19030 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19031 broadcastIntentLocked(null, null, intent, 19032 null, null, 0, null, null, 19033 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19034 true, false, MY_PID, Process.SYSTEM_UID, userId); 19035 } 19036 } 19037 } 19038 19039 void finishUserSwitch(UserStartedState uss) { 19040 synchronized (this) { 19041 finishUserBoot(uss); 19042 19043 startProfilesLocked(); 19044 19045 int num = mUserLru.size(); 19046 int i = 0; 19047 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19048 Integer oldUserId = mUserLru.get(i); 19049 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19050 if (oldUss == null) { 19051 // Shouldn't happen, but be sane if it does. 19052 mUserLru.remove(i); 19053 num--; 19054 continue; 19055 } 19056 if (oldUss.mState == UserStartedState.STATE_STOPPING 19057 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19058 // This user is already stopping, doesn't count. 19059 num--; 19060 i++; 19061 continue; 19062 } 19063 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19064 // Owner and current can't be stopped, but count as running. 19065 i++; 19066 continue; 19067 } 19068 // This is a user to be stopped. 19069 stopUserLocked(oldUserId, null); 19070 num--; 19071 i++; 19072 } 19073 } 19074 } 19075 19076 @Override 19077 public int stopUser(final int userId, final IStopUserCallback callback) { 19078 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19079 != PackageManager.PERMISSION_GRANTED) { 19080 String msg = "Permission Denial: switchUser() from pid=" 19081 + Binder.getCallingPid() 19082 + ", uid=" + Binder.getCallingUid() 19083 + " requires " + INTERACT_ACROSS_USERS_FULL; 19084 Slog.w(TAG, msg); 19085 throw new SecurityException(msg); 19086 } 19087 if (userId <= 0) { 19088 throw new IllegalArgumentException("Can't stop primary user " + userId); 19089 } 19090 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19091 synchronized (this) { 19092 return stopUserLocked(userId, callback); 19093 } 19094 } 19095 19096 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19097 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19098 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19099 return ActivityManager.USER_OP_IS_CURRENT; 19100 } 19101 19102 final UserStartedState uss = mStartedUsers.get(userId); 19103 if (uss == null) { 19104 // User is not started, nothing to do... but we do need to 19105 // callback if requested. 19106 if (callback != null) { 19107 mHandler.post(new Runnable() { 19108 @Override 19109 public void run() { 19110 try { 19111 callback.userStopped(userId); 19112 } catch (RemoteException e) { 19113 } 19114 } 19115 }); 19116 } 19117 return ActivityManager.USER_OP_SUCCESS; 19118 } 19119 19120 if (callback != null) { 19121 uss.mStopCallbacks.add(callback); 19122 } 19123 19124 if (uss.mState != UserStartedState.STATE_STOPPING 19125 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19126 uss.mState = UserStartedState.STATE_STOPPING; 19127 updateStartedUserArrayLocked(); 19128 19129 long ident = Binder.clearCallingIdentity(); 19130 try { 19131 // We are going to broadcast ACTION_USER_STOPPING and then 19132 // once that is done send a final ACTION_SHUTDOWN and then 19133 // stop the user. 19134 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19135 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19136 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19137 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19138 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19139 // This is the result receiver for the final shutdown broadcast. 19140 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19141 @Override 19142 public void performReceive(Intent intent, int resultCode, String data, 19143 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19144 finishUserStop(uss); 19145 } 19146 }; 19147 // This is the result receiver for the initial stopping broadcast. 19148 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19149 @Override 19150 public void performReceive(Intent intent, int resultCode, String data, 19151 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19152 // On to the next. 19153 synchronized (ActivityManagerService.this) { 19154 if (uss.mState != UserStartedState.STATE_STOPPING) { 19155 // Whoops, we are being started back up. Abort, abort! 19156 return; 19157 } 19158 uss.mState = UserStartedState.STATE_SHUTDOWN; 19159 } 19160 mBatteryStatsService.noteEvent( 19161 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19162 Integer.toString(userId), userId); 19163 mSystemServiceManager.stopUser(userId); 19164 broadcastIntentLocked(null, null, shutdownIntent, 19165 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19166 true, false, MY_PID, Process.SYSTEM_UID, userId); 19167 } 19168 }; 19169 // Kick things off. 19170 broadcastIntentLocked(null, null, stoppingIntent, 19171 null, stoppingReceiver, 0, null, null, 19172 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19173 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19174 } finally { 19175 Binder.restoreCallingIdentity(ident); 19176 } 19177 } 19178 19179 return ActivityManager.USER_OP_SUCCESS; 19180 } 19181 19182 void finishUserStop(UserStartedState uss) { 19183 final int userId = uss.mHandle.getIdentifier(); 19184 boolean stopped; 19185 ArrayList<IStopUserCallback> callbacks; 19186 synchronized (this) { 19187 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19188 if (mStartedUsers.get(userId) != uss) { 19189 stopped = false; 19190 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19191 stopped = false; 19192 } else { 19193 stopped = true; 19194 // User can no longer run. 19195 mStartedUsers.remove(userId); 19196 mUserLru.remove(Integer.valueOf(userId)); 19197 updateStartedUserArrayLocked(); 19198 19199 // Clean up all state and processes associated with the user. 19200 // Kill all the processes for the user. 19201 forceStopUserLocked(userId, "finish user"); 19202 } 19203 19204 // Explicitly remove the old information in mRecentTasks. 19205 removeRecentTasksForUserLocked(userId); 19206 } 19207 19208 for (int i=0; i<callbacks.size(); i++) { 19209 try { 19210 if (stopped) callbacks.get(i).userStopped(userId); 19211 else callbacks.get(i).userStopAborted(userId); 19212 } catch (RemoteException e) { 19213 } 19214 } 19215 19216 if (stopped) { 19217 mSystemServiceManager.cleanupUser(userId); 19218 synchronized (this) { 19219 mStackSupervisor.removeUserLocked(userId); 19220 } 19221 } 19222 } 19223 19224 @Override 19225 public UserInfo getCurrentUser() { 19226 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19227 != PackageManager.PERMISSION_GRANTED) && ( 19228 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19229 != PackageManager.PERMISSION_GRANTED)) { 19230 String msg = "Permission Denial: getCurrentUser() from pid=" 19231 + Binder.getCallingPid() 19232 + ", uid=" + Binder.getCallingUid() 19233 + " requires " + INTERACT_ACROSS_USERS; 19234 Slog.w(TAG, msg); 19235 throw new SecurityException(msg); 19236 } 19237 synchronized (this) { 19238 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19239 return getUserManagerLocked().getUserInfo(userId); 19240 } 19241 } 19242 19243 int getCurrentUserIdLocked() { 19244 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19245 } 19246 19247 @Override 19248 public boolean isUserRunning(int userId, boolean orStopped) { 19249 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19250 != PackageManager.PERMISSION_GRANTED) { 19251 String msg = "Permission Denial: isUserRunning() from pid=" 19252 + Binder.getCallingPid() 19253 + ", uid=" + Binder.getCallingUid() 19254 + " requires " + INTERACT_ACROSS_USERS; 19255 Slog.w(TAG, msg); 19256 throw new SecurityException(msg); 19257 } 19258 synchronized (this) { 19259 return isUserRunningLocked(userId, orStopped); 19260 } 19261 } 19262 19263 boolean isUserRunningLocked(int userId, boolean orStopped) { 19264 UserStartedState state = mStartedUsers.get(userId); 19265 if (state == null) { 19266 return false; 19267 } 19268 if (orStopped) { 19269 return true; 19270 } 19271 return state.mState != UserStartedState.STATE_STOPPING 19272 && state.mState != UserStartedState.STATE_SHUTDOWN; 19273 } 19274 19275 @Override 19276 public int[] getRunningUserIds() { 19277 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19278 != PackageManager.PERMISSION_GRANTED) { 19279 String msg = "Permission Denial: isUserRunning() from pid=" 19280 + Binder.getCallingPid() 19281 + ", uid=" + Binder.getCallingUid() 19282 + " requires " + INTERACT_ACROSS_USERS; 19283 Slog.w(TAG, msg); 19284 throw new SecurityException(msg); 19285 } 19286 synchronized (this) { 19287 return mStartedUserArray; 19288 } 19289 } 19290 19291 private void updateStartedUserArrayLocked() { 19292 int num = 0; 19293 for (int i=0; i<mStartedUsers.size(); i++) { 19294 UserStartedState uss = mStartedUsers.valueAt(i); 19295 // This list does not include stopping users. 19296 if (uss.mState != UserStartedState.STATE_STOPPING 19297 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19298 num++; 19299 } 19300 } 19301 mStartedUserArray = new int[num]; 19302 num = 0; 19303 for (int i=0; i<mStartedUsers.size(); i++) { 19304 UserStartedState uss = mStartedUsers.valueAt(i); 19305 if (uss.mState != UserStartedState.STATE_STOPPING 19306 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19307 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19308 num++; 19309 } 19310 } 19311 } 19312 19313 @Override 19314 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19315 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19316 != PackageManager.PERMISSION_GRANTED) { 19317 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19318 + Binder.getCallingPid() 19319 + ", uid=" + Binder.getCallingUid() 19320 + " requires " + INTERACT_ACROSS_USERS_FULL; 19321 Slog.w(TAG, msg); 19322 throw new SecurityException(msg); 19323 } 19324 19325 mUserSwitchObservers.register(observer); 19326 } 19327 19328 @Override 19329 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19330 mUserSwitchObservers.unregister(observer); 19331 } 19332 19333 private boolean userExists(int userId) { 19334 if (userId == 0) { 19335 return true; 19336 } 19337 UserManagerService ums = getUserManagerLocked(); 19338 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19339 } 19340 19341 int[] getUsersLocked() { 19342 UserManagerService ums = getUserManagerLocked(); 19343 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19344 } 19345 19346 UserManagerService getUserManagerLocked() { 19347 if (mUserManager == null) { 19348 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19349 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19350 } 19351 return mUserManager; 19352 } 19353 19354 private int applyUserId(int uid, int userId) { 19355 return UserHandle.getUid(userId, uid); 19356 } 19357 19358 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19359 if (info == null) return null; 19360 ApplicationInfo newInfo = new ApplicationInfo(info); 19361 newInfo.uid = applyUserId(info.uid, userId); 19362 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19363 + info.packageName; 19364 return newInfo; 19365 } 19366 19367 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19368 if (aInfo == null 19369 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19370 return aInfo; 19371 } 19372 19373 ActivityInfo info = new ActivityInfo(aInfo); 19374 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19375 return info; 19376 } 19377 19378 private final class LocalService extends ActivityManagerInternal { 19379 @Override 19380 public void onWakefulnessChanged(int wakefulness) { 19381 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19382 } 19383 19384 @Override 19385 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19386 String processName, String abiOverride, int uid, Runnable crashHandler) { 19387 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19388 processName, abiOverride, uid, crashHandler); 19389 } 19390 } 19391 19392 /** 19393 * An implementation of IAppTask, that allows an app to manage its own tasks via 19394 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19395 * only the process that calls getAppTasks() can call the AppTask methods. 19396 */ 19397 class AppTaskImpl extends IAppTask.Stub { 19398 private int mTaskId; 19399 private int mCallingUid; 19400 19401 public AppTaskImpl(int taskId, int callingUid) { 19402 mTaskId = taskId; 19403 mCallingUid = callingUid; 19404 } 19405 19406 private void checkCaller() { 19407 if (mCallingUid != Binder.getCallingUid()) { 19408 throw new SecurityException("Caller " + mCallingUid 19409 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19410 } 19411 } 19412 19413 @Override 19414 public void finishAndRemoveTask() { 19415 checkCaller(); 19416 19417 synchronized (ActivityManagerService.this) { 19418 long origId = Binder.clearCallingIdentity(); 19419 try { 19420 if (!removeTaskByIdLocked(mTaskId, false)) { 19421 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19422 } 19423 } finally { 19424 Binder.restoreCallingIdentity(origId); 19425 } 19426 } 19427 } 19428 19429 @Override 19430 public ActivityManager.RecentTaskInfo getTaskInfo() { 19431 checkCaller(); 19432 19433 synchronized (ActivityManagerService.this) { 19434 long origId = Binder.clearCallingIdentity(); 19435 try { 19436 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19437 if (tr == null) { 19438 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19439 } 19440 return createRecentTaskInfoFromTaskRecord(tr); 19441 } finally { 19442 Binder.restoreCallingIdentity(origId); 19443 } 19444 } 19445 } 19446 19447 @Override 19448 public void moveToFront() { 19449 checkCaller(); 19450 // Will bring task to front if it already has a root activity. 19451 startActivityFromRecentsInner(mTaskId, null); 19452 } 19453 19454 @Override 19455 public int startActivity(IBinder whoThread, String callingPackage, 19456 Intent intent, String resolvedType, Bundle options) { 19457 checkCaller(); 19458 19459 int callingUser = UserHandle.getCallingUserId(); 19460 TaskRecord tr; 19461 IApplicationThread appThread; 19462 synchronized (ActivityManagerService.this) { 19463 tr = recentTaskForIdLocked(mTaskId); 19464 if (tr == null) { 19465 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19466 } 19467 appThread = ApplicationThreadNative.asInterface(whoThread); 19468 if (appThread == null) { 19469 throw new IllegalArgumentException("Bad app thread " + appThread); 19470 } 19471 } 19472 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19473 resolvedType, null, null, null, null, 0, 0, null, null, 19474 null, options, callingUser, null, tr); 19475 } 19476 19477 @Override 19478 public void setExcludeFromRecents(boolean exclude) { 19479 checkCaller(); 19480 19481 synchronized (ActivityManagerService.this) { 19482 long origId = Binder.clearCallingIdentity(); 19483 try { 19484 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19485 if (tr == null) { 19486 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19487 } 19488 Intent intent = tr.getBaseIntent(); 19489 if (exclude) { 19490 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19491 } else { 19492 intent.setFlags(intent.getFlags() 19493 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19494 } 19495 } finally { 19496 Binder.restoreCallingIdentity(origId); 19497 } 19498 } 19499 } 19500 } 19501} 19502